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