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

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