d79b75d9d8a58ae4a5230ee79419c0a51150d446
[~madcoder/dotfiles.git] / rc.lua
1 -- awesome 3 configuration file
2
3 -- Include awesome library, with lots of useful function!
4 require("awful")
5 require("eminent")
6 require("wicked")
7 require("beautiful")
8
9 terminal = "x-terminal-emulator"
10 lock     = 'xscreensaver-command -lock'
11 beautiful.init(awful.util.getdir("config").."/theme")
12
13 -- {{{ Modkeys
14 modkey = "Mod4"
15 shift = "Shift"
16 alt = "Mod1"
17 control = "Control"
18
19 k_n  = {}
20 k_m  = {modkey}
21 k_ms = {modkey, shift}
22 k_ma = {modkey, alt}
23 k_mc = {modkey, control}
24 k_a  = {alt}
25 k_ac = {alt, control}
26 k_c  = {control}
27 k_cs = {control, shift}
28 k_s  = {shift}
29
30 -- }}}
31
32 -- {{{ Markup helper functions
33 -- Inline markup is a tad ugly, so use these functions
34 -- to dynamically create markup.
35 function fg(color, text)
36     return '<span color="'..color..'">'..text..'</span>'
37 end
38
39 function heading(text)
40     return fg(beautiful.fg_focus, text)
41 end
42
43 -- }}}
44 -- {{{ Functions
45 -- Toggle whether we're viewing a tag
46 function tag_toggleview(tag)
47     tag:view(not tag:isselected())
48 end
49
50 -- Get the screen number we're on
51 function getscreen()
52     local sel = client.focus
53     return (sel and sel.screen) or mouse.screen
54 end
55
56 -- Move current client to a specific screen
57 function client_movetoscreen(i)
58     client.focus.screen = i
59 end
60
61 -- }}}
62 -- {{{ Set tag names
63
64 for s = 1, screen.count() do
65     eminent.newtag(s, 5)
66     for i = 1, 10 do
67         eminent.tag.name(i, s, 'work-'..i)
68     end
69 end
70
71 -- }}}
72 -- {{{ Taglist
73
74 maintaglist = {}
75 maintaglist.buttons = awful.util.table.join(
76     awful.button(k_n, 1, awful.tag.viewonly),
77     awful.button(k_s, 1, awful.client.toggletag)
78 )
79
80 -- }}}
81 -- {{{ Widgets
82
83 -- {{{ Load Averages Widget
84
85 loadwidget = widget({
86     type = 'textbox',
87     name = 'gpuwidget',
88     align = 'right'
89 })
90
91 wicked.register(loadwidget, 'function', function (widget, args)
92     -- Use /proc/loadavg to get the average system load on 1, 5 and 15 minute intervals
93     local f = io.open('/proc/loadavg')
94     local n = f:read()
95     f:close()
96
97     -- Find the third space
98     local pos = n:find(' ', n:find(' ', n:find(' ')+1)+1)
99
100     return heading('Load')..': '..n:sub(1,pos-1)
101
102 end, 2)
103
104 -- }}}
105 -- {{{ CPU Usage Widget
106
107 cputextwidget = widget({
108     type = 'textbox',
109     name = 'cputextwidget',
110     align = 'right'
111 })
112
113 cputextwidget.text = heading('CPU')..': 00% '
114 wicked.register(cputextwidget, 'cpu', function (widget, args)
115     local r = tonumber(args[1])
116     local percent = args[1]..'%'
117     if r < 10 then
118         percent = '0'..percent
119     end
120     if r < 25 then
121         percent = fg('green', percent)
122     elseif r < 50 then
123         percent = fg('yellow', percent)
124     elseif r < 75 then
125         percent = fg('orange', percent)
126     else
127         percent = fg('red', percent)
128     end
129     return heading('CPU')..': '..percent..' '
130 end, 2)
131
132 -- }}}
133 -- {{{ CPU Graph Widget
134
135 cpugraphwidget = widget({
136     type = 'graph',
137     name = 'cpugraphwidget',
138     align = 'right'
139 })
140
141 cpugraphwidget.height = 0.85
142 cpugraphwidget.width = 45
143 cpugraphwidget.bg = '#333333'
144 cpugraphwidget.border_color = '#0a0a0a'
145 cpugraphwidget.grow = 'right'
146
147 cpugraphwidget:plot_properties_set('cpu', {
148     fg = '#AEC6D8',
149     fg_center = '#285577',
150     fg_end = '#285577',
151     vertical_gradient = false
152 })
153
154 wicked.register(cpugraphwidget, 'cpu', '$1', 2, 'cpu')
155
156 -- }}}
157 -- {{{ Memory Usage Widget
158
159 memtextwidget = widget({
160     type = 'textbox',
161     name = 'memtextwidget',
162     align = 'right'
163 })
164
165 memtextwidget.text = heading('MEM')..': '
166 wicked.register(memtextwidget, 'mem', function (widget, args)
167     -- Add extra preceding zeroes when needed
168     local r = tonumber(args[1])
169     local percent = args[1]..'%'
170     if r < 10 then
171         percent = '0'..percent
172     end
173     if r < 50 then
174         percent = fg('green', percent)
175     elseif r < 80 then
176         percent = fg('orange', percent)
177     else
178         percent = fg('red', percent)
179     end
180     return heading('MEM')..': '..percent..' '..args[2]..'M'
181 end, 2)
182
183 -- }}}
184 -- {{{ Battery widget
185 --[[
186 batterywidget = widget({
187     type = 'textbox',
188     name = 'batterywidget',
189     align = 'right'
190 })
191
192 function batterywidget_update()
193     local v = io.popen("powersave -b|sed -ne 's/.*Remaining percent: \\(.*\\)/\\1/p'"):read()
194     local r = tonumber(v)
195
196     percent = v
197     if r < 10 then
198         percent = fg('red', percent)
199     elseif r < 25 then
200         percent = fg('orange', percent)
201     else
202         percent = fg('green', percent)
203     end
204     batterywidget.text = heading('BAT')..': '..percent
205 end
206 batterywidget_update()
207 awful.hooks.timer.register(30, batterywidget_update)
208 --]]
209 -- }}}
210 -- {{{ spacers
211
212 rspacer = widget({ type = 'textbox', name = 'rspacer', align = 'right' })
213 rspacer.text = " │ "
214
215 -- }}}
216 -- {{{ Clock
217 clockwidget = widget({ type = "textbox", name = "clockwidget", align = "right" })
218 clock_update = function()
219     clockwidget.text = fg("#dddddd", os.date("%a %d %b - %H:%M"))
220 end
221 clock_update()
222 awful.hooks.timer.register(10, clock_update)
223
224 -- }}}
225
226 mymenubox = widget{ type = "textbox", name = "mytextbox", align = "left" }
227
228 -- {{{ Statusbar
229
230 mainstatusbar = {}
231
232 for s = 1, screen.count() do
233     mainstatusbar[s] = wibox{
234         position = "top",
235         height = 18,
236         name = "mainstatusbar" .. s,
237     }
238
239     mainstatusbar[s].widgets = {
240         awful.widget.taglist.new(s, awful.widget.taglist.label.noempty, maintaglist.buttons),
241         maintaglist,
242         mymenubox,
243
244         rspacer, loadwidget,
245         rspacer, cputextwidget, cpugraphwidget,
246         rspacer, memtextwidget,
247         rspacer, clockwidget,
248     }
249     mainstatusbar[s].screen = s
250 end
251
252 -- }}}
253 -- }}}
254
255 -- {{{ Keys
256 ---- {{{ Global keys
257
258 local hist = os.getenv("HOME") .. "/.cache/awesome/history"
259 globalkeys = awful.util.table.join(
260     -- Mod+{A/S}: Switch to prev/next tag
261     awful.key(k_m, "Left",  eminent.tag.prev),
262     awful.key(k_m, "Right", eminent.tag.next),
263
264     -- Mod+Shift+{A/S}: Move window to Prev/Next tag
265     awful.key(k_ms, "Left", function()
266         awful.client.movetotag(eminent.tag.getprev())
267         eminent.tag.prev()
268     end),
269     awful.key(k_ms, "Right", function()
270         awful.client.movetotag(eminent.tag.getnext())
271         eminent.tag.next()
272     end),
273
274     -- Mod+Shift_{E/D}: move window to next/prev screen
275     awful.key(k_mc, "Right", function()
276        local s = getscreen() + 1
277        while s > screen.count() do
278            s = s-screen.count()
279        end
280        client_movetoscreen(s)
281     end),
282     awful.key(k_mc, "Left", function()
283        local s = getscreen() - 1
284        while s < 1 do
285            s = s+screen.count()
286        end
287        client_movetoscreen(s)
288     end),
289
290
291     -- Focus Prev/Next window
292     awful.key(k_m, "j",
293         function ()
294             awful.client.focus.byidx(1)
295             if client.focus then client.focus:raise() end
296         end),
297     awful.key(k_m, "k",
298         function ()
299             awful.client.focus.byidx(-1)
300             if client.focus then client.focus:raise() end
301         end),
302
303     -- Swap window with the Prev/Next one
304     awful.key(k_ms, "j", function () awful.client.swap.byidx(1) end),
305     awful.key(k_ms, "k", function () awful.client.swap.byidx(-1) end),
306
307     -- Mod+{E/D}: Switch to next/previous screen
308     awful.key(k_m, "Tab",  function () awful.screen.focus(1) end),
309     awful.key(k_ms, "Tab", function () awful.screen.focus(-1) end),
310
311     -- Mod+Enter: Launch a new terminal
312     awful.key(k_m,  "e",      function() awful.util.spawn("firefox") end),
313     awful.key(k_m,  "Return", function() awful.util.spawn(terminal) end),
314     awful.key(k_ac, "r", awesome.restart),
315     awful.key(k_m, "F12", function() awful.util.spawn(lock) end),
316     awful.key({}, "#148", function() awful.util.spawn("kcalc") end),
317
318     -- Layout manipulation
319     awful.key(k_m,  "l", function () awful.tag.incmwfact(0.05) end),
320     awful.key(k_m,  "h", function () awful.tag.incmwfact(-0.05) end),
321     awful.key(k_ms, "h", function () awful.tag.incnmaster(1) end),
322     awful.key(k_ms, "l", function () awful.tag.incnmaster(-1) end),
323     awful.key(k_mc, "h", function () awful.tag.incncol(1) end),
324     awful.key(k_mc, "l", function () awful.tag.incncol(-1) end),
325
326     -- Menu
327     awful.key(k_m, "r",
328         function ()
329             awful.prompt.run({ prompt = "Run: " },
330                              mymenubox,
331                              awful.util.spawn,
332                              awful.completion.bash,
333                              awful.util.getdir("cache").."/commands")
334         end),
335     awful.key(k_m, "F4",
336         function ()
337             awful.prompt.run({ prompt = "Run Lua code: " },
338                              mymenubox,
339                              awful.util.eval,
340                              awful.prompt.bash,
341                              awful.util.getdir("cache").."/lua_commands")
342     end),
343
344     awful.key({}, "#192", function() eminent.tag.goto(1, nil, true) end),
345     awful.key({}, "#193", function() eminent.tag.goto(2, nil, true) end),
346     awful.key({}, "#194", function() eminent.tag.goto(3, nil, true) end),
347     awful.key({}, "#195", function() eminent.tag.goto(4, nil, true) end),
348     awful.key({}, "#196", function() eminent.tag.goto(5, nil, true) end)
349 )
350
351 -- Mod+#: Switch to tag
352 -- Mod+Shift+#: Toggle tag display
353 -- Mod+Control+#: Move client to tag
354 -- Mod+Alt+#: Toggle client on tag
355
356 for i = 1, 10 do
357     globalkeys = awful.util.table.join(
358         globalkeys,
359         awful.key(k_m, i % 10,
360             function()
361                 eminent.tag.goto(i, nil, true)
362             end),
363
364         awful.key(k_ms, i % 10,
365             function ()
366                 local t = eminent.tag.getn(i, nil, true)
367                 if t ~= nil then t.selected = not t.selected end
368             end),
369         awful.key(k_mc, i % 10,
370             function ()
371                 local t = eminent.tag.getn(i, nil, true)
372                 if t ~= nil then awful.client.movetotag(t) end
373             end)
374     )
375 end
376
377 ---- }}}
378 ---- {{{ Client hotkeys
379
380 clientkeys = awful.util.table.join(
381     awful.key(k_m, "i", function (c)
382         if mymenubox.text then
383             mymenubox.text = ""
384         else
385             mymenubox.text = "Class: " .. c.class .. " Instance: ".. c.instance
386         end
387     end),
388
389     -- Client manipulation
390     awful.key(k_m, "c", function (c) c:kill() end),
391     awful.key(k_m, "o", awful.client.floating.toggle),
392     awful.key(k_m, "t", awful.client.togglemarked),
393     awful.key(k_m, "F11", function (c) c.fullscreen = not c.fullscreen end)
394 )
395
396 ---- }}}
397
398 root.keys(globalkeys)
399 -- }}}
400 -- {{{ Hooks
401
402 awful.hooks.focus.register(function (c)
403     if not awful.client.ismarked(c) then
404         c.border_color = beautiful.border_focus
405     end
406 end)
407
408 awful.hooks.unfocus.register(function (c)
409     if not awful.client.ismarked(c) then
410         c.border_color = beautiful.border_normal
411     end
412 end)
413
414 awful.hooks.marked.register(function (c)
415     c.border_color = beautiful.border_marked
416 end)
417
418 awful.hooks.unmarked.register(function (c)
419     c.border_color = beautiful.border_focus
420 end)
421
422 -- Hook function to execute when the mouse enters a client.
423 awful.hooks.mouse_enter.register(function (c)
424     -- Sloppy focus
425     client.focus = c
426 end)
427
428 awful.hooks.manage.register(function (c, startup)
429     if not startup and awful.client.focus.filter(c) then
430         c.screen = mouse.screen
431     end
432
433     -- Add mouse bindings
434     c:buttons(awful.util.table.join(
435         awful.button({ }, 1, function (c) client.focus = c; c:raise() end),
436         awful.button(k_a, 1, awful.mouse.client.move),
437         awful.button(k_a, 3, awful.mouse.client.resize)
438     ))
439
440     -- Create border
441     c.border_width = beautiful.border_width
442     c.border_color = beautiful.border_normal
443
444     -- Make certain windows floating
445     local class = c.class:lower()
446     if class:find('pinentry')
447     or class:find('kcalc')
448     or class:find('gajim')
449     then
450         c.floating = true
451     end
452
453     -- Focus new clients
454     client.focus = c
455     c:keys(clientkeys)
456     c.size_hints_honor = false
457 end)
458
459 -- Hook function to execute when arranging the screen
460 -- (tag switch, new client, etc)
461 awful.hooks.arrange.register(function (screen)
462     local sel = client.focus
463
464     if not sel then
465         sel = awful.client.focus.history.get(screen, 0)
466         if not sel then return end
467         client.focus = sel
468     end
469
470     local o = mouse.object_under_pointer()
471     if not o or (type(o) == "client" and o ~= sel) then
472         local g = sel:geometry()
473
474         mouse.coords { x = g.x + 5, y = g.y + 5 }
475     end
476 end)
477
478 -- }}}
479
480 awful.util.spawn("xkbcomp -w 0 -R/usr/share/X11/xkb /home/madcoder/.Xkeyboard :0")