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:

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