]> git.madduck.net Git - etc/awesome.git/blob - .config/awesome/rc.lua

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

26967cd61144d28a1f092d33df69a7b099225182
[etc/awesome.git] / .config / awesome / rc.lua
1 -- Standard awesome library
2 require("awful")
3 require("beautiful")
4 require("naughty")
5
6 -- Load Debian menu entries
7 require("debian.menu")
8
9 -- {{{ Variable definitions
10 -- Themes define colours, icons, and wallpapers
11 -- The default is a dark theme
12 theme_path = "/usr/share/awesome/themes/default/theme.lua"
13 -- Uncommment this for a lighter theme
14 -- theme_path = "/usr/share/awesome/themes/sky/theme.lua"
15
16 -- Actually load theme
17 beautiful.init(theme_path)
18
19 -- This is used later as the default terminal and editor to run.
20 terminal = "x-terminal-emulator"
21 editor = os.getenv("EDITOR") or "editor"
22 editor_cmd = terminal .. " -e " .. editor
23
24 -- Default modkey.
25 -- Usually, Mod4 is the key with a logo between Control and Alt.
26 -- If you do not like this or do not have such a key,
27 -- I suggest you to remap Mod4 to another key using xmodmap or other tools.
28 -- However, you can use another modifier like Mod1, but it may interact with others.
29 modkey = "Mod4"
30
31 -- Table of layouts to cover with awful.layout.inc, order matters.
32 layouts =
33 {
34     awful.layout.suit.tile,
35     awful.layout.suit.tile.left,
36     awful.layout.suit.tile.bottom,
37     awful.layout.suit.tile.top,
38     awful.layout.suit.fair,
39     awful.layout.suit.fair.horizontal,
40     awful.layout.suit.max,
41     awful.layout.suit.max.fullscreen,
42     awful.layout.suit.magnifier,
43     awful.layout.suit.floating
44 }
45
46 -- Table of clients that should be set floating. The index may be either
47 -- the application class or instance. The instance is useful when running
48 -- a console app in a terminal like (Music on Console)
49 --    xterm -name mocp -e mocp
50 -- OVERRULED BY TILEDAPPS BELOW
51 floatapps =
52 {
53     -- by class
54     ["MPlayer"] = true,
55     ["pinentry"] = true,
56     ["GIMP"] = true,
57     ["twinkle"] = true,
58     ["Add-ons"] = true,
59     ["Play stream"] = true,
60 }
61
62 -- Applications that should never float, assuming everything else floats
63 -- (by instance)
64 tiledapps =
65 {
66     ["urxvt"] = true,
67 }
68
69 -- Applications that should be maximised
70 -- (by instance)
71 maxapps =
72 {
73     ["Navigator"] = true,
74     -- jpilot is -v
75     ["-v"] = true,
76     ["Xpdf"] = true,
77     ["gscan2pdf"] = true
78 }
79
80 -- Applications to be moved to a pre-defined tag by class or instance.
81 -- Use the screen and tags indices.
82 apptags =
83 {
84     ["Navigator"] = { screen = 1, tag = 9 },
85     -- jpilot is -v
86     ["-v"] = { screen = 1, tag = 8 },
87 }
88
89 -- Define if we want to use titlebar on all applications.
90 use_titlebar = false
91 -- }}}
92
93 -- {{{ Tags
94 -- Define tags table.
95 tags = {}
96 for s = 1, screen.count() do
97     -- Each screen has its own tag table.
98     tags[s] = {}
99     -- Create 9 tags per screen.
100     for tagnumber = 1, 9 do
101         tags[s][tagnumber] = tag(tagnumber)
102         -- split at 0.5/50% exactly
103         tags[s][tagnumber].mwfact = 0.5
104         -- Add tags to screen one by one
105         tags[s][tagnumber].screen = s
106         awful.layout.set(layouts[5], tags[s][tagnumber])
107     end
108     -- I'm sure you want to see at least one tag.
109     tags[s][1].selected = true
110 end
111 -- }}}
112
113 -- {{{ Wibox
114 -- Create a textbox widget
115 mytextbox = widget({ type = "textbox", align = "right" })
116 -- Set the default text in textbox
117 mytextbox.text = "<b><small> " .. awesome.release .. " </small></b>"
118
119 -- Create a laucher widget and a main menu
120 myawesomemenu = {
121    { "manual", terminal .. " -e man awesome" },
122    { "edit config", editor_cmd .. " " .. awful.util.getdir("config") .. "/rc.lua" },
123    { "restart", awesome.restart },
124    { "quit", awesome.quit }
125 }
126
127 mymainmenu = awful.menu.new({ items = { { "awesome", myawesomemenu, beautiful.awesome_icon },
128                                         { "open terminal", terminal },
129                                         { "Debian", debian.menu.Debian_menu.Debian }
130                                       }
131                             })
132
133 mylauncher = awful.widget.launcher({ image = image(beautiful.awesome_icon),
134                                      menu = mymainmenu })
135
136 -- Create a systray
137 mysystray = widget({ type = "systray", align = "right" })
138
139 -- Create textbox widgets
140 mytimebox = widget({ type = "textbox", name = "mytimebox", align = "right" })
141 mybatterybox = widget({ type = "textbox", name = "mybatterybox", align = "right" })
142
143 -- Create a wibox for each screen and add it
144 mywibox = {}
145 mypromptbox = {}
146 mylayoutbox = {}
147 mytaglist = {}
148 mytaglist.buttons = awful.util.table.join(
149                     awful.button({ }, 1, awful.tag.viewonly),
150                     awful.button({ modkey }, 1, awful.client.movetotag),
151                     awful.button({ }, 3, function (tag) tag.selected = not tag.selected end),
152                     awful.button({ modkey }, 3, awful.client.toggletag),
153                     awful.button({ }, 4, awful.tag.viewnext),
154                     awful.button({ }, 5, awful.tag.viewprev)
155                     )
156 mytasklist = {}
157 mytasklist.buttons = awful.util.table.join(
158                      awful.button({ }, 1, function (c)
159                                               if not c:isvisible() then
160                                                   awful.tag.viewonly(c:tags()[1])
161                                               end
162                                               client.focus = c
163                                               c:raise()
164                                           end),
165                      awful.button({ }, 3, function ()
166                                               if instance then
167                                                   instance:hide()
168                                                   instance = nil
169                                               else
170                                                   instance = awful.menu.clients({ width=250 })
171                                               end
172                                           end),
173                      awful.button({ }, 4, function ()
174                                               awful.client.focus.byidx(1)
175                                               if client.focus then client.focus:raise() end
176                                           end),
177                      awful.button({ }, 5, function ()
178                                               awful.client.focus.byidx(-1)
179                                               if client.focus then client.focus:raise() end
180                                           end))
181
182 for s = 1, screen.count() do
183     -- Create a promptbox for each screen
184     mypromptbox[s] = awful.widget.prompt({ align = "left" })
185     -- Create an imagebox widget which will contains an icon indicating which layout we're using.
186     -- We need one layoutbox per screen.
187     mylayoutbox[s] = widget({ type = "imagebox", align = "right" })
188     mylayoutbox[s]:buttons(awful.util.table.join(
189                            awful.button({ }, 1, function () awful.layout.inc(layouts, 1) end),
190                            awful.button({ }, 3, function () awful.layout.inc(layouts, -1) end),
191                            awful.button({ }, 4, function () awful.layout.inc(layouts, 1) end),
192                            awful.button({ }, 5, function () awful.layout.inc(layouts, -1) end)))
193     -- Create a taglist widget
194     mytaglist[s] = awful.widget.taglist(s, awful.widget.taglist.label.all, mytaglist.buttons)
195
196     -- Create a tasklist widget
197     mytasklist[s] = awful.widget.tasklist(function(c)
198                                               return awful.widget.tasklist.label.currenttags(c, s)
199                                           end, mytasklist.buttons)
200
201     -- Create the wibox
202     mywibox[s] = wibox({ position = "top", fg = beautiful.fg_normal, bg = beautiful.bg_normal })
203     -- Add widgets to the wibox - order matters
204     mywibox[s].widgets = { mytaglist[s],
205                            mytasklist[s],
206                            mypromptbox[s],
207                            mybatterybox,
208                            mytimebox,
209                            mylayoutbox[s],
210                            s == screen.count() and mysystray or nil }
211     mywibox[s].screen = s
212 end
213 -- }}}
214
215 --Battery widget
216 batterywidget = widget({ type = 'progressbar', name = 'batterywidget' })
217 batterywidget.width = 100
218 batterywidget.height = 0.8
219 batterywidget.gap = 1
220 batterywidget.border_padding = 1
221 batterywidget.border_width = 1
222 batterywidget.ticks_count = 10
223 batterywidget.ticks_gap = 1
224 batterywidget.vertical = false
225 batterywidget:bar_properties_set('bat', {
226   bg = 'black',
227   fg = 'blue4',
228   fg_off = 'red',
229   reverse = false,
230   min_value = 0,
231   max_value = 100
232 })
233 -- }}}
234
235
236 -- {{{ Mouse bindings
237 root.buttons(awful.util.table.join(
238     awful.button({ }, 3, function () mymainmenu:toggle() end),
239     awful.button({ }, 4, awful.tag.viewnext),
240     awful.button({ }, 5, awful.tag.viewprev)
241 ))
242 -- }}}
243
244 -- {{{ Key bindings
245 globalkeys = awful.util.table.join(
246     awful.key({ modkey,           }, "Left",   awful.tag.viewprev       ),
247     awful.key({ modkey,           }, "Right",  awful.tag.viewnext       ),
248     awful.key({ modkey,           }, "Escape", awful.tag.history.restore),
249
250     awful.key({ modkey,           }, "j",
251         function ()
252             awful.client.focus.byidx( 1)
253             if client.focus then client.focus:raise() end
254         end),
255     awful.key({ modkey,           }, "k",
256         function ()
257             awful.client.focus.byidx(-1)
258             if client.focus then client.focus:raise() end
259         end),
260     awful.key({ modkey,           }, "w", function () mymainmenu:show(true)        end),
261
262     -- Layout manipulation
263     awful.key({ modkey, "Shift"   }, "j", function () awful.client.swap.byidx(  1) end),
264     awful.key({ modkey, "Shift"   }, "k", function () awful.client.swap.byidx( -1) end),
265     awful.key({ modkey, "Control" }, "j", function () awful.screen.focus( 1)       end),
266     awful.key({ modkey, "Control" }, "k", function () awful.screen.focus(-1)       end),
267     awful.key({ modkey,           }, "u", awful.client.urgent.jumpto),
268     awful.key({ modkey,           }, "Tab",
269         function ()
270             awful.client.focus.history.previous()
271             if client.focus then
272                 client.focus:raise()
273             end
274         end),
275
276     -- Standard program
277     awful.key({ modkey,           }, "Return", function () awful.util.spawn(terminal) end),
278     awful.key({ modkey, "Control" }, "r", awesome.restart),
279     awful.key({ modkey, "Shift"   }, "q", awesome.quit),
280
281     awful.key({ modkey,           }, "l",     function () awful.tag.incmwfact( 0.05)    end),
282     awful.key({ modkey,           }, "h",     function () awful.tag.incmwfact(-0.05)    end),
283     awful.key({ modkey, "Shift"   }, "h",     function () awful.tag.incnmaster( 1)      end),
284     awful.key({ modkey, "Shift"   }, "l",     function () awful.tag.incnmaster(-1)      end),
285     awful.key({ modkey, "Control" }, "h",     function () awful.tag.incncol( 1)         end),
286     awful.key({ modkey, "Control" }, "l",     function () awful.tag.incncol(-1)         end),
287     awful.key({ modkey,           }, "space", function () awful.layout.inc(layouts,  1) end),
288     awful.key({ modkey, "Shift"   }, "space", function () awful.layout.inc(layouts, -1) end),
289
290     -- Prompt
291     awful.key({ modkey },            "r",     function () mypromptbox[mouse.screen]:run() end),
292
293     awful.key({ modkey }, "x",
294               function ()
295                   awful.prompt.run({ prompt = "Run Lua code: " },
296                   mypromptbox[mouse.screen].widget,
297                   awful.util.eval, nil,
298                   awful.util.getdir("cache") .. "/history_eval")
299               end)
300 )
301
302 -- Client awful tagging: this is useful to tag some clients and then do stuff like move to tag on them
303 clientkeys = awful.util.table.join(
304     awful.key({ modkey,           }, "f",      function (c) c.fullscreen = not c.fullscreen  end),
305     awful.key({ modkey, "Shift"   }, "c",      function (c) c:kill()                         end),
306     awful.key({ modkey, "Control" }, "space",  awful.client.floating.toggle                     ),
307     awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end),
308     awful.key({ modkey,           }, "o",      awful.client.movetoscreen                        ),
309     awful.key({ modkey, "Shift"   }, "r",      function (c) c:redraw()                       end),
310     awful.key({ modkey }, "t", awful.client.togglemarked),
311     awful.key({ modkey,}, "m",
312         function (c)
313 --            if not awful.client.floating then
314 --                awful.client.floating.toggle()
315 --            end
316             c.maximized_horizontal = not c.maximized_horizontal
317             c.maximized_vertical   = not c.maximized_vertical
318         end)
319 )
320
321 -- Compute the maximum number of digit we need, limited to 9
322 keynumber = 0
323 for s = 1, screen.count() do
324    keynumber = math.min(9, math.max(#tags[s], keynumber));
325 end
326
327 for i = 1, keynumber do
328     globalkeys = awful.util.table.join(globalkeys,
329         awful.key({ modkey }, i,
330                   function ()
331                         local screen = mouse.screen
332                         if tags[screen][i] then
333                             awful.tag.viewonly(tags[screen][i])
334                         end
335                   end),
336         awful.key({ modkey, "Control" }, i,
337                   function ()
338                       local screen = mouse.screen
339                       if tags[screen][i] then
340                           tags[screen][i].selected = not tags[screen][i].selected
341                       end
342                   end),
343         awful.key({ modkey, "Shift" }, i,
344                   function ()
345                       if client.focus and tags[client.focus.screen][i] then
346                           awful.client.movetotag(tags[client.focus.screen][i])
347                       end
348                   end),
349         awful.key({ modkey, "Control", "Shift" }, i,
350                   function ()
351                       if client.focus and tags[client.focus.screen][i] then
352                           awful.client.toggletag(tags[client.focus.screen][i])
353                       end
354                   end),
355         awful.key({ modkey, "Shift" }, "F" .. i,
356                   function ()
357                       local screen = mouse.screen
358                       if tags[screen][i] then
359                           for k, c in pairs(awful.client.getmarked()) do
360                               awful.client.movetotag(tags[screen][i], c)
361                           end
362                       end
363                    end))
364 end
365
366 cmdmodkey = "Mod3"
367
368 -- xmms2 & sound
369 globalkeys = awful.util.table.join(globalkeys,
370   awful.key({ cmdmodkey }, "Prior", function () awful.util.spawn("amixer set Master 2+") end),
371   awful.key({ cmdmodkey }, "Next", function () awful.util.spawn("amixer set Master 2-") end),
372   awful.key({ cmdmodkey }, "Up", function () awful.util.spawn("amixer set PCM 2+") end),
373   awful.key({ cmdmodkey }, "Down", function () awful.util.spawn("amixer set PCM 2-") end),
374   awful.key({ cmdmodkey }, "Home", function () awful.util.spawn("amixer set Mic toggle") end),
375   awful.key({ cmdmodkey }, "End", function () awful.util.spawn("amixer set Master toggle") end),
376   awful.key({ cmdmodkey }, "Left", function () awful.util.spawn("xmms2 prev") end),
377   awful.key({ cmdmodkey }, "Right", function () awful.util.spawn("xmms2 next") end),
378   awful.key({ cmdmodkey }, "space", function () awful.util.spawn("xmms2 toggleplay") end),
379   awful.key({ cmdmodkey }, "backslash", function () awful.util.spawn("xmms2 current | head -1 | xmessage -nearmouse -timeout 5 -file -") end),
380   awful.key({ cmdmodkey, "Shift" }, "backslash", function () awful.util.spawn("xmms2 list | xmessage -nearmouse -timeout 5 -file -") end)
381 )
382
383 -- misc apps
384 globalkeys = awful.util.table.join(globalkeys,
385   awful.key({ cmdmodkey }, "n", function () awful.util.spawn("sensible-browser") end),
386   awful.key({ cmdmodkey }, "m", function () awful.util.spawn(terminal .. " -e mutt -f =store") end),
387   awful.key({ cmdmodkey }, "t", function () awful.util.spawn(terminal) end),
388   awful.key({ cmdmodkey }, "c", function () awful.util.spawn(terminal .. " -e python") end),
389   awful.key({ cmdmodkey }, "r", function () awful.util.spawn("gmrun") end),
390   awful.key({ cmdmodkey }, "j", function () awful.util.spawn("jpilot") end),
391   awful.key({ cmdmodkey }, "x", function () awful.util.spawn("/sbin/start-stop-daemon --start --background --exec /usr/bin/xscreensaver; xscreensaver-command -lock") end),
392   awful.key({ cmdmodkey, "Shift" }, "x", function () awful.util.spawn("xscreensaver-command -exit") end)
393 )
394
395 -- Set keys
396 root.keys(globalkeys)
397 -- }}}
398
399 -- {{{ Hooks
400 -- Hook function to execute when focusing a client.
401 awful.hooks.focus.register(function (c)
402     if not awful.client.ismarked(c) then
403         c.border_color = beautiful.border_focus
404     end
405 end)
406
407 -- Hook function to execute when unfocusing a client.
408 awful.hooks.unfocus.register(function (c)
409     if not awful.client.ismarked(c) then
410         c.border_color = beautiful.border_normal
411     end
412 end)
413
414 -- Hook function to execute when marking a client
415 awful.hooks.marked.register(function (c)
416     c.border_color = beautiful.border_marked
417 end)
418
419 -- Hook function to execute when unmarking a client.
420 awful.hooks.unmarked.register(function (c)
421     c.border_color = beautiful.border_focus
422 end)
423
424 -- Hook function to execute when the mouse enters a client.
425 awful.hooks.mouse_enter.register(function (c)
426     -- Sloppy focus, but disabled for magnifier layout
427     if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
428         and awful.client.focus.filter(c) then
429         client.focus = c
430     end
431 end)
432
433 -- Hook function to execute when a new client appears.
434 awful.hooks.manage.register(function (c, startup)
435     -- If we are not managing this application at startup,
436     -- move it to the screen where the mouse is.
437     -- We only do it for filtered windows (i.e. no dock, etc).
438     if not startup and awful.client.focus.filter(c) then
439         c.screen = mouse.screen
440     end
441
442     if use_titlebar then
443         -- Add a titlebar
444         awful.titlebar.add(c, { modkey = modkey })
445     end
446     -- Add mouse bindings
447     c:buttons(awful.util.table.join(
448         awful.button({ }, 1, function (c) client.focus = c; c:raise() end),
449         awful.button({ modkey }, 1, awful.mouse.client.move),
450         awful.button({ modkey }, 3, awful.mouse.client.resize)
451     ))
452     -- New client may not receive focus
453     -- if they're not focusable, so set border anyway.
454     c.border_width = beautiful.border_width
455     c.border_color = beautiful.border_normal
456
457     -- Check if the application should be floating.
458     -- OVERRIDDEN, SEE tiledapps BELOW
459     local cls = c.class
460     local inst = c.instance
461     if floatapps[cls] then
462         awful.client.floating.set(c, floatapps[cls])
463     elseif floatapps[inst] then
464         awful.client.floating.set(c, floatapps[inst])
465     end
466
467     -- Override with tiledapps
468     awful.client.floating.set(c, not (tiledapps[inst] or tiledapps[cls]))
469
470     -- Check application->screen/tag mappings.
471     local target
472     if apptags[cls] then
473         target = apptags[cls]
474     elseif apptags[inst] then
475         target = apptags[inst]
476     end
477     if target then
478         c.screen = target.screen
479         awful.client.movetotag(tags[target.screen][target.tag], c)
480     end
481
482     -- Do this after tag mapping, so you don't see it on the wrong tag for a split second.
483     client.focus = c
484
485     -- Set key bindings
486     c:keys(clientkeys)
487
488     -- Set the windows at the slave,
489     -- i.e. put it at the end of others instead of setting it master.
490     -- awful.client.setslave(c)
491
492     -- Honor size hints: if you want to drop the gaps between windows, set this to false.
493     c.size_hints_honor = true
494
495     -- Maximise some
496     if maxapps[inst] or maxapps[cls] then
497         c.maximized_horizontal = not c.maximized_horizontal
498         c.maximized_vertical   = not c.maximized_vertical
499     end
500 end)
501
502 -- Hook function to execute when arranging the screen.
503 -- (tag switch, new client, etc)
504 awful.hooks.arrange.register(function (screen)
505     local layout = awful.layout.getname(awful.layout.get(screen))
506     if layout and beautiful["layout_" ..layout] then
507         mylayoutbox[screen].image = image(beautiful["layout_" .. layout])
508     else
509         mylayoutbox[screen].image = nil
510     end
511
512     -- Give focus to the latest client in history if no window has focus
513     -- or if the current window is a desktop or a dock one.
514     if not client.focus then
515         local c = awful.client.focus.history.get(screen, 0)
516         if c then client.focus = c end
517     end
518 end)
519
520 -- Hook called every second
521 awful.hooks.timer.register(1, function ()
522     mytimebox.text = os.date(" %a %d %b %H:%M:%S ")
523 end)
524
525 -- Hook called every sixty seconds
526 function hook_battery()
527     mybatterybox.text = " " .. get_acpibatt() .. " "
528 end
529
530 -- {{{ Statusbar battery
531 --
532 function get_acpibatt()
533
534     local f = io.popen('acpi -b', 'r')
535     if not f then
536       return "acpi -b failed"
537     end
538
539     local s = f:read('*l')
540     f:close()
541     if not s then
542       return '-';
543     end
544
545     -- Battery 0: Discharging, 89%, 00:02:14 remaining
546     -- Battery 0: Charging, 58%, 00:02:14 until charged
547     -- Battery 0: Full, 100%
548     -- so find the first bit first and then go look for the time
549     local st, en, status, percent = string.find(s, '%a+%s%d:%s(%a+),%s(%d+%%)');
550     local st, en, time = string.find(s, ',%s(%d+:%d+):%d+%s%a+', en);
551
552     if not status or not percent then -- time can be empty if we're full
553       return "couldn't parse line " .. s
554     end
555
556     if not time then
557       return percent
558     end
559
560     if status == 'Charging' then
561       return '↑ ' .. percent;
562     elseif status == 'Discharging' then
563       return '↓ '.. time;
564     else
565       return '';
566     end
567 end
568 -- }}}
569
570 --{{{ batt hook
571 local function get_bat()
572   local a = io.open("/sys/class/power_supply/BAT1/charge_full")
573   for line in a:lines() do
574     full = line
575   end
576   a:close()
577   local b = io.open("/sys/class/power_supply/BAT1/charge_now")
578   for line in b:lines() do
579     now = line
580   end
581   b:close()
582   batt=math.floor(now*100/full)
583   batterywidget:bar_data_add("bat",batt )
584 end
585 --}}}
586
587 -- Set up some hooks
588 awful.hooks.timer.register(20, hook_battery)
589 -- awful.hooks.timer.register(5, get_bat)
590 -- }}}
591
592 -- Highlight statusbars on the screen that has focus,
593 -- set this to false if you only have one screen or
594 -- you don't like it :P
595 if screen.count() > 1 then
596   statusbar_highlight_focus = true
597 else
598   statusbar_highlight_focus = false
599 end
600
601 hook_battery()
602
603 function displayMonth(month,year,weekStart)
604     local t,wkSt=os.time{year=year, month=month+1, day=0},weekStart or 1
605     local d=os.date("*t",t)
606     local mthDays,stDay=d.day,(d.wday-d.day-wkSt+1)%7
607
608     local lines = {}
609
610     for x=0,6 do
611         lines[x+1] = os.date("%a ",os.time{year=2006,month=1,day=x+wkSt})
612     end
613     lines[8] = "    "
614
615     local writeLine = 1
616     while writeLine < (stDay + 1) do
617         lines[writeLine] = lines[writeLine] .. "   "
618         writeLine = writeLine + 1
619     end
620
621     for x=1,mthDays do
622         if writeLine == 8 then
623             writeLine = 1
624         end
625         if writeLine == 1 or x == 1 then
626             lines[8] = lines[8] .. os.date(" %V",os.time{year=year,month=month,day=x})
627         end
628         if (#(tostring(x)) == 1) then
629             x = " " .. x
630         end
631         lines[writeLine] = lines[writeLine] .. " " .. x
632         writeLine = writeLine + 1
633     end
634     local header = os.date("%B %Y\n",os.time{year=year,month=month,day=1})
635     header = string.rep(" ", math.floor((#(lines[1]) - #header) / 2 )) .. header
636
637     return header .. table.concat(lines, '\n')
638 end
639
640 local calendar = {}
641 function switchNaughtyMonth(switchMonths)
642     if (#calendar < 3) then return end
643     local swMonths = switchMonths or 1
644     calendar[1] = calendar[1] + swMonths
645     calendar[3].box.widgets[2].text = displayMonth(calendar[1], calendar[2], 2)
646 end
647
648 mytimebox.mouse_enter = function ()
649     local month, year = os.date('%m'), os.date('%Y')
650     calendar = { month, year,
651                 naughty.notify({
652                     text = displayMonth(month, year, 2),
653                     timeout = 0, hover_timeout = 0.5,
654                     width = 200, screen = mouse.screen
655                 })
656                }
657 end
658 mytimebox.mouse_leave = function () naughty.destroy(calendar[3]) end
659
660 mytimebox.buttons = awful.util.table.join(
661     awful.button({ }, 1, function() switchNaughtyMonth(-1) end),
662     awful.button({ }, 3, function() switchNaughtyMonth(1) end),
663     awful.button({ }, 4, function() switchNaughtyMonth(-1) end),
664     awful.button({ }, 5, function() switchNaughtyMonth(1) end),
665     awful.button({ 'Shift' }, 1, function() switchNaughtyMonth(-12) end),
666     awful.button({ 'Shift' }, 3, function() switchNaughtyMonth(12) end),
667     awful.button({ 'Shift' }, 4, function() switchNaughtyMonth(-12) end),
668     awful.button({ 'Shift' }, 5, function() switchNaughtyMonth(12) end)
669 )