]> 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:

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