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

c558b8dc0b5221d7466a73e517b8a7161a760cfe
[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             c.maximized_horizontal = not c.maximized_horizontal
391             c.maximized_vertical   = not c.maximized_vertical
392         end)
393 )
394
395 -- Compute the maximum number of digit we need, limited to 9
396 keynumber = 0
397 for s = 1, screen.count() do
398    keynumber = math.min(9, math.max(#tags[s], keynumber));
399 end
400
401 -- Bind all key numbers to tags.
402 -- Be careful: we use keycodes to make it works on any keyboard layout.
403 -- This should map on the top row of your keyboard, usually 1 to 9.
404 for i = 1, keynumber do
405     globalkeys = awful.util.table.join(globalkeys,
406         awful.key({ modkey }, "#" .. i + 9,
407                   function ()
408                         local screen = mouse.screen
409                         if tags[screen][i] then
410                             awful.tag.viewonly(tags[screen][i])
411                         end
412                   end),
413         awful.key({ modkey, "Control" }, "#" .. i + 9,
414                   function ()
415                       local screen = mouse.screen
416                       if tags[screen][i] then
417                           awful.tag.viewtoggle(tags[screen][i])
418                       end
419                   end),
420         awful.key({ modkey, "Shift" }, "#" .. i + 9,
421                   function ()
422                       if client.focus and tags[client.focus.screen][i] then
423                           awful.client.movetotag(tags[client.focus.screen][i])
424                       end
425                   end),
426         awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
427                   function ()
428                       if client.focus and tags[client.focus.screen][i] then
429                           awful.client.toggletag(tags[client.focus.screen][i])
430                       end
431                   end))
432 end
433
434 clientbuttons = awful.util.table.join(
435     awful.button({ }, 1, function (c) client.focus = c; c:raise() end),
436     awful.button({ modkey }, 1, awful.mouse.client.move),
437     awful.button({ modkey }, 3, awful.mouse.client.resize))
438
439 cmdmodkey = "Mod3"
440
441 -- xmms2 & sound
442 globalkeys = awful.util.table.join(globalkeys,
443   awful.key({ cmdmodkey }, "Prior", function () awful.util.spawn("amixer set Master 2+") end),
444   awful.key({ cmdmodkey }, "Next", function () awful.util.spawn("amixer set Master 2-") end),
445   awful.key({ cmdmodkey }, "Up", function () awful.util.spawn("amixer set PCM 2+") end),
446   awful.key({ cmdmodkey }, "Down", function () awful.util.spawn("amixer set PCM 2-") end),
447   awful.key({ cmdmodkey }, "Home", function () awful.util.spawn("amixer set Mic toggle") end),
448   awful.key({ cmdmodkey }, "End", function () awful.util.spawn("amixer set Master toggle") end),
449   awful.key({ cmdmodkey }, "Left", function () awful.util.spawn("nyxmms2 prev") end),
450   awful.key({ cmdmodkey }, "Right", function () awful.util.spawn("nyxmms2 next") end),
451   awful.key({ cmdmodkey }, "space", function () awful.util.spawn("nyxmms2 toggle") end),
452   awful.key({ cmdmodkey }, "backslash", function ()
453     local f = io.popen('nyxmms2 current', 'r')
454     for s, t in string.gmatch(f:read(), '(%w+):%s+([^:]+)') do
455       naughty.notify({ title = s, text = t, timeout = 5 })
456     end
457     f:close()
458   end),
459   awful.key({ cmdmodkey, "Shift" }, "backslash", function ()
460     local f = io.popen('nyxmms2 list', 'r')
461     naughty.notify({ title = "Playlist", text = f:read("*a"), timeout = 15 })
462     f:close()
463   end)
464 )
465
466 -- misc apps
467 globalkeys = awful.util.table.join(globalkeys,
468   awful.key({ cmdmodkey }, "n", function () awful.util.spawn("sensible-browser") end),
469   awful.key({ cmdmodkey }, "m", function () awful.util.spawn(terminal .. " -e mutt -f =store") end),
470   awful.key({ cmdmodkey }, "t", function () awful.util.spawn(terminal) end),
471   awful.key({ cmdmodkey }, "y", function () awful.util.spawn(terminal .. " -e python") end),
472   awful.key({ cmdmodkey }, "c", function () awful.util.spawn(terminal .. " -e wyrd") end),
473   awful.key({ cmdmodkey }, "r", function () mypromptbox[mouse.screen]:run() end),
474   awful.key({ cmdmodkey }, "g", function () awful.util.spawn("gscan2pdf") end),
475   awful.key({ cmdmodkey }, "o", function () awful.util.spawn("okular") end),
476   awful.key({ cmdmodkey }, "l", function () awful.util.spawn("libreoffice") end),
477   awful.key({ cmdmodkey }, "i", function () awful.util.spawn(terminal .. " -title irc -name irc -e mosh -- irc screen -dr irc") end),
478   awful.key({ cmdmodkey }, "x", function () awful.util.spawn_with_shell("/sbin/start-stop-daemon --start --background --exec /usr/bin/xscreensaver; xscreensaver-command -lock") end),
479   awful.key({ cmdmodkey, "Shift" }, "x", function () awful.util.spawn("xscreensaver-command -exit") end),
480   awful.key(nil, "XF86ScreenSaver", function () awful.util.spawn("xset dpms force off") end)
481 )
482
483 -- Set keys
484 root.keys(globalkeys)
485 -- }}}
486
487 -- {{{ Rules
488 awful.rules.rules = {
489     -- All clients will match this rule.
490     { rule = { },
491       properties = { border_width = beautiful.border_width,
492                      border_color = beautiful.border_normal,
493                      focus = true,
494                      floating = true,
495                      keys = clientkeys,
496                      buttons = clientbuttons },
497       callback = awful.placement.centered },
498     { rule = { class = "URxvt" },
499       properties = { floating = false } },
500     { rule = { class = "URxvt", instance = "irc" },
501       properties = { floating = false, tag = tags[screen.count()][screen.count() == 1 and 2 or 1], switchtotag = true } },
502     { rule = { class = "Iceweasel", instance = "Navigator" },
503       properties = { tag = tags[screen.count() == 3 and 1 or screen.count()][9], switchtotag = false, floating = false } },
504 --    { rule = { class = "Iceweasel", instance = "Dialog" },
505 --      properties = { floating = true } },
506     { rule = { class = "Jpilot", instance = "jpilot" },
507       properties = { tag = tags[screen.count() == 3 and 1 or screen.count()][8], switchtotag = true, floating = false } },
508    -- { rule = { name = "OpenOffice.org" },
509   --    properties = { switchtotag = true, floating = true, maximized_vertical = true, maximized_horizontal = true, callback = awful.placement.no_offscreen } },
510  --   { rule = { name = "Okular" },
511 --      properties = { switchtotag = true, floating = true, maximized_vertical = true, maximized_horizontal = true, callback = awful.placement.no_offscreen } },
512 }
513 -- }}}
514
515 -- {{{ Signals
516 -- Signal function to execute when a new client appears.
517 client.add_signal("manage", function (c, startup)
518     -- Add a titlebar
519     -- awful.titlebar.add(c, { modkey = modkey })
520
521     -- Enable sloppy focus
522     c:add_signal("mouse::enter", function(c)
523         if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
524             and awful.client.focus.filter(c) then
525             client.focus = c
526         end
527     end)
528
529     if not startup then
530         -- Set the windows at the slave,
531         -- i.e. put it at the end of others instead of setting it master.
532         -- awful.client.setslave(c)
533
534         -- Put windows in a smart way, only if they does not set an initial position.
535         if not c.size_hints.user_position and not c.size_hints.program_position then
536             --awful.placement.center_vertical(c)
537             --awful.placement.center_horizontal(c)
538             awful.placement.no_overlap(c)
539             awful.placement.no_offscreen(c)
540         end
541     end
542     c.size_hints_honor = false
543 end)
544
545 client.add_signal("focus", function(c) c.border_color = beautiful.border_focus end)
546 client.add_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
547
548 function clear_urgency_flag(c)
549     print("property::urgent received for client: ", c)
550     io.flush ()
551 --    if c.urgent then
552 --        c.urgent = false
553 --    end
554 end
555
556 client.add_signal("new", function (c)
557   c:add_signal("property::urgent", clear_urgency_flag)
558 end)
559
560 -- Hook called every sixty seconds
561 function hook_battery()
562     mybatterybox.text = " " .. get_acpibatt() .. " "
563 end
564 -- }}}
565
566 -- {{{ Statusbar battery
567 --
568 function get_acpibatt()
569     local f = io.popen('acpi -b', 'r')
570     if not f then
571       return "acpi -b failed"
572     end
573
574     local s = f:read('*l')
575     f:close()
576     if not s then
577       return '-';
578     end
579
580     -- Battery 0: Discharging, 89%, 00:02:14 remaining
581     -- Battery 0: Charging, 58%, 00:02:14 until charged
582     -- Battery 0: Full, 100%
583     -- so find the first bit first and then go look for the time
584     local st, en, status, percent = string.find(s, '%a+%s%d:%s(%a+),%s(%d+%%)');
585     local st, en, time = string.find(s, ',%s(%d+:%d+):%d+%s%a+', en);
586
587     if not status or not percent then -- time can be empty if we're full
588       return "couldn't parse line " .. s
589     end
590
591     if not time then
592       return percent
593     end
594
595     if status == 'Charging' then
596       return '↑ ' .. percent;
597     elseif status == 'Discharging' then
598       return '↓ '.. time;
599     else
600       return '';
601     end
602 end
603 --t = timer({ timeout = 20 })
604 --t:add_signal('timeout', hook_battery)
605 --t:start()
606 --hook_battery()
607 --bashets.register_lua(mybatterybox, get_acpibatt, '%1', 30)
608 --bashets.start()
609 -- }}}