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

29b0d62105c585094332de15b5d7d3e8f4f9c50a
[etc/awesome.git] / .config / awesome / rc.lua
1 -- awesome 3 configuration file
2
3 -- Include awesome library, with lots of useful function!
4 require("awful")
5 require("tabulous")
6 require("beautiful")
7
8 -- {{{ Variable definitions
9 -- This is a file path to a theme file which will defines colors.
10 theme_path = "/home/madduck/code/awesome/share/awesome/themes/default"
11
12 -- This is used later as the default terminal to run.
13 terminal = "x-terminal-emulator"
14
15 -- Default modkey.
16 -- Usually, Mod4 is the key with a logo between Control and Alt.
17 -- If you do not like this or do not have such a key,
18 -- I suggest you to remap Mod4 to another key using xmodmap or other tools.
19 -- However, you can use another modifier like Mod1, but it may interact with others.
20 modkey = "Mod4"
21
22 -- Table of layouts to cover with awful.layout.inc, order matters.
23 layouts =
24 {
25     "tile",
26     "tileleft",
27     "tilebottom",
28     "tiletop",
29     "fairh",
30     "fairv",
31     "magnifier",
32     "max",
33 --    "spiral",
34 --    "dwindle",
35     "floating"
36 }
37
38 -- Table of clients that should be set floating. The index may be either
39 -- the application class or instance. The instance is useful when running
40 -- a console app in a terminal like (Music on Console)
41 --    xterm -name mocp -e mocp
42 -- OVERRULED BY TILEDAPPS BELOW
43 floatapps =
44 {
45     -- by class
46     ["MPlayer"] = true,
47     ["pinentry"] = true,
48     ["GIMP"] = true,
49     ["twinkle"] = true,
50     ["Add-ons"] = true,
51     ["Play stream"] = true
52 }
53
54 -- Applications that should never float, assuming everything else floats
55 -- (by instance)
56 tiledapps =
57 {
58     ["urxvt"] = true
59 }
60
61 -- Applications that should be maximised
62 -- (by instance)
63 maxapps =
64 {
65     ["Navigator"] = true,
66     -- jpilot is -v
67     ["-v"] = true,
68     ["Xpdf"] = true
69 }
70
71 -- Applications to be moved to a pre-defined tag by class or instance.
72 -- Use the screen and tags indices.
73 apptags =
74 {
75     ["Navigator"] = { screen = 1, tag = 9 },
76     -- jpilot is -v
77     ["-v"] = { screen = 1, tag = 8 },
78 }
79
80 -- Define if we want to use titlebar on all applications.
81 use_titlebar = false
82 -- }}}
83
84 -- {{{ Initialization
85 -- Initialize theme (colors).
86 beautiful.init(theme_path)
87
88 -- Register theme in awful.
89 -- This allows to not pass plenty of arguments to each function
90 -- to inform it about colors we want it to draw.
91 awful.beautiful.register(beautiful)
92
93 -- Uncomment this to activate autotabbing
94 -- tabulous.autotab_start()
95 -- }}}
96
97 -- {{{ Tags
98 -- Define tags table.
99 tags = {}
100 for s = 1, screen.count() do
101     -- Each screen has its own tag table.
102     tags[s] = {}
103     -- Create 9 tags per screen.
104     for tagnumber = 1, 9 do
105         tags[s][tagnumber] = tag({ name = tagnumber, layout = layouts[6] })
106         -- Add tags to screen one by one
107         -- split at 0.5/50% exactly
108         -- tags[s][tagnumber].mwfact = 0.5
109         tags[s][tagnumber].screen = s
110     end
111     -- I'm sure you want to see at least one tag.
112     tags[s][1].selected = true
113 end
114 -- }}}
115
116 -- {{{ Wibox
117 -- Create a taglist widget
118 mytaglist = widget({ type = "taglist", name = "mytaglist" })
119 mytaglist:buttons({
120     button({ }, 1, function (object, tag) awful.tag.viewonly(tag) end),
121     button({ modkey }, 1, function (object, tag) awful.client.movetotag(tag) end),
122     button({ }, 3, function (object, tag) tag.selected = not tag.selected end),
123     button({ modkey }, 3, function (object, tag) awful.client.toggletag(tag) end),
124     button({ }, 4, awful.tag.viewnext),
125     button({ }, 5, awful.tag.viewprev)
126 })
127 mytaglist.label = awful.widget.taglist.label.all
128
129 -- Create a tasklist widget
130 mytasklist = widget({ type = "tasklist", name = "mytasklist" })
131 mytasklist:buttons({
132     button({ }, 1, function (object, c) client.focus = c; c:raise() end),
133     button({ }, 4, function () awful.client.focus.byidx(1) end),
134     button({ }, 5, function () awful.client.focus.byidx(-1) end)
135 })
136 mytasklist.label = awful.widget.tasklist.label.currenttags
137
138 -- Create a textbox widget
139 mytimebox = widget({ type = "textbox", name = "mytimebox", align = "right" })
140 mybatterybox = widget({ type = "textbox", name = "mybatterybox", align = "right" })
141 mypromptbox = widget({ type = "textbox", name = "mypromptbox", align = "left" })
142
143 -- Create a laucher widget
144 mylauncher = awful.widget.launcher({ name = "mylauncher",
145                                      image = "/home/madduck/code/awesome/share/awesome/icons/awesome16.png",
146                                      command = terminal .. " -e man awesome"})
147
148 -- Create a systray
149 mysystray = widget({ type = "systray", name = "mysystray", align = "right" })
150
151 -- Create an iconbox widget which will contains an icon indicating which layout we're using.
152 -- We need one layoutbox per screen.
153 mylayoutbox = {}
154 for s = 1, screen.count() do
155     mylayoutbox[s] = widget({ type = "imagebox", name = "mylayoutbox", align = "right" })
156     mylayoutbox[s]:buttons({
157         button({ }, 1, function () awful.layout.inc(layouts, 1) end),
158         button({ }, 3, function () awful.layout.inc(layouts, -1) end),
159         button({ }, 4, function () awful.layout.inc(layouts, 1) end),
160         button({ }, 5, function () awful.layout.inc(layouts, -1) end)
161     })
162     mylayoutbox[s].image = image("/home/madduck/code/awesome/share/awesome/icons/layouts/tilew.png")
163 end
164
165 --Battery widget
166 batterywidget = widget({ type = 'progressbar', name = 'batterywidget' })
167 batterywidget.width = 100
168 batterywidget.height = 0.8
169 batterywidget.gap = 1
170 batterywidget.border_padding = 1
171 batterywidget.border_width = 1
172 batterywidget.ticks_count = 10
173 batterywidget.ticks_gap = 1
174 batterywidget.vertical = false
175 batterywidget:bar_properties_set('bat', {
176   bg = 'black',
177   fg = 'blue4',
178   fg_off = 'red',
179   reverse = false,
180   min_value = 0,
181   max_value = 100
182 })
183 -- }}}
184
185 -- Create a wibox for each screen and add it
186 mywibox = {}
187 for s = 1, screen.count() do
188     mywibox[s] = wibox({ position = "top", name = "mywibox" .. s,
189                              fg = beautiful.fg_normal, bg = beautiful.bg_normal })
190     -- Add widgets to the wibox - order matters
191     mywibox[s]:widgets({
192         mytaglist,
193         mytasklist,
194         mypromptbox,
195 --        batterywidget,
196 --        mybatterybox,
197         mytimebox,
198         mylayoutbox[s],
199         s == screen.count() and mysystray or nil
200     })
201     mywibox[s].screen = s
202 end
203 -- }}}
204
205 -- {{{ Mouse bindings
206 awesome.buttons({
207     button({ }, 3, function () awful.util.spawn(terminal) end),
208     button({ }, 4, awful.tag.viewnext),
209     button({ }, 5, awful.tag.viewprev)
210 })
211 -- }}}
212
213 -- {{{ Key bindings
214
215 -- Bind keyboard digits
216 -- Compute the maximum number of digit we need, limited to 9
217 keynumber = 0
218 for s = 1, screen.count() do
219    keynumber = math.min(9, math.max(#tags[s], keynumber));
220 end
221
222 for i = 1, keynumber do
223     keybinding({ modkey }, i,
224                    function ()
225                        local screen = mouse.screen
226                        if tags[screen][i] then
227                            awful.tag.viewonly(tags[screen][i])
228                        end
229                    end):add()
230     keybinding({ modkey, "Control" }, i,
231                    function ()
232                        local screen = mouse.screen
233                        if tags[screen][i] then
234                            tags[screen][i].selected = not tags[screen][i].selected
235                        end
236                    end):add()
237     keybinding({ modkey, "Shift" }, i,
238                    function ()
239                        if client.focus then
240                            if tags[client.focus.screen][i] then
241                                awful.client.movetotag(tags[client.focus.screen][i])
242                            end
243                        end
244                    end):add()
245     keybinding({ modkey, "Control", "Shift" }, i,
246                    function ()
247                        if client.focus then
248                            if tags[client.focus.screen][i] then
249                                awful.client.toggletag(tags[client.focus.screen][i])
250                            end
251                        end
252                    end):add()
253 end
254
255 keybinding({ modkey }, "Left", awful.tag.viewprev):add()
256 keybinding({ modkey }, "Right", awful.tag.viewnext):add()
257 keybinding({ modkey }, "Escape", awful.tag.history.restore):add()
258
259 -- Standard program
260 keybinding({ modkey }, "Return", function () awful.util.spawn(terminal) end):add()
261
262 keybinding({ modkey, "Control" }, "r", function ()
263                                            mypromptbox[mouse.screen].text =
264                                                awful.util.escape(awful.util.restart())
265                                         end):add()
266 keybinding({ modkey, "Shift" }, "q", awesome.quit):add()
267
268 -- Client manipulation
269 keybinding({ modkey }, "m", awful.client.maximize):add()
270 keybinding({ modkey }, "f", function () client.focus.fullscreen = not client.focus.fullscreen end):add()
271 keybinding({ modkey, "Shift" }, "c", function () client.focus:kill() end):add()
272 keybinding({ modkey }, "j", function () awful.client.focus.byidx(1); client.focus:raise() end):add()
273 keybinding({ modkey }, "k", function () awful.client.focus.byidx(-1);  client.focus:raise() end):add()
274 keybinding({ modkey, "Shift" }, "j", function () awful.client.swap(1) end):add()
275 keybinding({ modkey, "Shift" }, "k", function () awful.client.swap(-1) end):add()
276 keybinding({ modkey, "Control" }, "j", function () awful.screen.focus(1) end):add()
277 keybinding({ modkey, "Control" }, "k", function () awful.screen.focus(-1) end):add()
278 keybinding({ modkey, "Control" }, "space", awful.client.togglefloating):add()
279 keybinding({ modkey, "Control" }, "Return", function () client.focus:swap(awful.client.master()) end):add()
280 keybinding({ modkey }, "o", awful.client.movetoscreen):add()
281 keybinding({ modkey }, "Tab", awful.client.focus.history.previous):add()
282 keybinding({ modkey }, "u", awful.client.urgent.jumpto):add()
283 keybinding({ modkey, "Shift" }, "r", function () client.focus:redraw() end):add()
284
285 -- Layout manipulation
286 keybinding({ modkey }, "l", function () awful.tag.incmwfact(0.05) end):add()
287 keybinding({ modkey }, "h", function () awful.tag.incmwfact(-0.05) end):add()
288 keybinding({ modkey, "Shift" }, "h", function () awful.tag.incnmaster(1) end):add()
289 keybinding({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1) end):add()
290 keybinding({ modkey, "Control" }, "h", function () awful.tag.incncol(1) end):add()
291 keybinding({ modkey, "Control" }, "l", function () awful.tag.incncol(-1) end):add()
292 keybinding({ modkey }, "space", function () awful.layout.inc(layouts, 1) end):add()
293 keybinding({ modkey, "Shift" }, "space", function () awful.layout.inc(layouts, -1) end):add()
294
295 -- Prompt
296 keybinding({ modkey }, "F1", function ()
297                                  awful.prompt.run({ prompt = "Run: " }, mypromptbox[mouse.screen], awful.util.spawn, awful.completion.bash,
298 os.getenv("HOME") .. "/.cache/awesome/history") end):add()
299 keybinding({ modkey }, "F4", function ()
300                                  awful.prompt.run({ prompt = "Run Lua code: " }, mypromptbox[mouse.screen], awful.util.eval, awful.prompt.bash,
301 os.getenv("HOME") .. "/.cache/awesome/history_eval") end):add()
302 keybinding({ modkey, "Ctrl" }, "i", function ()
303                                         local s = mouse.screen
304                                         if mypromptbox[s].text then
305                                             mypromptbox[s].text = nil
306                                         else
307                                             mypromptbox[s].text = nil
308                                             if client.focus.class then
309                                                 mypromptbox[s].text = "Class: " .. client.focus.class .. " "
310                                             end
311                                             if client.focus.instance then
312                                                 mypromptbox[s].text = mypromptbox[s].text .. "Instance: ".. client.focus.instance .. " "
313                                             end
314                                             if client.focus.role then
315                                                 mypromptbox[s].text = mypromptbox[s].text .. "Role: ".. client.focus.role
316                                             end
317                                         end
318                                     end):add()
319
320 --- Tabulous, tab manipulation
321 keybinding({ modkey, "Control" }, "y", function ()
322     local tabbedview = tabulous.tabindex_get()
323     local nextclient = awful.client.next(1)
324
325     if not tabbedview then
326         tabbedview = tabulous.tabindex_get(nextclient)
327
328         if not tabbedview then
329             tabbedview = tabulous.tab_create()
330             tabulous.tab(tabbedview, nextclient)
331         else
332             tabulous.tab(tabbedview, client.focus)
333         end
334     else
335         tabulous.tab(tabbedview, nextclient)
336     end
337 end):add()
338
339 keybinding({ modkey, "Shift" }, "y", tabulous.untab):add()
340
341 keybinding({ modkey }, "y", function ()
342    local tabbedview = tabulous.tabindex_get()
343
344    if tabbedview then
345        local n = tabulous.next(tabbedview)
346        tabulous.display(tabbedview, n)
347    end
348 end):add()
349
350 -- Client awful tagging: this is useful to tag some clients and then do stuff like move to tag on them
351 keybinding({ modkey }, "t", awful.client.togglemarked):add()
352 keybinding({ modkey, 'Shift' }, "t", function ()
353     local tabbedview = tabulous.tabindex_get()
354     local clients = awful.client.getmarked()
355
356     if not tabbedview then
357         tabbedview = tabulous.tab_create(clients[1])
358         table.remove(clients, 1)
359     end
360
361     for k,c in pairs(clients) do
362         tabulous.tab(tabbedview, c)
363     end
364
365 end):add()
366
367 for i = 1, keynumber do
368     keybinding({ modkey, "Shift" }, "F" .. i,
369                    function ()
370                        local screen = mouse.screen
371                        if tags[screen][i] then
372                            for k, c in pairs(awful.client.getmarked()) do
373                                awful.client.movetotag(tags[screen][i], c)
374                            end
375                        end
376                    end):add()
377 end
378 -- }}}
379
380 -- {{{ Hooks
381 -- Hook function to execute when focusing a client.
382 awful.hooks.focus.register(function (c)
383     if not awful.client.ismarked(c) then
384         c.border_color = beautiful.border_focus
385     end
386 end)
387
388 -- Hook function to execute when unfocusing a client.
389 awful.hooks.unfocus.register(function (c)
390     if not awful.client.ismarked(c) then
391         c.border_color = beautiful.border_normal
392     end
393 end)
394
395 -- Hook function to execute when marking a client
396 awful.hooks.marked.register(function (c)
397     c.border_color = beautiful.border_marked
398 end)
399
400 -- Hook function to execute when unmarking a client
401 awful.hooks.unmarked.register(function (c)
402     c.border_color = beautiful.border_focus
403 end)
404
405 -- Hook function to execute when the mouse is over a client.
406 awful.hooks.mouse_enter.register(function (c)
407     -- Sloppy focus, but disabled for magnifier layout
408     if awful.layout.get(c.screen) ~= "magnifier"
409         and awful.client.focus.filter(c) then
410         client.focus = c
411     end
412 end)
413
414 -- Hook function to execute when a new client appears.
415 awful.hooks.manage.register(function (c)
416     if use_titlebar then
417         -- Add a titlebar
418         awful.titlebar.add(c, { modkey = modkey })
419     end
420     -- Add mouse bindings
421     c:buttons({
422         button({ }, 1, function (c) client.focus = c; c:raise() end),
423         button({ modkey }, 1, function (c) c:mouse_move() end),
424         button({ modkey }, 3, function (c) c:mouse_resize() end)
425     })
426     -- New client may not receive focus
427     -- if they're not focusable, so set border anyway.
428     c.border_width = beautiful.border_width
429     c.border_color = beautiful.border_normal
430     client.focus = c
431
432     -- Check if the application should be floating.
433     -- OVERRIDDEN, SEE tiledapps BELOW
434     local cls = c.class
435     local inst = c.instance
436     if floatapps[cls] then
437         c.floating = floatapps[cls]
438     elseif floatapps[inst] then
439         c.floating = floatapps[inst]
440     end
441
442     -- Override with tiledapps
443     c.floating = not (tiledapps[inst] or tiledapps[cls])
444
445     -- Check application->screen/tag mappings.
446     local target
447     if apptags[cls] then
448         target = apptags[cls]
449     elseif apptags[inst] then
450         target = apptags[inst]
451     end
452     if target then
453         c.screen = target.screen
454         awful.client.movetotag(tags[target.screen][target.tag], c)
455     end
456
457     -- Set the windows at the slave,
458     -- i.e. put it at the end of others instead of setting it master.
459     -- awful.client.setslave(c)
460
461     -- Honor size hints: if you want to drop the gaps between windows, set this to false.
462     c.honorsizehints = true
463
464     -- Maximise some
465     if maxapps[inst] or maxapps[cls] then
466       awful.client.maximize(c)
467     end
468 end)
469
470 -- Hook function to execute when arranging the screen
471 -- (tag switch, new client, etc)
472 awful.hooks.arrange.register(function (screen)
473     local layout = awful.layout.get(screen)
474     if layout then
475         mylayoutbox[screen].image = image("/home/madduck/code/awesome/share/awesome/icons/layouts/" .. layout .. "w.png")
476     else
477         mylayoutbox[screen].image = nil
478     end
479
480     -- Give focus to the latest client in history if no window has focus
481     -- or if the current window is a desktop or a dock one.
482     if not client.focus then
483         local c = awful.client.focus.history.get(screen, 0)
484         if c then client.focus = c end
485     end
486
487     -- Uncomment if you want mouse warping
488     --[[
489     if client.focus then
490         local c_c = client.focus:coords()
491         local m_c = mouse.coords()
492
493         if m_c.x < c_c.x or m_c.x >= c_c.x + c_c.width or
494             m_c.y < c_c.y or m_c.y >= c_c.y + c_c.height then
495             if table.maxn(m_c.buttons) == 0 then
496                 mouse.coords({ x = c_c.x + 5, y = c_c.y + 5})
497             end
498         end
499     end
500     ]]
501 end)
502
503 -- Hook called every second
504 awful.hooks.timer.register(1, function ()
505     -- For unix time_t lovers
506     -- mytextbox.text = " " .. os.time() .. " time_t "
507     -- Otherwise use:
508     mytimebox.text = " " .. os.date() .. " "
509 end)
510
511 -- Hook called every sixty seconds
512 function hook_battery()
513     mybatterybox.text = " " .. get_acpibatt() .. " "
514 end
515
516 -- {{{ Statusbar battery
517 --
518 function get_acpibatt()
519
520     local f = io.popen('acpi -b', 'r')
521     if not f then
522       return "acpi -b failed"
523     end
524
525     local s = f:read('*l')
526     f:close()
527     if not s then
528       return '-';
529     end
530
531     -- Battery 0: Discharging, 89%, 00:02:14 remaining
532     -- Battery 0: Charging, 58%, 00:02:14 until charged
533     -- Battery 0: Full, 100%
534     -- so find the first bit first and then go look for the time
535     local st, en, status, percent = string.find(s, '%a+%s%d:%s(%a+),%s(%d+%%)');
536     local st, en, time = string.find(s, ',%s(%d+:%d+:%d+)%s%a+', en);
537
538     if not status or not percent then -- time can be empty if we're full
539       return "couldn't parse line " .. s
540     end
541
542     if not time then
543       return percent
544     end
545
546     if status == 'Charging' then
547       status = 'c';
548     elseif status == 'Discarching' then
549       status = 'd';
550     else
551       status = '-';
552     end
553
554     return percent; -- .. ' (' .. status .. ')'; -- .. ' ' .. time .. ' left';
555 end
556 -- }}}
557
558 --{{{ batt hook
559 local function get_bat()
560   local a = io.open("/sys/class/power_supply/BAT1/charge_full")
561   for line in a:lines() do
562     full = line
563   end
564   a:close()
565   local b = io.open("/sys/class/power_supply/BAT1/charge_now")
566   for line in b:lines() do
567     now = line
568   end
569   b:close()
570   batt=math.floor(now*100/full)
571   batterywidget:bar_data_add("bat",batt )
572 end
573 --}}}
574
575 -- Set up some hooks
576 awful.hooks.timer.register(120, hook_battery)
577 -- awful.hooks.timer.register(5, get_bat)
578 -- }}}
579
580 cmdmodkey = "Mod3"
581
582 -- xmms2 & sound
583 keybinding({ cmdmodkey }, "Prior", function () awful.util.spawn("amixer set Master 2+") end):add()
584 keybinding({ cmdmodkey }, "Next", function () awful.util.spawn("amixer set Master 2-") end):add()
585 keybinding({ cmdmodkey }, "Up", function () awful.util.spawn("amixer set PCM 2+") end):add()
586 keybinding({ cmdmodkey }, "Down", function () awful.util.spawn("amixer set PCM 2-") end):add()
587 keybinding({ cmdmodkey }, "Home", function () awful.util.spawn("amixer set Mic toggle") end):add()
588 keybinding({ cmdmodkey }, "End", function () awful.util.spawn("amixer set Master toggle") end):add()
589 keybinding({ cmdmodkey }, "Left", function () awful.util.spawn("xmms2 prev") end):add()
590 keybinding({ cmdmodkey }, "Right", function () awful.util.spawn("xmms2 next") end):add()
591 keybinding({ cmdmodkey }, "space", function () awful.util.spawn("xmms2 toggleplay") end):add()
592 keybinding({ cmdmodkey }, "backslash", function () awful.util.spawn("xmms2 current | head -1 | xmessage -nearmouse -timeout 5 -file -") end):add()
593 keybinding({ cmdmodkey, "Shift" }, "backslash", function () awful.util.spawn("xmms2 list | xmessage -nearmouse -timeout 5 -file -") end):add()
594
595 -- misc apps
596 keybinding({ cmdmodkey }, "n", function () awful.util.spawn("sensible-browser") end):add()
597 keybinding({ cmdmodkey }, "m", function () awful.util.spawn(terminal .. " -e mutt -f =store") end):add()
598 keybinding({ cmdmodkey }, "t", function () awful.util.spawn(terminal) end):add()
599 keybinding({ cmdmodkey }, "c", function () awful.util.spawn(terminal .. " -e python") end):add()
600 keybinding({ cmdmodkey }, "r", function () awful.util.spawn("gmrun") end):add()
601 keybinding({ cmdmodkey }, "j", function () awful.util.spawn("jpilot") end):add()
602 keybinding({ cmdmodkey }, "x", function () awful.util.spawn("/sbin/start-stop-daemon --start --background --exec /usr/bin/xscreensaver; xscreensaver-command -lock") end):add()
603 keybinding({ cmdmodkey, "Shift" }, "x", function () awful.util.spawn("xscreensaver-command -exit") end):add()
604
605 -- Highlight statusbars on the screen that has focus, 
606 -- set this to false if you only have one screen or 
607 -- you don't like it :P
608 if screen.count() > 1 then
609   statusbar_highlight_focus = true
610 else
611   statusbar_highlight_focus = false
612 end
613
614 hook_battery()