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