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

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