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

478f3f75f76dfc23c74e886f5d10847ebb4925e6
[etc/awesome.git] / .config / awesome / rc.lua
1 -- {{{ Imports
2 -- Standard awesome library
3 local gears = require("gears")
4 local awful = require("awful")
5 require("awful.autofocus")
6 -- Widget and layout library
7 local wibox = require("wibox")
8 -- Theme handling library
9 local beautiful = require("beautiful")
10 -- Notification library
11 local naughty = require("naughty")
12 local menubar = require("menubar")
13 local hotkeys_popup = require("awful.hotkeys_popup").widget
14 local lain = require("lain")
15 local dkjson = require("lain.util").dkjson
16 local math = require("math")
17 -- }}}
18
19 -- {{{ Error handling
20 -- Check if awesome encountered an error during startup and fell back to
21 -- another config (This code will only ever execute for the fallback config)
22 if awesome.startup_errors then
23     naughty.notify({ preset = naughty.config.presets.critical,
24                      title = "Oops, there were errors during startup!",
25                      text = awesome.startup_errors })
26 end
27
28 -- Handle runtime errors after startup
29 do
30     local in_error = false
31     awesome.connect_signal("debug::error", function (err)
32         -- Make sure we don't go into an endless error loop
33         if in_error then return end
34         in_error = true
35
36         naughty.notify({ preset = naughty.config.presets.critical,
37                          title = "Oops, an error happened!",
38                          text = tostring(err) })
39         in_error = false
40     end)
41 end
42 -- }}}
43
44 -- {{{ Variable definitions
45 -- Themes define colours, icons, and wallpapers
46 beautiful.init(awful.util.get_themes_dir() .. "default/theme.lua")
47
48 -- This is used later as the default terminal and editor to run.
49 terminal = "x-terminal-emulator"
50 editor = "sensible-editor"
51 editor_cmd = terminal .. " -e " .. editor
52
53 -- Default modkey.
54 -- Usually, Mod4 is the key with a logo between Control and Alt.
55 -- If you do not like this or do not have such a key,
56 -- I suggest you to remap Mod4 to another key using xmodmap or other tools.
57 -- However, you can use another modifier like Mod1, but it may interact with others.
58 modkey = "Mod4"
59 cmdkey = "Mod3"
60
61 -- Table of layouts to cover with awful.layout.inc, order matters.
62 awful.layout.layouts = {
63     awful.layout.suit.fair,
64     awful.layout.suit.tile,
65     -- awful.layout.suit.tile.left,
66     -- awful.layout.suit.tile.bottom,
67     awful.layout.suit.tile.top,
68     -- awful.layout.suit.spiral,
69     -- awful.layout.suit.spiral.dwindle,
70     awful.layout.suit.max,
71     -- awful.layout.suit.max.fullscreen,
72     -- awful.layout.suit.magnifier,
73     -- awful.layout.suit.corner.nw,
74     -- awful.layout.suit.corner.ne,
75     -- awful.layout.suit.corner.sw,
76     -- awful.layout.suit.corner.se,
77     awful.layout.suit.floating,
78 }
79
80 layout_default = awful.layout.layouts[1]
81 layout_tiled = awful.layout.layouts[2]
82 layout_maximised = awful.layout.layouts[4]
83 layout_floating = awful.layout.layouts[5]
84 -- }}}
85
86 -- {{{ Helper functions
87 local function client_menu_toggle_fn()
88     local instance = nil
89
90     return function ()
91         if instance and instance.wibox.visible then
92             instance:hide()
93             instance = nil
94         else
95             instance = awful.menu.clients({ theme = { width = 250 } })
96         end
97     end
98 end
99
100 local function sorted_pairs(t, f)
101     local a = {}
102     for n in pairs(t) do table.insert(a, n) end
103     table.sort(a, f)
104     local i = 0      -- iterator variable
105     local iter = function ()   -- iterator function
106         i = i + 1
107         if a[i] == nil then return nil
108         else return a[i], t[a[i]]
109         end
110     end
111     return iter
112 end
113
114 local function print_table(tbl, indent)
115     if not indent then indent = 0 end
116     for k, v in pairs(tbl) do
117         formatting = string.rep("  ", indent) .. k .. ": "
118         if type(v) == "table" then
119             print(formatting)
120             print_table(v, indent+1)
121         else
122             print(formatting .. tostring(v))
123         end
124     end
125 end
126
127 local lain_bat = lain.widgets.bat({
128     batteries = {"BAT0", "BAT1"},
129     settings = function()
130         local delim = "↓"
131         if bat_now.status == "Charging" then delim = "↑" end
132         widget:set_text(bat_now.perc .. "% " .. delim .. " " .. bat_now.time)
133     end,
134 })
135
136 local function poloniex_price(output, pair, prec)
137     local xc, pos, err = dkjson.decode(output, 1, nil)
138     if not prec then prec = 4 end
139     val = (xc and xc[pair]["last"]) or 0
140     val = math.floor(val*10^prec+0.5)/10^prec
141     return (not err and val) or "n/a"
142 end
143
144 local eth_widget = lain.widgets.abase({
145     cmd = "curl -m5 -s 'https://poloniex.com/public?command=returnTicker'",
146     timeout = 600,
147     settings = function()
148         widget:set_text(poloniex_price(output, 'BTC_ETH') .. " Ƀ/Ξ")
149     end
150 })
151
152 local function coindesk_price(output, base, prec)
153     print(output)
154     local xc, pos, err = dkjson.decode(output, 1, nil)
155     if not prec then prec = 4 end
156     val = (xc and xc["bpi"][base]["rate_float"]) or 0
157     val = math.floor(val*10^prec+0.5)/10^prec
158     return (not err and val) or "n/a"
159 end
160
161 local btc_widget = lain.widgets.abase({
162     cmd = "curl -m5 -Ls 'https://api.coindesk.com/v1/bpi/currentprice/EUR.json'",
163     timeout = 600,
164     settings = function()
165         widget:set_text(coindesk_price(output, "EUR", 2) .. " €/Ƀ")
166     end
167 })
168
169 -- }}}
170
171 -- {{{ Menu
172 -- Create a launcher widget and a main menu
173 myawesomemenu = {
174    { "hotkeys", function() return false, hotkeys_popup.show_help end},
175    { "manual", terminal .. " -e man awesome" },
176    { "edit config", editor_cmd .. " " .. awesome.conffile },
177    { "restart", awesome.restart },
178    { "quit", awesome.quit }
179 }
180
181 mymainmenu = awful.menu({ items = { { "awesome", myawesomemenu, beautiful.awesome_icon },
182                                     { "open terminal", terminal }
183                                   }
184                         })
185
186 mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon,
187                                      menu = mymainmenu })
188 -- }}}
189
190 -- {{{ Menubar configuration
191 menubar.utils.terminal = terminal -- Set the terminal for applications that require it
192 -- }}}
193
194 -- {{{ Wibox
195 local spacer = wibox.widget.textbox()
196 spacer:set_text(' | ')
197 -- Create a textclock widget
198 mytextclock = wibox.widget.textclock("%a %d %b %H:%M:%S", 1)
199
200 -- Create a wibox for each screen and add it
201 mywibox = {}
202 mypromptbox = {}
203 mylayoutbox = {}
204 mytaglist = {}
205 mytaglist.buttons = awful.util.table.join(
206                     awful.button({ }, 1, function(t) t:view_only() end),
207                     awful.button({ modkey }, 1, function(t)
208                                               if client.focus then
209                                                   client.focus:move_to_tag(t)
210                                               end
211                                           end),
212                     awful.button({ }, 3, awful.tag.viewtoggle),
213                     awful.button({ modkey }, 3, function(t)
214                                               if client.focus then
215                                                   client.focus:toggle_tag(t)
216                                               end
217                                           end),
218                     awful.button({ }, 4, function(t) awful.tag.viewnext(t.screen) end),
219                     awful.button({ }, 5, function(t) awful.tag.viewprev(t.screen) end)
220                 )
221
222 mytasklist = {}
223 mytasklist.buttons = awful.util.table.join(
224                      awful.button({ }, 1, function (c)
225                                               if c == client.focus then
226                                                   -- I don't like click-minimising
227                                                   -- c.minimized = true
228                                               else
229                                                   -- Without this, the following
230                                                   -- :isvisible() makes no sense
231                                                   c.minimized = false
232                                                   if not c:isvisible() and c.first_tag then
233                                                       c.first_tag:view_only()
234                                                   end
235                                                   -- This will also un-minimize
236                                                   -- the client, if needed
237                                                   client.focus = c
238                                                   c:raise()
239                                               end
240                                           end),
241                      awful.button({ }, 3, client_menu_toggle_fn()),
242                      awful.button({ }, 4, function ()
243                                               awful.client.focus.byidx(1)
244                                           end),
245                      awful.button({ }, 5, function ()
246                                               awful.client.focus.byidx(-1)
247                                           end))
248 -- }}}
249
250 -- {{{ Tags
251 tags = {}
252 tags.config = {}
253 tags.config["main"] = {
254     t1 = { layout = layout_default, selected = true },
255     t2 = { layout = layout_default },
256     t3 = { layout = layout_tiled },
257     t4 = { layout = layout_tiled },
258     t5 = { layout = layout_tiled },
259     t6 = { layout = layout_floating },
260     t7 = { layout = layout_maximised },
261     t8 = { layout = layout_maximised },
262     t9 = { layout = layout_maximised },
263 }
264 tags.config["aux"] = {
265     t1 = { layout = layout_default, selected = true },
266     t2 = { layout = layout_default },
267     t3 = { layout = layout_tiled },
268     t4 = { layout = layout_floating },
269     t5 = { layout = layout_floating },
270     t6 = { layout = layout_floating },
271     t7 = { layout = layout_floating },
272     t8 = { layout = layout_floating },
273     t9 = { layout = layout_maximised },
274 }
275
276 screentags = {}
277 screentags[1] = tags.config["main"]
278 if screen.count() == 2 then -- aux screen is on the right
279   screentags[2] = tags.config["aux"]
280 elseif screen.count() == 3 then -- main screen is still #1 in the middle
281   screentags[2] = tags.config["aux"]
282   screentags[3] = tags.config["aux"]
283 end
284
285 awful.screen.connect_for_each_screen(function(s)
286     -- Wallpaper
287     --DISABLED--if beautiful.wallpaper then
288     --DISABLED--    local wallpaper = beautiful.wallpaper
289     --DISABLED--    -- If wallpaper is a function, call it with the screen
290     --DISABLED--    if type(wallpaper) == "function" then
291     --DISABLED--        wallpaper = wallpaper(s)
292     --DISABLED--    end
293     --DISABLED--    gears.wallpaper.maximized(wallpaper, s, true)
294     --DISABLED--end
295
296     if not tags[s.index] then
297         tags[s.index] = {}
298     end
299     for n,p in sorted_pairs(screentags[s.index]) do
300         p["screen"] = s
301         n = string.sub(n, 2) -- remove leading 't' needed for syntax in table
302         table.insert(tags[s.index], awful.tag.add(n, p))
303     end
304
305     -- Create a promptbox for each screen
306     mypromptbox[s] = awful.widget.prompt()
307     -- Create an imagebox widget which will contains an icon indicating which layout we're using.
308     -- We need one layoutbox per screen.
309     mylayoutbox[s] = awful.widget.layoutbox(s)
310     mylayoutbox[s]:buttons(awful.util.table.join(
311                            awful.button({ }, 1, function () awful.layout.inc( 1) end),
312                            awful.button({ }, 3, function () awful.layout.inc(-1) end),
313                            awful.button({ }, 4, function () awful.layout.inc( 1) end),
314                            awful.button({ }, 5, function () awful.layout.inc(-1) end)))
315     -- Create a taglist widget
316     mytaglist[s] = awful.widget.taglist(s, awful.widget.taglist.filter.all, mytaglist.buttons)
317
318     -- Create a tasklist widget
319     mytasklist[s] = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, mytasklist.buttons)
320
321     -- Create the wibox
322     mywibox[s] = awful.wibar({ position = "top", screen = s })
323
324     -- Add widgets to the wibox
325     mywibox[s]:setup {
326         layout = wibox.layout.align.horizontal,
327         { -- Left widgets
328             layout = wibox.layout.fixed.horizontal,
329             -- mylauncher,
330             mytaglist[s],
331             mypromptbox[s],
332         },
333         mytasklist[s], -- Middle widget
334         { -- Right widgets
335             layout = wibox.layout.fixed.horizontal,
336             mykeyboardlayout,
337             wibox.widget.systray(),
338             btc_widget,
339             spacer,
340             eth_widget,
341             spacer,
342             lain_bat.widget,
343             spacer,
344             mytextclock,
345             mylayoutbox[s],
346         },
347     }
348 end)
349 -- }}}
350
351 -- {{{ Mouse bindings
352 root.buttons(awful.util.table.join(
353     awful.button({ }, 3, function () mymainmenu:toggle() end),
354     awful.button({ }, 4, awful.tag.viewnext),
355     awful.button({ }, 5, awful.tag.viewprev)
356 ))
357 -- }}}
358
359 -- {{{ Key bindings
360 globalkeys = awful.util.table.join(
361     awful.key({ modkey,           }, "s",      hotkeys_popup.show_help,
362               {description="show help", group="awesome"}),
363     awful.key({ modkey,           }, "Left",   awful.tag.viewprev,
364               {description = "view previous", group = "tag"}),
365     awful.key({ modkey,           }, "Right",  awful.tag.viewnext,
366               {description = "view next", group = "tag"}),
367     awful.key({ modkey,           }, "Escape", awful.tag.history.restore,
368               {description = "go back", group = "tag"}),
369
370     awful.key({ modkey,           }, "k",
371         function ()
372             awful.client.focus.byidx( 1)
373         end,
374         {description = "focus next by index", group = "client"}
375     ),
376     awful.key({ modkey,           }, "j",
377         function ()
378             awful.client.focus.byidx(-1)
379         end,
380         {description = "focus previous by index", group = "client"}
381     ),
382     awful.key({ modkey,           }, "w", function () mymainmenu:show() end,
383               {description = "show main menu", group = "awesome"}),
384
385     -- Layout manipulation
386     awful.key({ modkey, "Shift"   }, "k", function () awful.client.swap.byidx(  1)    end,
387               {description = "swap with next client by index", group = "client"}),
388     awful.key({ modkey, "Shift"   }, "j", function () awful.client.swap.byidx( -1)    end,
389               {description = "swap with previous client by index", group = "client"}),
390     awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative( 1) end,
391               {description = "focus the next screen", group = "screen"}),
392     awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative(-1) end,
393               {description = "focus the previous screen", group = "screen"}),
394     awful.key({ modkey,           }, "u", awful.client.urgent.jumpto,
395               {description = "jump to urgent client", group = "client"}),
396     awful.key({ modkey,           }, "Tab",
397         function ()
398             awful.client.focus.history.previous()
399             if client.focus then
400                 client.focus:raise()
401             end
402         end,
403         {description = "go back", group = "client"}),
404
405     -- Standard program
406     awful.key({ modkey,           }, "Return", function () awful.spawn(terminal) end,
407               {description = "open a terminal", group = "launcher"}),
408     awful.key({ modkey, "Control" }, "r", awesome.restart,
409               {description = "reload awesome", group = "awesome"}),
410     awful.key({ modkey, "Shift"   }, "q", awesome.quit,
411               {description = "quit awesome", group = "awesome"}),
412
413     awful.key({ modkey,           }, "l",     function () awful.tag.incmwfact( 0.05)          end,
414               {description = "increase master width factor", group = "layout"}),
415     awful.key({ modkey,           }, "h",     function () awful.tag.incmwfact(-0.05)          end,
416               {description = "decrease master width factor", group = "layout"}),
417     awful.key({ modkey, "Shift"   }, "h",     function () awful.tag.incnmaster( 1, nil, true) end,
418               {description = "increase the number of master clients", group = "layout"}),
419     awful.key({ modkey, "Shift"   }, "l",     function () awful.tag.incnmaster(-1, nil, true) end,
420               {description = "decrease the number of master clients", group = "layout"}),
421     awful.key({ modkey, "Control" }, "h",     function () awful.tag.incncol( 1, nil, true)    end,
422               {description = "increase the number of columns", group = "layout"}),
423     awful.key({ modkey, "Control" }, "l",     function () awful.tag.incncol(-1, nil, true)    end,
424               {description = "decrease the number of columns", group = "layout"}),
425     awful.key({ modkey,           }, "space", function () awful.layout.inc( 1)                end,
426               {description = "select next", group = "layout"}),
427     awful.key({ modkey, "Shift"   }, "space", function () awful.layout.inc(-1)                end,
428               {description = "select previous", group = "layout"}),
429
430     awful.key({ modkey, "Control" }, "n",
431               function ()
432                   local c = awful.client.restore()
433                   -- Focus restored client
434                   if c then
435                       client.focus = c
436                       c:raise()
437                   end
438               end,
439               {description = "restore minimized", group = "client"}),
440
441     -- Prompt
442     awful.key({ modkey },            "r",     function () mypromptbox[awful.screen.focused()]:run() end,
443               {description = "run prompt", group = "launcher"}),
444
445     awful.key({ modkey }, "x",
446               function ()
447                   awful.prompt.run({ prompt = "Run Lua code: " },
448                   mypromptbox[awful.screen.focused()].widget,
449                   awful.util.eval, nil,
450                   awful.util.get_cache_dir() .. "/history_eval")
451               end,
452               {description = "lua execute prompt", group = "awesome"}),
453     -- Menubar
454     awful.key({ modkey }, "p", function() menubar.show() end,
455               {description = "show the menubar", group = "launcher"})
456 )
457
458 clientkeys = awful.util.table.join(
459     awful.key({ modkey,           }, "f",
460         function (c)
461             c.fullscreen = not c.fullscreen
462             c:raise()
463         end,
464         {description = "toggle fullscreen", group = "client"}),
465     awful.key({ modkey, "Shift"   }, "c",      function (c) c:kill()                         end,
466               {description = "close", group = "client"}),
467     awful.key({ modkey, "Control" }, "space",  awful.client.floating.toggle                     ,
468               {description = "toggle floating", group = "client"}),
469     awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end,
470               {description = "move to master", group = "client"}),
471     awful.key({ modkey,           }, "o",      function (c) c:move_to_screen()               end,
472               {description = "move to screen", group = "client"}),
473     awful.key({ modkey,           }, "t",      function (c) c.ontop = not c.ontop            end,
474               {description = "toggle keep on top", group = "client"}),
475     awful.key({ modkey,           }, "n",
476         function (c)
477             -- The client currently has the input focus, so it cannot be
478             -- minimized, since minimized clients can't have the focus.
479             c.minimized = true
480         end ,
481         {description = "minimize", group = "client"}),
482     awful.key({ modkey,           }, "m",
483         function (c)
484             c.maximized = not c.maximized
485             c:raise()
486         end ,
487         {description = "maximize", group = "client"})
488 )
489
490 -- Bind all key numbers to tags.
491 -- Be careful: we use keycodes to make it works on any keyboard layout.
492 -- This should map on the top row of your keyboard, usually 1 to 9.
493 for i = 1, 9 do
494     globalkeys = awful.util.table.join(globalkeys,
495         -- View tag only.
496         awful.key({ modkey }, "#" .. i + 9,
497                   function ()
498                         local screen = awful.screen.focused()
499                         local tag = screen.tags[i]
500                         if tag then
501                            tag:view_only()
502                         end
503                   end,
504                   {description = "view tag #"..i, group = "tag"}),
505         -- Toggle tag.
506         awful.key({ modkey, "Control" }, "#" .. i + 9,
507                   function ()
508                       local screen = awful.screen.focused()
509                       local tag = screen.tags[i]
510                       if tag then
511                          awful.tag.viewtoggle(tag)
512                       end
513                   end,
514                   {description = "toggle tag #" .. i, group = "tag"}),
515         -- Move client to tag.
516         awful.key({ modkey, "Shift" }, "#" .. i + 9,
517                   function ()
518                       if client.focus then
519                           local tag = client.focus.screen.tags[i]
520                           if tag then
521                               client.focus:move_to_tag(tag)
522                           end
523                      end
524                   end,
525                   {description = "move focused client to tag #"..i, group = "tag"}),
526         -- Toggle tag on focused client.
527         awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
528                   function ()
529                       if client.focus then
530                           local tag = client.focus.screen.tags[i]
531                           if tag then
532                               client.focus:toggle_tag(tag)
533                           end
534                       end
535                   end,
536                   {description = "toggle focused client on tag #" .. i, group = "tag"})
537     )
538 end
539
540 clientbuttons = awful.util.table.join(
541     awful.button({ }, 1, function (c) client.focus = c; c:raise() end),
542     awful.button({ modkey }, 1, awful.mouse.client.move),
543     awful.button({ modkey }, 3, awful.mouse.client.resize))
544
545 -- misc apps
546 globalkeys = awful.util.table.join(globalkeys,
547 awful.key({ cmdkey }, "n", function () awful.spawn("firefox") end),
548 awful.key({ cmdkey }, "m", function () awful.spawn("chromium") end),
549 awful.key({ cmdkey }, "y", function () awful.spawn(terminal .. " -e python") end),
550 awful.key({ cmdkey }, "c", function () awful.spawn("icedove") end),
551 awful.key({ cmdkey }, "r", function () mypromptbox[mouse.screen]:run() end),
552 awful.key({ cmdkey }, "g", function () awful.spawn("gscan2pdf") end),
553 awful.key({ cmdkey }, "v", function () awful.spawn("virt-manager") end),
554 awful.key({ cmdkey }, "l", function () awful.spawn("libreoffice") end),
555 awful.key({ cmdkey }, "f", function () awful.spawn("thunar") end),
556 awful.key({ cmdkey }, "i", function () awful.spawn(terminal .. " -title irc -name irc -e env MOSH_TITLE_NOPREFIX=true mosh -4 -- irc-host screen -dr irc") end),
557 awful.key({ cmdkey }, "x", function () awful.spawn.with_shell("/sbin/start-stop-daemon --start --background --exec /usr/bin/xscreensaver -- -no-capture-stderr; sleep 2; xscreensaver-command -lock") end),
558 awful.key({ cmdkey, "Shift" }, "x", function () awful.spawn("xscreensaver-command -exit") end),
559
560 -- function keys
561 awful.key(nil, "XF86ScreenSaver", function () awful.spawn("xset dpms force off") end),
562 awful.key(nil, "XF86AudioMute", function () awful.spawn("pactl set-sink-mute 0 toggle") end),
563 awful.key({ cmdkey }, "End", function () awful.spawn("pactl set-sink-mute 0 toggle") end),
564 awful.key(nil, "XF86AudioLowerVolume", function () awful.spawn("pactl set-sink-volume 0 -2%") end),
565 awful.key({ cmdkey }, "Next", function () awful.spawn("pactl set-sink-volume 0 -2%") end),
566 awful.key(nil, "XF86AudioRaiseVolume", function () awful.spawn("pactl set-sink-volume 0 +2%") end),
567 awful.key({ cmdkey }, "Prior", function () awful.spawn("pactl set-sink-volume 0 +2%") end),
568 awful.key(nil, "XF86AudioMicMute", function () awful.spawn("pactl set-source-mute 1 toggle") end),
569 awful.key({ cmdkey }, "Home", function () awful.spawn("pactl set-source-mute 1 toggle") end),
570 awful.key(nil, "XF86MonBrightnessDown", function () awful.spawn("xbacklight -dec 5%") end),
571 awful.key(nil, "XF86MonBrightnessUp", function () awful.spawn("xbacklight -inc 5%") end),
572 awful.key(nil, "XF86Display", function () awful.spawn("") end),
573 awful.key(nil, "XF86WLAN", function () awful.spawn("") end),
574 awful.key(nil, "XF86Tools", function () awful.spawn("") end),
575 awful.key(nil, "XF86Search", function () awful.spawn("") end),
576 awful.key(nil, "XF86LaunchA", function () awful.spawn("") end),
577 awful.key(nil, "XF86Explorer", function () awful.spawn("") end)
578 )
579
580 -- Set keys
581 root.keys(globalkeys)
582 -- }}}
583
584 -- {{{ Rules
585 -- Rules to apply to new clients (through the "manage" signal).
586
587 local function move_to_tag(s, t)
588     return function(c)
589         c:move_to_tag(tags[s][t])
590     end
591 end
592
593 awful.rules.rules = {
594     -- All clients will match this rule.
595     { rule = { },
596       properties = { border_width = beautiful.border_width,
597                      border_color = beautiful.border_normal,
598                      focus = awful.client.focus.filter,
599                      raise = true,
600                      keys = clientkeys,
601                      buttons = clientbuttons,
602                      screen = awful.screen.preferred,
603                      placement = awful.placement.no_overlap+awful.placement.no_offscreen,
604                      floating = true
605                  },
606     },
607
608     -- Add titlebars to normal clients and dialogs
609     --DISABLED-- { rule_any = {type = { "normal", "dialog" }
610     --DISABLED--  }, properties = { titlebars_enabled = true }
611     --DISABLED-- },
612
613     { rule = { type = "dialog" },
614       properties = { placement = awful.placement.centered }},
615
616     { rule = { class = "URxvt" },
617                properties = {
618                    floating = false,
619                    size_hints_honor = false
620                } },
621     { rule = { class = "URxvt", instance = "irc" },
622                properties = {
623                    switchtotag = true
624                },
625                callback = move_to_tag(screen.count(), screen.count() == 1 and 2 or 1)
626            },
627     { rule = { class = "Firefox", instance = "Navigator" },
628                properties = {
629                    floating = false,
630                },
631                callback = move_to_tag(screen.count() == 1 and 1 or 2, 9)
632            },
633     { rule = { class = "Icedove", instance = "Mail" },
634                properties = {
635                    floating = false,
636                },
637                callback = move_to_tag(screen.count() == 1 and 1 or 2, 8)
638            },
639     { rule = { class = "Chromium", instance = "chromium" },
640                properties = {
641                    floating = false,
642                },
643                callback = move_to_tag(screen.count() == 1 and 1 or 2, 9)
644            },
645     { rule = { class = "Gscan2pdf" },
646                properties = {
647                    switchtotag = true
648                },
649                callback = move_to_tag(1, 5)
650            },
651     { rule = { name = "gscan2pdf .*" },
652                properties = {
653                    floating = false,
654                },
655            },
656     { rule = { class = "Thunar", type = "normal" },
657                properties = {
658                    floating = false,
659                },
660            },
661 }
662 -- }}}
663
664 -- {{{ Signals
665 -- Signal function to execute when a new client appears.
666 client.connect_signal("manage", function (c)
667     -- Set the windows at the slave,
668     -- i.e. put it at the end of others instead of setting it master.
669     -- if not awesome.startup then awful.client.setslave(c) end
670
671     if awesome.startup and
672       not c.size_hints.user_position
673       and not c.size_hints.program_position then
674         -- Prevent clients from being unreachable after screen count changes.
675         awful.placement.no_offscreen(c)
676     end
677 end)
678
679 -- Add a titlebar if titlebars_enabled is set to true in the rules.
680 client.connect_signal("request::titlebars", function(c)
681     -- buttons for the titlebar
682     local buttons = awful.util.table.join(
683         awful.button({ }, 1, function()
684             client.focus = c
685             c:raise()
686             awful.mouse.client.move(c)
687         end),
688         awful.button({ }, 3, function()
689             client.focus = c
690             c:raise()
691             awful.mouse.client.resize(c)
692         end)
693     )
694
695     awful.titlebar(c) : setup {
696         { -- Left
697             awful.titlebar.widget.iconwidget(c),
698             buttons = buttons,
699             layout  = wibox.layout.fixed.horizontal
700         },
701         { -- Middle
702             { -- Title
703                 align  = "center",
704                 widget = awful.titlebar.widget.titlewidget(c)
705             },
706             buttons = buttons,
707             layout  = wibox.layout.flex.horizontal
708         },
709         { -- Right
710             awful.titlebar.widget.floatingbutton (c),
711             awful.titlebar.widget.maximizedbutton(c),
712             awful.titlebar.widget.stickybutton   (c),
713             awful.titlebar.widget.ontopbutton    (c),
714             awful.titlebar.widget.closebutton    (c),
715             layout = wibox.layout.fixed.horizontal()
716         },
717         layout = wibox.layout.align.horizontal
718     }
719 end)
720
721 -- Enable sloppy focus
722 client.connect_signal("mouse::enter", function(c)
723     if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
724         and awful.client.focus.filter(c) then
725         client.focus = c
726     end
727 end)
728
729 client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end)
730 client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
731
732 awful.ewmh.add_activate_filter(function(c, context, hints)
733     if context == "ewmh" and c.class == "Firefox" then return false end
734 end)
735
736 -- vim:ft=lua:sw=4:sts=4:ts=4:et