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

follow config changes
[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.focusbyidx(1) end),
134     button({ }, 5, function () awful.client.focusbyidx(-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.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, 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, awful.eval, awful.prompt.bash,
301 os.getenv("HOME") .. "/.cache/awesome/history_eval") end):add()
302 keybinding({ modkey, "Ctrl" }, "i", function ()
303                                         if mypromptbox.text then
304                                             mypromptbox.text = nil
305                                         else
306                                             mypromptbox.text = nil
307                                             if client.focus.class then
308                                                 mypromptbox.text = "Class: " .. client.focus.class .. " "
309                                             end
310                                             if client.focus.instance then
311                                                 mypromptbox.text = mypromptbox.text .. "Instance: ".. client.focus.instance .. " "
312                                             end
313                                             if client.focus.role then
314                                                 mypromptbox.text = mypromptbox.text .. "Role: ".. client.focus.role
315                                             end
316                                         end
317                                     end):add()
318
319 --- Tabulous, tab manipulation
320 keybinding({ modkey, "Control" }, "y", function ()
321     local tabbedview = tabulous.tabindex_get()
322     local nextclient = awful.client.next(1)
323
324     if not tabbedview then
325         tabbedview = tabulous.tabindex_get(nextclient)
326
327         if not tabbedview then
328             tabbedview = tabulous.tab_create()
329             tabulous.tab(tabbedview, nextclient)
330         else
331             tabulous.tab(tabbedview, client.focus)
332         end
333     else
334         tabulous.tab(tabbedview, nextclient)
335     end
336 end):add()
337
338 keybinding({ modkey, "Shift" }, "y", tabulous.untab):add()
339
340 keybinding({ modkey }, "y", function ()
341    local tabbedview = tabulous.tabindex_get()
342
343    if tabbedview then
344        local n = tabulous.next(tabbedview)
345        tabulous.display(tabbedview, n)
346    end
347 end):add()
348
349 -- Client awful tagging: this is useful to tag some clients and then do stuff like move to tag on them
350 keybinding({ modkey }, "t", awful.client.togglemarked):add()
351 keybinding({ modkey, 'Shift' }, "t", function ()
352     local tabbedview = tabulous.tabindex_get()
353     local clients = awful.client.getmarked()
354
355     if not tabbedview then
356         tabbedview = tabulous.tab_create(clients[1])
357         table.remove(clients, 1)
358     end
359
360     for k,c in pairs(clients) do
361         tabulous.tab(tabbedview, c)
362     end
363
364 end):add()
365
366 for i = 1, keynumber do
367     keybinding({ modkey, "Shift" }, "F" .. i,
368                    function ()
369                        local screen = mouse.screen
370                        if tags[screen][i] then
371                            for k, c in pairs(awful.client.getmarked()) do
372                                awful.client.movetotag(tags[screen][i], c)
373                            end
374                        end
375                    end):add()
376 end
377 -- }}}
378
379 -- {{{ Hooks
380 -- Hook function to execute when focusing a client.
381 awful.hooks.focus.register(function (c)
382     if not awful.client.ismarked(c) then
383         c.border_color = beautiful.border_focus
384     end
385 end)
386
387 -- Hook function to execute when unfocusing a client.
388 awful.hooks.unfocus.register(function (c)
389     if not awful.client.ismarked(c) then
390         c.border_color = beautiful.border_normal
391     end
392 end)
393
394 -- Hook function to execute when marking a client
395 awful.hooks.marked.register(function (c)
396     c.border_color = beautiful.border_marked
397 end)
398
399 -- Hook function to execute when unmarking a client
400 awful.hooks.unmarked.register(function (c)
401     c.border_color = beautiful.border_focus
402 end)
403
404 -- Hook function to execute when the mouse is over a client.
405 awful.hooks.mouse_enter.register(function (c)
406     -- Sloppy focus, but disabled for magnifier layout
407     if awful.layout.get(c.screen) ~= "magnifier"
408         and awful.client.focus.filter(c) then
409         client.focus = c
410     end
411 end)
412
413 -- Hook function to execute when a new client appears.
414 awful.hooks.manage.register(function (c)
415     if use_titlebar then
416         -- Add a titlebar
417         awful.titlebar.add(c, { modkey = modkey })
418     end
419     -- Add mouse bindings
420     c:buttons({
421         button({ }, 1, function (c) client.focus = c; c:raise() end),
422         button({ modkey }, 1, function (c) c:mouse_move() end),
423         button({ modkey }, 3, function (c) c:mouse_resize() end)
424     })
425     -- New client may not receive focus
426     -- if they're not focusable, so set border anyway.
427     c.border_width = beautiful.border_width
428     c.border_color = beautiful.border_normal
429     client.focus = c
430
431     -- Check if the application should be floating.
432     -- OVERRIDDEN, SEE tiledapps BELOW
433     local cls = c.class
434     local inst = c.instance
435     if floatapps[cls] then
436         c.floating = floatapps[cls]
437     elseif floatapps[inst] then
438         c.floating = floatapps[inst]
439     end
440
441     -- Override with tiledapps
442     c.floating = not (tiledapps[inst] or tiledapps[cls])
443
444     -- Check application->screen/tag mappings.
445     local target
446     if apptags[cls] then
447         target = apptags[cls]
448     elseif apptags[inst] then
449         target = apptags[inst]
450     end
451     if target then
452         c.screen = target.screen
453         awful.client.movetotag(tags[target.screen][target.tag], c)
454     end
455
456     -- Set the windows at the slave,
457     -- i.e. put it at the end of others instead of setting it master.
458     -- awful.client.setslave(c)
459
460     -- Honor size hints: if you want to drop the gaps between windows, set this to false.              |      if maxapps[inst] or maxapps[cls] then                                                              
461     c.honorsizehints = true
462
463     -- Maximise some
464     if maxapps[inst] or maxapps[cls] then
465       awful.client.maximize(c)
466     end
467 end)
468
469 -- Hook function to execute when arranging the screen
470 -- (tag switch, new client, etc)
471 awful.hooks.arrange.register(function (screen)
472     local layout = awful.layout.get(screen)
473     if layout then
474         mylayoutbox[screen].image = image("/home/madduck/code/awesome/share/awesome/icons/layouts/" .. layout .. "w.png")
475     else
476         mylayoutbox[screen].image = nil
477     end
478
479     -- Give focus to the latest client in history if no window has focus
480     -- or if the current window is a desktop or a dock one.
481     if not client.focus then
482         local c = awful.client.focus.history.get(screen, 0)
483         if c then client.focus = c end
484     end
485
486     -- Uncomment if you want mouse warping
487     --[[
488     if client.focus then
489         local c_c = client.focus:coords()
490         local m_c = mouse.coords()
491
492         if m_c.x < c_c.x or m_c.x >= c_c.x + c_c.width or
493             m_c.y < c_c.y or m_c.y >= c_c.y + c_c.height then
494             if table.maxn(m_c.buttons) == 0 then
495                 mouse.coords({ x = c_c.x + 5, y = c_c.y + 5})
496             end
497         end
498     end
499     ]]
500 end)
501
502 -- Hook called every second
503 awful.hooks.timer.register(1, function ()
504     -- For unix time_t lovers
505     -- mytextbox.text = " " .. os.time() .. " time_t "
506     -- Otherwise use:
507     mytimebox.text = " " .. os.date() .. " "
508 end)
509
510 -- Hook called every sixty seconds
511 function hook_battery()
512     mybatterybox.text = " " .. get_acpibatt() .. " "
513 end
514
515 -- {{{ Statusbar battery
516 --
517 function get_acpibatt()
518
519     local f = io.popen('acpi -b', 'r')
520     if not f then
521       return "acpi -b failed"
522     end
523
524     local s = f:read('*l')
525     f:close()
526     if not s then
527       return laststring;
528     end
529
530     -- Battery 0: Discharging, 89%, 00:02:14 remaining
531     -- Battery 0: Charging, 58%, 00:02:14 until charged
532     -- Battery 0: Full, 100%
533     -- so find the first bit first and then go look for the time
534     local st, en, status, percent = string.find(s, '%a+%s%d:%s(%a+),%s(%d+%%)');
535     local st, en, time = string.find(s, ',%s(%d+:%d+:%d+)%s%a+', en);
536
537     if not status or not percent then -- time can be empty if we're full
538       return "couldn't parse line " .. s
539     end
540
541     if not time then
542       return percent
543     end
544
545     if status == 'Charging' then
546       status = 'c';
547     elseif status == 'Discarching' then
548       status = 'd';
549     else
550       status = '';
551     end
552
553     return percent; -- .. ' (' .. status .. ')'; -- .. ' ' .. time .. ' left';
554 end
555 -- }}}
556
557 --{{{ batt hook
558 local function get_bat()
559   local a = io.open("/sys/class/power_supply/BAT1/charge_full")
560   for line in a:lines() do
561     full = line
562   end
563   a:close()
564   local b = io.open("/sys/class/power_supply/BAT1/charge_now")
565   for line in b:lines() do
566     now = line
567   end
568   b:close()
569   batt=math.floor(now*100/full)
570   batterywidget:bar_data_add("bat",batt )
571 end
572 --}}}
573
574 -- Set up some hooks
575 awful.hooks.timer.register(120, hook_battery)
576 -- awful.hooks.timer.register(5, get_bat)
577 -- }}}
578
579 cmdmodkey = "Mod3"
580
581 -- xmms2 & sound
582 keybinding({ cmdmodkey }, "Prior", function () awful.util.spawn("amixer set Master 2+") end):add()
583 keybinding({ cmdmodkey }, "Next", function () awful.util.spawn("amixer set Master 2-") end):add()
584 keybinding({ cmdmodkey }, "Up", function () awful.util.spawn("amixer set PCM 2+") end):add()
585 keybinding({ cmdmodkey }, "Down", function () awful.util.spawn("amixer set PCM 2-") end):add()
586 keybinding({ cmdmodkey }, "Home", function () awful.util.spawn("amixer set Mic toggle") end):add()
587 keybinding({ cmdmodkey }, "End", function () awful.util.spawn("amixer set Master toggle") end):add()
588 keybinding({ cmdmodkey }, "Left", function () awful.util.spawn("xmms2 prev") end):add()
589 keybinding({ cmdmodkey }, "Right", function () awful.util.spawn("xmms2 next") end):add()
590 keybinding({ cmdmodkey }, "space", function () awful.util.spawn("xmms2 toggleplay") end):add()
591 keybinding({ cmdmodkey }, "backslash", function () awful.util.spawn("xmms2 current | head -1 | xmessage -nearmouse -timeout 5 -file -") end):add()
592 keybinding({ cmdmodkey, "Shift" }, "backslash", function () awful.util.spawn("xmms2 list | xmessage -nearmouse -timeout 5 -file -") end):add()
593
594 -- misc apps
595 keybinding({ cmdmodkey }, "n", function () awful.util.spawn("sensible-browser") end):add()
596 keybinding({ cmdmodkey }, "m", function () awful.util.spawn(terminal .. " -e mutt -f =store") end):add()
597 keybinding({ cmdmodkey }, "t", function () awful.util.spawn(terminal) end):add()
598 keybinding({ cmdmodkey }, "c", function () awful.util.spawn(terminal .. " -e python") end):add()
599 keybinding({ cmdmodkey }, "r", function () awful.util.spawn("gmrun") end):add()
600 keybinding({ cmdmodkey }, "j", function () awful.util.spawn("jpilot") end):add()
601 keybinding({ cmdmodkey }, "x", function () awful.util.spawn("/sbin/start-stop-daemon --start --background --exec /usr/bin/xscreensaver; xscreensaver-command -lock") end):add()
602 keybinding({ cmdmodkey, "Shift" }, "x", function () awful.util.spawn("xscreensaver-command -exit") end):add()
603
604 -- Highlight statusbars on the screen that has focus, 
605 -- set this to false if you only have one screen or 
606 -- you don't like it :P
607 if screen.count() > 1 then
608   statusbar_highlight_focus = true
609 else
610   statusbar_highlight_focus = false
611 end
612
613 hook_battery()