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

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