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:

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