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

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