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:

reformat
[etc/awesome.git] / .config / awesome / rc.lua
1 -- Standard awesome library
2 require("awful")
3 require("awful.autofocus")
4 require("awful.rules")
5 -- Theme handling library
6 require("beautiful")
7 -- Notification library
8 require("naughty")
9
10 --require("vicious")
11
12 require("obvious.battery")
13 require("obvious.clock")
14
15 --require("bashets.bashets")
16
17 -- Load Debian menu entries
18 require("debian.menu")
19
20 -- {{{ Variable definitions
21 -- Themes define colours, icons, and wallpapers
22 -- The default is a dark theme
23 theme_path = "/usr/share/awesome/themes/default/theme.lua"
24 -- Uncommment this for a lighter theme
25 -- theme_path = "/usr/share/awesome/themes/sky/theme.lua"
26
27 wallpaper_cmd = { "awsetbg -t .config/awesome/bgstripes.png" } 
28
29 -- Actually load theme
30 beautiful.init(theme_path)
31
32 -- This is used later as the default terminal and editor to run.
33 terminal = "x-terminal-emulator"
34 editor = os.getenv("EDITOR") or "editor"
35 editor_cmd = terminal .. " -e " .. editor
36
37 -- Default modkey.
38 -- Usually, Mod4 is the key with a logo between Control and Alt.
39 -- If you do not like this or do not have such a key,
40 -- I suggest you to remap Mod4 to another key using xmodmap or other tools.
41 -- However, you can use another modifier like Mod1, but it may interact with others.
42 modkey = "Mod4"
43
44 -- Table of layouts to cover with awful.layout.inc, order matters.
45 layouts =
46 {
47 --    awful.layout.suit.tile,
48 --    awful.layout.suit.tile.left,
49 --    awful.layout.suit.tile.bottom,
50 --    awful.layout.suit.tile.top,
51     awful.layout.suit.fair,
52     awful.layout.suit.fair.horizontal,
53 --    awful.layout.suit.spiral,
54 --    awful.layout.suit.spiral.dwindle,
55     awful.layout.suit.max,
56 --    awful.layout.suit.max.fullscreen,
57     awful.layout.suit.magnifier,
58     awful.layout.suit.floating
59 }
60
61 ---- Table of clients that should be set floating. The index may be either
62 ---- the application class or instance. The instance is useful when running
63 ---- a console app in a terminal like (Music on Console)
64 ----    xterm -name mocp -e mocp
65 ---- OVERRULED BY TILEDAPPS BELOW
66 --floatapps =
67 --{
68 --    -- by class
69 --    ["MPlayer"] = true,
70 --    ["pinentry"] = true,
71 --    ["GIMP"] = true,
72 --    ["twinkle"] = true,
73 --    ["Add-ons"] = true,
74 --    ["Play stream"] = true,
75 --    ["gscan2pdf"] = true,
76 --}
77 --
78 ---- Applications that should never float, assuming everything else floats
79 ---- (by instance)
80 --tiledapps =
81 --{
82 --    ["urxvt"] = true,
83 --}
84 --
85 ---- Applications that should be maximised
86 ---- (by instance)
87 --maxapps =
88 --{
89 --    ["Navigator"] = true,
90 --    -- jpilot is -v
91 --    ["-v"] = true,
92 --    ["Xpdf"] = true,
93 --    ["gscan2pdf"] = true
94 --}
95 --
96 ---- Applications to be moved to a pre-defined tag by class or instance.
97 ---- Use the screen and tags indices.
98 --apptags =
99 --{
100 --    ["Navigator"] = { screen = 1, tag = 9 },
101 --    -- jpilot is -v
102 --    ["-v"] = { screen = 1, tag = 8 },
103 --}
104
105 -- Define if we want to use titlebar on all applications.
106 use_titlebar = false
107 -- }}}
108
109 -- {{{ Tags
110 tags = {}
111 tags.settings = {
112     { name = "1", layout = layouts[1] },
113     { name = "2", layout = layouts[1] },
114     { name = "3", layout = layouts[1] },
115     { name = "4", layout = layouts[1] },
116     { name = "5", layout = layouts[5] },
117     { name = "6", layout = layouts[3] },
118     { name = "7", layout = layouts[3] },
119     { name = "8", layout = layouts[3] },
120     { name = "9", layout = layouts[3] },
121 }
122
123 -- Define a tag table which hold all screen tags.
124 for s = 1, screen.count() do
125     tags[s] = {}
126     for i, v in ipairs(tags.settings) do
127         tags[s][i] = tag({ name = v.name })
128         tags[s][i].screen = s
129         awful.tag.setproperty(tags[s][i], "layout", v.layout)
130         awful.tag.setproperty(tags[s][i], "mwfact", v.mwfact)
131         awful.tag.setproperty(tags[s][i], "hide",   v.hide)
132     end
133     tags[s][1].selected = true
134 end
135
136 if screen.count() == 3 then
137   tags[1][1].selected = false
138   tags[1][9].selected = true
139 end
140 -- }}}
141
142 -- {{{ Menu
143 -- Create a laucher widget and a main menu
144 myawesomemenu = {
145    { "manual", terminal .. " -e man awesome" },
146    { "edit config", editor_cmd .. " " .. awful.util.getdir("config") .. "/rc.lua" },
147    { "restart", awesome.restart },
148    { "quit", awesome.quit }
149 }
150
151 mymainmenu = awful.menu({ items = { { "awesome", myawesomemenu, beautiful.awesome_icon },
152                                     { "Debian", debian.menu.Debian_menu.Debian },
153                                     { "open terminal", terminal }
154                                   }
155                         })
156
157 mylauncher = awful.widget.launcher({ image = image(beautiful.awesome_icon),
158                                      menu = mymainmenu })
159 -- }}}
160
161 -- {{{ Wibox
162
163 -- {{{ Reusable separators
164 spacer         = widget({ type = "textbox", name = "spacer" })
165 separator      = widget({ type = "textbox", name = "separator" })
166 spacer.text    = " "
167 separator.text = "٭"
168 -- }}}
169
170 ---- {{{ CPU usage and temperature
171 ---- Widget icon
172 --cpuicon        = widget({ type = "imagebox", name = "cpuicon" })
173 --cpuicon.image  = image(beautiful.widget_cpu)
174 ---- Initialize widgets
175 --thermalwidget  = widget({ type = "textbox", name = "thermalwidget" })
176 --cpuwidget      = awful.widget.graph({ layout = awful.widget.layout.horizontal.rightleft })
177 ---- Graph properties
178 --cpuwidget:set_width(50)
179 ----cpuwidget:set_scale(false)
180 --cpuwidget:set_max_value(100)
181 --cpuwidget:set_background_color(beautiful.fg_off_widget)
182 --cpuwidget:set_border_color(beautiful.border_widget)
183 --cpuwidget:set_color(beautiful.fg_end_widget)
184 --cpuwidget:set_gradient_angle(0)
185 --cpuwidget:set_gradient_colors({
186 --    beautiful.fg_end_widget,
187 --    beautiful.fg_center_widget,
188 --    beautiful.fg_widget })
189 ---- Register widgets
190 --vicious.register(cpuwidget, vicious.widgets.cpu, "$1")
191 --vicious.register(thermalwidget, vicious.widgets.thermal, "CPU: $1°C", 19, "hwmon0")
192 ---- }}}
193
194 -- Battery widget
195 --batterywidget = widget({ type = 'progressbar', name = 'batterywidget' })
196 --batterywidget.width = 100
197 --batterywidget.height = 0.8
198 --batterywidget.gap = 1
199 --batterywidget.border_padding = 1
200 --batterywidget.border_width = 1
201 --batterywidget.ticks_count = 10
202 --batterywidget.ticks_gap = 1
203 --batterywidget.vertical = false
204 --batterywidget:bar_properties_set('bat', {
205 --  bg = 'black',
206 --  fg = 'blue4',
207 --  fg_off = 'red',
208 --  reverse = false,
209 --  min_value = 0,
210 --  max_value = 100
211 --})
212
213 -- Create a textclock widget
214 mytextclock = awful.widget.textclock({ align = "right" }, "%a %d %b %H:%M:%S", 1)
215
216 -- Create a systray
217 mysystray = widget({ type = "systray", align = "right" })
218
219 mybatterybox = widget({ type = "textbox", name = "mybatterybox", align = "right" })
220
221 -- Create a wibox for each screen and add it
222 mywibox = {}
223 mypromptbox = {}
224 mylayoutbox = {}
225 mytaglist = {}
226 mytaglist.buttons = awful.util.table.join(
227                     awful.button({ }, 1, awful.tag.viewonly),
228                     awful.button({ modkey }, 1, awful.client.movetotag),
229                     awful.button({ }, 3, awful.tag.viewtoggle),
230                     awful.button({ modkey }, 3, awful.client.toggletag),
231                     awful.button({ }, 4, awful.tag.viewnext),
232                     awful.button({ }, 5, awful.tag.viewprev)
233                     )
234 mytasklist = {}
235 mytasklist.buttons = awful.util.table.join(
236                      awful.button({ }, 1, function (c)
237                                               if not c:isvisible() then
238                                                   awful.tag.viewonly(c:tags()[1])
239                                               end
240                                               client.focus = c
241                                               c:raise()
242                                           end),
243                      awful.button({ }, 3, function ()
244                                               if instance then
245                                                   instance:hide()
246                                                   instance = nil
247                                               else
248                                                   instance = awful.menu.clients({ width=250 })
249                                               end
250                                           end),
251                      awful.button({ }, 4, function ()
252                                               awful.client.focus.byidx(1)
253                                               if client.focus then client.focus:raise() end
254                                           end),
255                      awful.button({ }, 5, function ()
256                                               awful.client.focus.byidx(-1)
257                                               if client.focus then client.focus:raise() end
258                                           end))
259
260 for s = 1, screen.count() do
261     -- Create a promptbox for each screen
262     mypromptbox[s] = awful.widget.prompt({ layout = awful.widget.layout.horizontal.leftright })
263     -- Create an imagebox widget which will contains an icon indicating which layout we're using.
264     -- We need one layoutbox per screen.
265     mylayoutbox[s] = awful.widget.layoutbox(s)
266     mylayoutbox[s]:buttons(awful.util.table.join(
267                            awful.button({ }, 1, function () awful.layout.inc(layouts, 1) end),
268                            awful.button({ }, 3, function () awful.layout.inc(layouts, -1) end),
269                            awful.button({ }, 4, function () awful.layout.inc(layouts, 1) end),
270                            awful.button({ }, 5, function () awful.layout.inc(layouts, -1) end)))
271     -- Create a taglist widget
272     mytaglist[s] = awful.widget.taglist(s, awful.widget.taglist.label.all, mytaglist.buttons)
273
274     -- Create a tasklist widget
275     mytasklist[s] = awful.widget.tasklist(function(c)
276                                               return awful.widget.tasklist.label.currenttags(c, s)
277                                           end, mytasklist.buttons)
278
279     -- Create the wibox
280     mywibox[s] = awful.wibox({ position = "top", screen = s })
281     -- Add widgets to the wibox - order matters
282     mywibox[s].widgets = {
283         {
284 --            mylauncher,
285             mytaglist[s],
286             mypromptbox[s],
287             layout = awful.widget.layout.horizontal.leftright
288         },
289         mylayoutbox[s],
290         spacer,
291         mytextclock,
292         spacer, separator, spacer,
293         obvious.battery.widget,
294 --        mybatterybox,
295 --        batterywidget,
296 --        spacer, separator, spacer,
297 --        cpuwidget.widget,
298 --        spacer, separator, spacer,
299 --        thermalwidget.widget,
300         spacer,
301         s == screen.count() and mysystray or nil,
302         mytasklist[s],
303         layout = awful.widget.layout.horizontal.rightleft
304     }
305 end
306
307 -- }}}
308
309 -- {{{ Mouse bindings
310 root.buttons(awful.util.table.join(
311     awful.button({ }, 3, function () mymainmenu:toggle() end),
312     awful.button({ }, 4, awful.tag.viewnext),
313     awful.button({ }, 5, awful.tag.viewprev)
314 ))
315 -- }}}
316
317 -- {{{ Key bindings
318 globalkeys = awful.util.table.join(
319     awful.key({ modkey,           }, "Left",   awful.tag.viewprev       ),
320     awful.key({ modkey,           }, "Right",  awful.tag.viewnext       ),
321     awful.key({ modkey,           }, "Escape", awful.tag.history.restore),
322     awful.key({ modkey, "Shift"   }, "Right", function () awful.screen.focus( 1)       end),
323     awful.key({ modkey, "Shift"   }, "Left", function () awful.screen.focus(-1)       end),
324     awful.key({ modkey, "Shift"   }, "h",   awful.tag.viewprev       ),
325     awful.key({ modkey, "Shift"   }, "l",  awful.tag.viewnext       ),
326
327     awful.key({ modkey,           }, "k",
328         function ()
329             awful.client.focus.byidx( 1)
330             if client.focus then client.focus:raise() end
331         end),
332     awful.key({ modkey,           }, "j",
333         function ()
334             awful.client.focus.byidx(-1)
335             if client.focus then client.focus:raise() end
336         end),
337     awful.key({ modkey,           }, "w", function () mymainmenu:show(true)        end),
338
339     -- Layout manipulation
340     awful.key({ modkey, "Shift"   }, "k", function () awful.client.swap.byidx(  1) end),
341     awful.key({ modkey, "Shift"   }, "j", function () awful.client.swap.byidx( -1) end),
342     awful.key({ modkey, "Control" }, "k", function () awful.screen.focus( 1)       end),
343     awful.key({ modkey, "Control" }, "j", function () awful.screen.focus(-1)       end),
344     awful.key({ modkey,           }, "u", awful.client.urgent.jumpto),
345     awful.key({ modkey,           }, "Tab",
346         function ()
347             awful.client.focus.history.previous()
348             if client.focus then
349                 client.focus:raise()
350             end
351         end),
352
353     -- Standard program
354     awful.key({ modkey,           }, "Return", function () awful.util.spawn(terminal) end),
355     awful.key({ modkey, "Control" }, "r", awesome.restart),
356     awful.key({ modkey, "Shift"   }, "q", awesome.quit),
357
358     awful.key({ modkey,           }, "l",     function () awful.tag.incmwfact( 0.05)    end),
359     awful.key({ modkey,           }, "h",     function () awful.tag.incmwfact(-0.05)    end),
360     awful.key({ modkey, "Shift"   }, "h",     function () awful.tag.incnmaster( 1)      end),
361     awful.key({ modkey, "Shift"   }, "l",     function () awful.tag.incnmaster(-1)      end),
362     awful.key({ modkey, "Control" }, "h",     function () awful.tag.incncol( 1)         end),
363     awful.key({ modkey, "Control" }, "l",     function () awful.tag.incncol(-1)         end),
364     awful.key({ modkey,           }, "space", function () awful.layout.inc(layouts,  1) end),
365     awful.key({ modkey, "Shift"   }, "space", function () awful.layout.inc(layouts, -1) end),
366
367     -- Prompt
368     awful.key({ modkey },            "r",     function () mypromptbox[mouse.screen]:run() end),
369
370     awful.key({ modkey }, "x",
371               function ()
372                   awful.prompt.run({ prompt = "Run Lua code: " },
373                   mypromptbox[mouse.screen].widget,
374                   awful.util.eval, nil,
375                   awful.util.getdir("cache") .. "/history_eval")
376               end)
377 )
378
379 clientkeys = awful.util.table.join(
380     awful.key({ modkey,           }, "f",      function (c) c.fullscreen = not c.fullscreen  end),
381     awful.key({ modkey, "Shift"   }, "c",      function (c) c:kill()                         end),
382     awful.key({ modkey, "Control" }, "space",  awful.client.floating.toggle                     ),
383     awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end),
384     awful.key({ modkey,           }, "o",      awful.client.movetoscreen                        ),
385     awful.key({ modkey, "Shift"   }, "r",      function (c) c:redraw()                       end),
386     awful.key({ modkey,           }, "t",      function (c) c.ontop = not c.ontop            end),
387     awful.key({ modkey,           }, "n",      function (c) c.minimized = not c.minimized    end),
388     awful.key({ modkey,           }, "m",
389         function (c)
390             -- silly lua can't do bitwise operations
391             if not c.maximized_horizontal and not c.maximized_vertical then
392                 c.maximized_horizontal = true
393                 c.maximized_vertical = true
394             elseif c.maximized_horizontal and c.maximized_vertical then
395                 c.maximized_horizontal = false
396                 c.maximized_vertical = true
397             elseif not c.maximized_horizontal and c.maximized_vertical then
398                 c.maximized_horizontal = true
399                 c.maximized_vertical = false
400             elseif c.maximized_horizontal and not c.maximized_vertical then
401                 c.maximized_horizontal = false
402                 c.maximized_vertical = false
403             end
404         end)
405 )
406
407 -- Compute the maximum number of digit we need, limited to 9
408 keynumber = 0
409 for s = 1, screen.count() do
410    keynumber = math.min(9, math.max(#tags[s], keynumber));
411 end
412
413 -- Bind all key numbers to tags.
414 -- Be careful: we use keycodes to make it works on any keyboard layout.
415 -- This should map on the top row of your keyboard, usually 1 to 9.
416 for i = 1, keynumber do
417     globalkeys = awful.util.table.join(globalkeys,
418         awful.key({ modkey }, "#" .. i + 9,
419                   function ()
420                         local screen = mouse.screen
421                         if tags[screen][i] then
422                             awful.tag.viewonly(tags[screen][i])
423                         end
424                   end),
425         awful.key({ modkey, "Control" }, "#" .. i + 9,
426                   function ()
427                       local screen = mouse.screen
428                       if tags[screen][i] then
429                           awful.tag.viewtoggle(tags[screen][i])
430                       end
431                   end),
432         awful.key({ modkey, "Shift" }, "#" .. i + 9,
433                   function ()
434                       if client.focus and tags[client.focus.screen][i] then
435                           awful.client.movetotag(tags[client.focus.screen][i])
436                       end
437                   end),
438         awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
439                   function ()
440                       if client.focus and tags[client.focus.screen][i] then
441                           awful.client.toggletag(tags[client.focus.screen][i])
442                       end
443                   end))
444 end
445
446 clientbuttons = awful.util.table.join(
447     awful.button({ }, 1, function (c) client.focus = c; c:raise() end),
448     awful.button({ modkey }, 1, awful.mouse.client.move),
449     awful.button({ modkey }, 3, awful.mouse.client.resize))
450
451 cmdmodkey = "Mod3"
452
453 -- xmms2 & sound
454 globalkeys = awful.util.table.join(globalkeys,
455   awful.key({ cmdmodkey }, "Prior", function () awful.util.spawn("amixer set Master 2%+") end),
456   awful.key({ cmdmodkey }, "Next", function () awful.util.spawn("amixer set Master 2%-") end),
457   awful.key({ cmdmodkey }, "Up", function () awful.util.spawn("amixer set PCM 2%+") end),
458   awful.key({ cmdmodkey }, "Down", function () awful.util.spawn("amixer set PCM 2%-") end),
459   awful.key({ cmdmodkey }, "Home", function () awful.util.spawn("amixer set Mic toggle") end),
460   awful.key({ cmdmodkey }, "End", function () awful.util.spawn("amixer set Master toggle") end),
461   awful.key({ cmdmodkey }, "Left", function () awful.util.spawn("nyxmms2 prev") end),
462   awful.key({ cmdmodkey }, "Right", function () awful.util.spawn("nyxmms2 next") end),
463   awful.key({ cmdmodkey }, "space", function () awful.util.spawn("nyxmms2 toggle") end),
464   awful.key({ cmdmodkey }, "backslash", function ()
465     local f = io.popen('nyxmms2 current', 'r')
466     for s, t in string.gmatch(f:read(), '(%w+):%s+([^:]+)') do
467       naughty.notify({ title = s, text = t, timeout = 5 })
468     end
469     f:close()
470   end),
471   awful.key({ cmdmodkey, "Shift" }, "backslash", function ()
472     local f = io.popen('nyxmms2 list', 'r')
473     naughty.notify({ title = "Playlist", text = f:read("*a"), timeout = 15 })
474     f:close()
475   end)
476 )
477
478 -- misc apps
479 globalkeys = awful.util.table.join(globalkeys,
480   awful.key({ cmdmodkey }, "n", function () awful.util.spawn("sensible-browser") end),
481   awful.key({ cmdmodkey }, "m", function () awful.util.spawn(terminal .. " -e mutt -f =store") end),
482   awful.key({ cmdmodkey }, "t", function () awful.util.spawn(terminal) end),
483   awful.key({ cmdmodkey }, "y", function () awful.util.spawn(terminal .. " -e python") end),
484   awful.key({ cmdmodkey }, "c", function () awful.util.spawn("icedove") end),
485   awful.key({ cmdmodkey }, "r", function () mypromptbox[mouse.screen]:run() end),
486   awful.key({ cmdmodkey }, "g", function () awful.util.spawn("gscan2pdf") end),
487   awful.key({ cmdmodkey }, "o", function () awful.util.spawn("okular") end),
488   awful.key({ cmdmodkey }, "l", function () awful.util.spawn("libreoffice") end),
489   awful.key({ cmdmodkey }, "i", function () awful.util.spawn(terminal .. " -title irc -name irc -e mosh -- irc screen -dr irc") end),
490   awful.key({ cmdmodkey }, "x", function () awful.util.spawn_with_shell("/sbin/start-stop-daemon --start --background --exec /usr/bin/xscreensaver -- -no-capture-stderr -log ~/.tmp/xscreensaver.log; xscreensaver-command -lock") end),
491   awful.key({ cmdmodkey, "Shift" }, "x", function () awful.util.spawn("xscreensaver-command -exit") end),
492   awful.key(nil, "XF86ScreenSaver", function () awful.util.spawn("xset dpms force off") end)
493 )
494
495 -- Set keys
496 root.keys(globalkeys)
497 -- }}}
498
499 -- {{{ Rules
500 awful.rules.rules = {
501     -- All clients will match this rule.
502     { rule = { },
503       properties = { border_width = beautiful.border_width,
504                      border_color = beautiful.border_normal,
505                      focus = true,
506                      floating = true,
507                      keys = clientkeys,
508                      buttons = clientbuttons },
509       callback = awful.placement.centered
510     },
511     { rule = { class = "URxvt" },
512       properties = { floating = false } },
513     { rule = { class = "URxvt", instance = "irc" },
514       properties = { floating = false, tag = tags[screen.count()][screen.count() == 1 and 2 or 1], switchtotag = true } },
515     { rule = { class = "Iceweasel", instance = "Navigator" },
516       properties = { tag = tags[screen.count() == 3 and 1 or screen.count()][9], switchtotag = false, floating = false } },
517     { rule = { class = "Icedove", instance = "Mail" },
518       properties = { tag = tags[screen.count() == 3 and 1 or screen.count()][8], switchtotag = false, floating = false } },
519 }
520 -- }}}
521
522 -- {{{ Signals
523 -- Signal function to execute when a new client appears.
524 client.add_signal("manage", function (c, startup)
525     -- Add a titlebar
526     -- awful.titlebar.add(c, { modkey = modkey })
527
528     -- Enable sloppy focus
529     c:add_signal("mouse::enter", function(c)
530         if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
531             and awful.client.focus.filter(c) then
532             client.focus = c
533         end
534     end)
535
536     if not startup then
537         -- Set the windows at the slave,
538         -- i.e. put it at the end of others instead of setting it master.
539         -- awful.client.setslave(c)
540
541         -- Put windows in a smart way, only if they does not set an initial position.
542         if not c.size_hints.user_position and not c.size_hints.program_position then
543             --awful.placement.center_vertical(c)
544             --awful.placement.center_horizontal(c)
545             awful.placement.no_overlap(c)
546             awful.placement.no_offscreen(c)
547         end
548     end
549     c.size_hints_honor = false
550 end)
551
552 client.add_signal("focus", function(c) c.border_color = beautiful.border_focus end)
553 client.add_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
554
555 function clear_urgency_flag(c)
556     print("property::urgent received for client: ", c)
557     io.flush ()
558 --    if c.urgent then
559 --        c.urgent = false
560 --    end
561 end
562
563 client.add_signal("new", function (c)
564   c:add_signal("property::urgent", clear_urgency_flag)
565 end)
566
567 -- Hook called every sixty seconds
568 function hook_battery()
569     mybatterybox.text = " " .. get_acpibatt() .. " "
570 end
571 -- }}}
572
573 -- {{{ Statusbar battery
574 --
575 function get_acpibatt()
576     local f = io.popen('acpi -b', 'r')
577     if not f then
578       return "acpi -b failed"
579     end
580
581     local s = f:read('*l')
582     f:close()
583     if not s then
584       return '-';
585     end
586
587     -- Battery 0: Discharging, 89%, 00:02:14 remaining
588     -- Battery 0: Charging, 58%, 00:02:14 until charged
589     -- Battery 0: Full, 100%
590     -- so find the first bit first and then go look for the time
591     local st, en, status, percent = string.find(s, '%a+%s%d:%s(%a+),%s(%d+%%)');
592     local st, en, time = string.find(s, ',%s(%d+:%d+):%d+%s%a+', en);
593
594     if not status or not percent then -- time can be empty if we're full
595       return "couldn't parse line " .. s
596     end
597
598     if not time then
599       return percent
600     end
601
602     if status == 'Charging' then
603       return '↑ ' .. percent;
604     elseif status == 'Discharging' then
605       return '↓ '.. time;
606     else
607       return '';
608     end
609 end
610 --t = timer({ timeout = 20 })
611 --t:add_signal('timeout', hook_battery)
612 --t:start()
613 --hook_battery()
614 --bashets.register_lua(mybatterybox, get_acpibatt, '%1', 30)
615 --bashets.start()
616 -- }}}