qdb: finish getting rid of eminent
[~madcoder/dotfiles.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("awful.autofocus")
6 require("awful.rules")
7 require("vicious")
8 require("beautiful")
9
10 terminal = "x-terminal-emulator"
11 lock     = 'xscreensaver-command -lock'
12 beautiful.init(awful.util.getdir("config").."/theme")
13
14 -- {{{ Modkeys
15 modkey = "Mod4"
16 shift = "Shift"
17 alt = "Mod1"
18 control = "Control"
19
20 k_n   = {}
21 k_m   = {modkey}
22 k_ms  = {modkey, shift}
23 k_ma  = {modkey, alt}
24 k_mc  = {modkey, control}
25 k_mcs = {modkey, control, shift}
26 k_a   = {alt}
27 k_ac  = {alt, control}
28 k_c   = {control}
29 k_cs  = {control, shift}
30 k_s   = {shift}
31
32 -- }}}
33 -- {{{ Markup helper functions
34 -- Inline markup is a tad ugly, so use these functions
35 -- to dynamically create markup.
36 function fg(color, text)
37     return '<span color="'..color..'">'..text..'</span>'
38 end
39
40 function heading(text)
41     return fg(beautiful.fg_focus, text)
42 end
43
44 -- }}}
45
46 -- {{{ Tags
47
48 tags = {}
49 for s = 1, screen.count() do
50     -- Each screen has its own tag table.
51     local p = {}
52     for i = 1, 10 do
53         table.insert(p, "work-"..i)
54     end
55     tags[s] = awful.tag(p, s, awful.layout.suit.tile)
56 end
57
58 -- Get the screen number we're on
59 function getscreen()
60     local sel = client.focus
61     return (sel and sel.screen) or mouse.screen
62 end
63
64 local mtag = { }
65 function mtag.getn(idx, s)
66     return tags[s or getscreen()][idx]
67 end
68 function mtag.viewonly (idx, s)
69     local t = mtag.getn(idx, s)
70     if t then awful.tag.viewonly(t) end
71 end
72 function mtag.viewtoggle (idx, s)
73     local t = mtag.getn(idx, s)
74     if t then awful.tag.viewtoggle(t) end
75 end
76 function mtag.isoccupied(s, t)
77     local clients = (t and t:clients()) or {}
78     return #clients > 0
79 end
80 function mtag.occupied(s)
81     local p = {}
82
83     if not s then s = getscreen() end
84     for t in pairs(tags[s]) do
85         t = tags[s][t]
86         if mtag.isoccupied(s, t) then table.insert(p, t) end
87     end
88     return p
89 end
90 function mtag.getnext(s)
91     if s == nil then s = getscreen() end
92
93     local p = mtag.occupied(s)
94     local curtag = awful.tag.selected()
95
96     local t = 0
97
98     -- Get tag #
99     if mtag.isoccupied(s, curtag) then
100         for x in pairs(p) do
101             if curtag == p[x] then t = x end
102         end
103     end
104
105     local lasto = 1
106     local o = 0
107
108     for x in pairs(tags[s]) do
109         if curtag == tags[s][x] then o = x end
110         if mtag.isoccupied(s, tags[s][x]) then lasto = x end
111     end
112
113     -- Now: t is # in non-empty, o is # in all
114     if o == table.maxn(tags[s]) then
115         -- We're the last tag, create a new one
116         if t == 0 then
117             -- We're empty, go to first
118             return tags[s][1]
119         else
120             -- We're occupied, create new
121             return newtag()
122         end
123     else
124         if t == 0 then
125             -- We're empty, check if we're last
126             if o > lasto then
127                 -- We're also later than the last non-empty
128                 -- Wrap to first
129                 return tags[s][1]
130             else
131                 -- Nevermind, get the next
132                 return tags[s][o+1]
133             end
134         else
135             -- Return next tag
136             return tags[s][o+1]
137         end
138     end
139 end
140 function mtag.next(s)
141     awful.tag.viewonly(mtag.getnext(s))
142 end
143 function mtag.movetonext(s)
144     local t = mtag.getnext(s)
145     awful.client.movetotag(t)
146     awful.tag.viewonly(t)
147 end
148 function mtag.getprev(s)
149     if s == nil then s = getscreen() end
150
151     local p = mtag.occupied(s)
152     local curtag = awful.tag.selected()
153
154     local t = 0
155
156     -- Get tag #
157     if mtag.isoccupied(s, curtag) then
158         for x in pairs(p) do
159             if curtag == p[x] then t = x end
160         end
161     end
162
163     local lasto = 1
164     local o = 0
165
166     for x in pairs(tags[s]) do
167         if curtag == tags[s][x] then o = x end
168         if mtag.isoccupied(s, tags[s][x]) then lasto = x end
169     end
170
171     -- Now: t is # in non-empty, o is # in all
172     if o == 1 then
173         -- We're the very first tag, wrap around
174         return p[ table.maxn(p) ]
175     else
176         -- We're not first, just go prev
177         return tags[s][o-1]
178     end
179 end
180 function mtag.prev(s)
181     awful.tag.viewonly(mtag.getprev(s))
182 end
183 function mtag.movetoprev(s)
184     local t = mtag.getprev(s)
185     awful.client.movetotag(t)
186     awful.tag.viewonly(t)
187 end
188
189
190 -- }}}
191 -- {{{ Widgets
192
193 -- {{{ Taglist
194
195 maintaglist = {}
196 maintaglist.buttons = awful.util.table.join(
197     awful.button(k_n, 1, awful.tag.viewonly),
198     awful.button(k_s, 1, awful.client.toggletag)
199 )
200
201 -- }}}
202 -- {{{ Load Average Widget
203
204 loadwidget = widget({ type = 'textbox' })
205 load_update = function()
206     -- Use /proc/loadavg to get the average system load on 1, 5 and 15 minute intervals
207     local f = io.open('/proc/loadavg')
208     local n = f:read()
209     f:close()
210
211     -- Find the third space
212     local pos = n:find(' ', n:find(' ', n:find(' ')+1)+1)
213
214     loadwidget.text = heading('Load')..': '..n:sub(1,pos-1)
215 end
216 load_update()
217
218 t = timer { timeout = 10 }
219 t:add_signal("timeout", load_update)
220 t:start()
221
222 -- }}}
223 -- {{{ CPU Usage Widget
224
225 cputextwidget = widget({ type = 'textbox' })
226 cpugraphwidget = awful.widget.graph{
227     width  = 40, height = 16,
228     layout = awful.widget.layout.horizontal.rightleft
229 }
230 cpugraphwidget:set_background_color('#333333')
231 cpugraphwidget:set_border_color('#0a0a0a')
232 cpugraphwidget:set_gradient_colors({ '#285577', '#285577', '#AEC6D8' })
233
234 vicious.register(cputextwidget, vicious.widgets.cpu,
235 function (widget, args)
236     local r = tonumber(args[1])
237     local percent = args[1]..'%'
238     if r < 10 then
239         percent = '0'..percent
240     end
241     if r < 25 then
242         percent = fg('green', percent)
243     elseif r < 50 then
244         percent = fg('yellow', percent)
245     elseif r < 75 then
246         percent = fg('orange', percent)
247     else
248         percent = fg('red', percent)
249     end
250     -- cpugraphwidget:add_value(r / 100)
251     return heading('CPU')..': '..percent..' '
252 end, 2)
253
254 -- }}}
255 -- {{{ CPU Graph Widget
256
257 -- }}}
258 -- {{{ Memory Usage Widget
259
260 memtextwidget = widget({ type = 'textbox' })
261
262 memtextwidget.text = heading('MEM')..': '
263 vicious.register(memtextwidget, vicious.widgets.mem, function (widget, args)
264     -- Add extra preceding zeroes when needed
265     local r = tonumber(args[1])
266     local percent = args[1]..'%'
267     if r < 10 then
268         percent = '0'..percent
269     end
270     if r < 50 then
271         percent = fg('green', percent)
272     elseif r < 80 then
273         percent = fg('orange', percent)
274     else
275         percent = fg('red', percent)
276     end
277     return heading('MEM')..': '..percent..' '..args[2]..'M'
278 end, 2)
279
280 -- }}}
281 -- {{{ spacers
282
283 rspacer = widget({ type = 'textbox' })
284 rspacer.text = " │ "
285
286 -- }}}
287 -- {{{ Clock
288
289 clockwidget = widget({ type = "textbox" })
290 vicious.register(clockwidget, vicious.widgets.date, fg("#dddddd", "%a %d %b - %H:%M"), 10)
291
292 -- }}}
293
294 mymenubox = widget{ type = "textbox" }
295
296 -- {{{ Statusbar
297
298 mainstatusbar = {}
299 mysystray = widget({ type = "systray" })
300
301 for s = 1, screen.count() do
302     mainstatusbar[s] = awful.wibox{ position = "top", height = 18, screen = s }
303
304     mainstatusbar[s].widgets = {
305         {
306             awful.widget.taglist(s, awful.widget.taglist.label.noempty, maintaglist.buttons),
307             maintaglist,
308             awful.widget.prompt({ layout = awful.widget.layout.horizontal.leftright }),
309             layout = awful.widget.layout.horizontal.leftright
310         },
311         s == 1 and mysystray or nil,
312         s == 1 and rspacer or nil,
313         clockwidget, rspacer,
314         memtextwidget, rspacer,
315         cpugraphwidget, cputextwidget, rspacer,
316         loadwidget, rspacer,
317         layout = awful.widget.layout.horizontal.rightleft
318     }
319 end
320
321 -- }}}
322 -- }}}
323 -- {{{ Keys
324 ---- {{{ Global keys
325
326 local hist = os.getenv("HOME") .. "/.cache/awesome/history"
327 globalkeys = awful.util.table.join(
328     -- Mod+{A/S}: Switch to prev/next tag
329     awful.key(k_m, "Left",  mtag.prev),
330     awful.key(k_m, "Right", mtag.next),
331
332     -- Mod+Shift+{A/S}: Move window to Prev/Next tag
333     awful.key(k_ms, "Left",  mtag.movetoprev),
334     awful.key(k_ms, "Right", mtag.movetonext),
335
336     -- Mod+Shift_{E/D}: move window to next/prev screen
337     awful.key(k_mc, "Right", function()
338        local s = getscreen() + 1
339        while s > screen.count() do s = s - screen.count() end
340        client.focus.screen = s
341     end),
342     awful.key(k_mc, "Left", function()
343        local s = getscreen() - 1
344        while s < 1 do s = s + screen.count() end
345        client.focus.screen = s
346     end),
347
348
349     -- Focus Prev/Next window
350     awful.key(k_m, "j",
351         function ()
352             awful.client.focus.byidx(1)
353             if client.focus then client.focus:raise() end
354         end),
355     awful.key(k_m, "k",
356         function ()
357             awful.client.focus.byidx(-1)
358             if client.focus then client.focus:raise() end
359         end),
360
361     -- Swap window with the Prev/Next one
362     awful.key(k_ms, "j", function () awful.client.swap.byidx(1) end),
363     awful.key(k_ms, "k", function () awful.client.swap.byidx(-1) end),
364
365     -- Mod+{E/D}: Switch to next/previous screen
366     awful.key(k_m, "Tab",  function () awful.screen.focus_relative(1) end),
367     awful.key(k_ms, "Tab", function () awful.screen.focus_relative(-1) end),
368
369     -- Mod+Enter: Launch a new terminal
370     awful.key(k_m,  "e",      function() awful.util.spawn("firefox") end),
371     awful.key(k_m,  "Return", function() awful.util.spawn(terminal) end),
372     awful.key(k_ac, "r", awesome.restart),
373     awful.key(k_m, "F12", function() awful.util.spawn(lock) end),
374     awful.key({}, "#148", function() awful.util.spawn("kcalc") end),
375
376     -- Layout manipulation
377     awful.key(k_m,  "l", function () awful.tag.incmwfact(0.05) end),
378     awful.key(k_m,  "h", function () awful.tag.incmwfact(-0.05) end),
379     awful.key(k_ms, "h", function () awful.tag.incnmaster(1) end),
380     awful.key(k_ms, "l", function () awful.tag.incnmaster(-1) end),
381     awful.key(k_mc, "h", function () awful.tag.incncol(1) end),
382     awful.key(k_mc, "l", function () awful.tag.incncol(-1) end),
383
384     -- Menu
385     awful.key(k_m, "r",
386         function ()
387             awful.prompt.run({ prompt = "Run: " },
388                              mymenubox,
389                              awful.util.spawn,
390                              awful.completion.shell,
391                              awful.util.getdir("cache").."/commands")
392         end),
393     awful.key(k_m, "F4",
394         function ()
395             awful.prompt.run({ prompt = "Run Lua code: " },
396                              mymenubox,
397                              awful.util.eval,
398                              awful.prompt.shell,
399                              awful.util.getdir("cache").."/lua_commands")
400     end),
401
402     awful.key({}, "#192", function() mtag.viewonly(1) end),
403     awful.key({}, "#193", function() mtag.viewonly(2) end),
404     awful.key({}, "#194", function() mtag.viewonly(3) end),
405     awful.key({}, "#195", function() mtag.viewonly(4) end),
406     awful.key({}, "#196", function() mtag.viewonly(5) end)
407 )
408
409 -- Mod+#: Switch to tag
410 -- Mod+Shift+#: Toggle tag display
411 -- Mod+Control+#: Move client to tag
412 -- Mod+Alt+#: Toggle client on tag
413
414 for i = 1, 10 do
415     globalkeys = awful.util.table.join(
416         globalkeys,
417         awful.key(k_m,  i % 10, function() mtag.viewonly(i)   end),
418         awful.key(k_ms, i % 10, function() mtag.viewtoggle(i) end),
419         awful.key(k_mc, i % 10,
420                   function ()
421                       if client.focus and tags[client.focus.screen][i] then
422                           awful.client.movetotag(tags[client.focus.screen][i])
423                       end
424                   end),
425         awful.key(k_mcs, i % 10,
426                   function ()
427                       if client.focus and tags[client.focus.screen][i] then
428                           awful.client.toggletag(tags[client.focus.screen][i])
429                       end
430                   end)
431     )
432 end
433
434 ---- }}}
435 ---- {{{ Client hotkeys / buttons
436
437 local clientkeys = awful.util.table.join(
438     awful.key(k_m, "i", function (c)
439         if mymenubox.text then
440             mymenubox.text = ""
441         else
442             mymenubox.text = "Class: " .. c.class .. " Instance: ".. c.instance
443         end
444     end),
445
446     -- Client manipulation
447     awful.key(k_m, "c", function (c) c:kill() end),
448     awful.key(k_m, "o", awful.client.floating.toggle),
449     awful.key(k_m, "F11", function (c) c.fullscreen = not c.fullscreen end)
450 )
451
452 local clientbuttons = awful.util.table.join(
453     awful.button({ }, 1, function (c) client.focus = c; c:raise() end),
454     awful.button(k_a, 1, awful.mouse.client.move),
455     awful.button(k_a, 3, awful.mouse.client.resize)
456 )
457
458 ---- }}}
459
460 root.keys(globalkeys)
461 -- }}}
462 -- {{{ Rules
463
464 awful.rules.rules = {
465     -- All clients will match this rule.
466     {
467         rule = { },
468         properties = {
469             border_width = beautiful.border_width,
470             border_color = beautiful.border_normal,
471             focus   = true,
472             keys    = clientkeys,
473             buttons = clientbuttons,
474             size_hints_honor = false,
475         }
476     },
477     { rule = { class = "MPlayer" },  properties = { floating = true } },
478     { rule = { class = "pinentry" }, properties = { floating = true } },
479     -- Set Firefox to always map on tags number 2 of screen 1.
480     -- { rule = { class = "Firefox" },
481     --   properties = { tag = tags[1][2] } },
482 }
483
484 -- }}}
485 -- {{{ Signals
486
487 client.add_signal("focus", function (c)
488     if not awful.client.ismarked(c) then
489         c.border_color = beautiful.border_focus
490     end
491 end)
492
493 client.add_signal("unfocus", function (c)
494     if not awful.client.ismarked(c) then
495         c.border_color = beautiful.border_normal
496     end
497 end)
498
499 client.add_signal("manage", function (c, startup)
500     -- Enable sloppy focus
501     c:add_signal("mouse::enter", function(c)
502         client.focus = c
503     end)
504
505     -- Focus new clients
506     client.focus = c
507 end)
508
509 function warp_mouse(screen)
510     local c = client.focus
511
512     if c then
513         local o = awful.mouse.client_under_pointer()
514         if not o or o ~= c then
515             local g = c:geometry()
516             mouse.coords { x = g.x + 5, y = g.y + 5 }
517         end
518     end
519 end
520
521 for s = 1, screen.count() do
522     -- screen[s]:add_signal("arrange", warp_mouse)
523 end
524
525 -- }}}
526
527 awful.util.spawn("xkbcomp -w 0 -R/usr/share/X11/xkb /home/madcoder/.Xkeyboard :0")