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:

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