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.
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 -- Tyrannical tab handling
9 --local tyrannical = require("tyrannical")
10 -- Theme handling library
11 local beautiful = require("beautiful")
12 local xrdb = beautiful.xresources
13 -- Notification library
14 local naughty = require("naughty")
15 local menubar = require("menubar")
16 local hotkeys_popup = require("awful.hotkeys_popup").widget
17 -- Enable hotkeys help widget for VIM and other apps
18 -- when client with a matching name is opened:
19 require("awful.hotkeys_popup.keys")
21 -- Load Debian menu entries
22 local debian = require("debian.menu")
23 local has_fdo, freedesktop = pcall(require, "freedesktop")
25 local lain = require("lain")
26 local ccwidgets = require("cryptocoin_widgets")
27 local clocksarray = require("clocksarray")
28 local dbg = require("debugfunc")
29 local th = require("taghelpers")
33 -- Check if awesome encountered an error during startup and fell back to
34 -- another config (This code will only ever execute for the fallback config)
35 if awesome.startup_errors then
36 naughty.notify({ preset = naughty.config.presets.critical,
37 title = "Oops, there were errors during startup!",
38 text = awesome.startup_errors })
41 -- Handle runtime errors after startup
43 local in_error = false
44 awesome.connect_signal("debug::error", function (err)
45 -- Make sure we don't go into an endless error loop
46 if in_error then return end
49 naughty.notify({ preset = naughty.config.presets.critical,
50 title = "Oops, an error happened!",
51 text = tostring(err) })
57 -- {{{ Variable definitions
58 --xrdb.set_dpi(95, screen[1])
59 --xrdb.set_dpi(120, screen[2])
61 -- Themes define colours, icons, font and wallpapers.
62 beautiful.init(gears.filesystem.get_configuration_dir () .. "theme/theme.lua")
64 -- This is used later as the default terminal and editor to run.
65 terminal = "rxvt-unicode"
66 editor = os.getenv("EDITOR") or "editor"
67 editor_cmd = terminal .. " -e " .. editor
70 -- Usually, Mod4 is the key with a logo between Control and Alt.
71 -- If you do not like this or do not have such a key,
72 -- I suggest you to remap Mod4 to another key using xmodmap or other tools.
73 -- However, you can use another modifier like Mod1, but it may interact with others.
77 -- Table of layouts to cover with awful.layout.inc, order matters.
79 default = awful.layout.suit.fair,
80 default_horiz = awful.layout.suit.fair.horizontal,
81 tiled = awful.layout.suit.tile,
82 tiled_horiz = awful.layout.suit.tile.top,
83 floating = awful.layout.suit.floating,
84 maximised = awful.layout.suit.max
86 awful.layout.layouts = {
91 layouts.default_horiz,
96 -- {{{ Helper functions
97 local function client_menu_toggle_fn()
101 if instance and instance.wibox.visible then
105 instance = awful.menu.clients({ theme = { width = 250 } })
110 local function set_wallpaper(s)
112 if beautiful.wallpaper then
113 local wallpaper = beautiful.wallpaper
114 -- If wallpaper is a function, call it with the screen
115 if type(wallpaper) == "function" then
116 wallpaper = wallpaper(s)
118 gears.wallpaper.maximized(wallpaper, s, true)
122 local function move_mouse_to_area(a)
123 local coords = mouse.coords()
124 if (coords.x < a.x or
125 coords.x > (a.x+a.width) or
127 coords.y > (a.y+a.height)) then
131 y = a.y + a.height/2,
139 -- Create a launcher widget and a main menu
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}
148 local menu_awesome = { "awesome", myawesomemenu, beautiful.awesome_icon }
149 local menu_terminal = { "open terminal", terminal }
152 mymainmenu = freedesktop.menu.build({
153 before = { menu_awesome },
154 after = { menu_terminal }
157 mymainmenu = awful.menu({
160 { "Debian", debian.menu.Debian_menu.Debian },
167 mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon,
170 -- Menubar configuration
171 menubar.utils.terminal = terminal -- Set the terminal for applications that require it
175 --local spacer = wibox.widget {
176 -- color = beautiful.bg_minimize,
178 -- widget = wibox.widget.separator
180 local function make_spacer(text)
181 local spacer = wibox.widget.textbox()
182 spacer:set_text(text or " │ ")
186 -- Keyboard map indicator and switcher
187 mykeyboardlayout = awful.widget.keyboardlayout()
189 local lain_bat = lain.widget.bat({
190 batteries = {"BAT0", "BAT1"},
191 settings = function()
193 if bat_now.status == "Charging" then delim = "↑"
194 elseif bat_now.status == "Unknown" then delim = "٭" end
195 widget:set_text(bat_now.perc .. "% " .. delim .. " " .. bat_now.time)
199 -- Create a textclock widget
200 clocksarray = clocksarray.get_clocksarray("%a %d %b %H:%M:%S %Z", {
201 ["NZ"] = "Pacific/Auckland",
202 ["DE"] = "Europe/Berlin"
205 -- Create a wibox for each screen and add it
206 local taglist_buttons = gears.table.join(
207 awful.button({ }, 1, function(t) t:view_only() end),
208 awful.button({ modkey }, 1, function(t)
210 client.focus:move_to_tag(t)
213 awful.button({ }, 3, awful.tag.viewtoggle),
214 awful.button({ modkey }, 3, function(t)
216 client.focus:toggle_tag(t)
219 awful.button({ }, 4, function(t) awful.tag.viewnext(t.screen) end),
220 awful.button({ }, 5, function(t) awful.tag.viewprev(t.screen) end)
223 local tasklist_buttons = gears.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
229 -- Without this, the following
230 -- :isvisible() makes no sense
232 if not c:isvisible() and c.first_tag then
233 c.first_tag:view_only()
235 -- This will also un-minimize
236 -- the client, if needed
241 awful.button({ }, 3, client_menu_toggle_fn()),
242 awful.button({ }, 4, function ()
243 awful.client.focus.byidx(1)
245 awful.button({ }, 5, function ()
246 awful.client.focus.byidx(-1)
252 -- Re-set wallpaper when a screen's geometry changes (e.g. different resolution)
253 screen.connect_signal("property::geometry", set_wallpaper)
255 -- {{{ Basic setup for screens
256 local function screen_set_profile(s, profile)
258 s.outputstr = table.concat(gears.table.keys(s.outputs), "+")
259 s.name = s.profile .. "/" .. s.outputstr
262 awful.screen.connect_for_each_screen(function(s)
264 s.set_profile = screen_set_profile
269 -- Create a text widget to display screen name
270 s.namebox = wibox.container.background(wibox.widget.textbox(s.name),
271 beautiful.bg_minimize)
273 -- Create a promptbox for each screen
274 s.mypromptbox = awful.widget.prompt()
275 -- Create an imagebox widget which will contains an icon indicating which layout we're using.
276 -- We need one layoutbox per screen.
277 s.mylayoutbox = awful.widget.layoutbox(s)
278 s.mylayoutbox:buttons(awful.util.table.join(
279 awful.button({ }, 1, function () awful.layout.inc( 1) end),
280 awful.button({ }, 3, function () awful.layout.inc(-1) end),
281 awful.button({ }, 4, function () awful.layout.inc( 1) end),
282 awful.button({ }, 5, function () awful.layout.inc(-1) end)))
283 -- Create a taglist widget
284 s.mytaglist = awful.widget.taglist(s, awful.widget.taglist.filter.all, taglist_buttons)
286 -- Create a tasklist widget
287 s.mytasklist = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, tasklist_buttons)
289 -- Create the wibox, but only if there isn't one yet
290 if not s.mywibox then
291 s.mywibox = awful.wibar({ position = "top", screen = s })
294 -- Add widgets to the wibox
295 local right_widgets = gears.table.join(clocksarray, {
297 wibox.widget.systray(),
299 layout = wibox.layout.fixed.horizontal,
302 if s == screen.primary then
303 right_widgets = gears.table.join({
305 ccwidgets.btc_widget,
307 ccwidgets.eth_widget,
315 layout = wibox.layout.align.horizontal,
317 layout = wibox.layout.fixed.horizontal,
323 s.mytasklist, -- Middle widget
328 -- {{{ autorandr integration
329 local function find_screen_by_name(name)
331 if s.name == name then
337 local function get_target_screen_for_tag(tag)
338 local function primary_screen(reason)
339 local s = screen.primary
340 local msg = " → primary screen \"" .. s.name .. "\""
341 if reason then msg = msg .. " (" .. reason .. ")" end
346 print("Figuring out target screen for tag " .. tag.name .. "…")
348 if type(tag.targets) == "table" then
349 for _,target in ipairs(tag.targets) do
350 local s = find_screen_by_name(target)
352 print(" → screen " .. s.name)
356 elseif tag.targets == "primary" then
357 return primary_screen("explicit request")
359 return primary_screen("no matching target in " .. table.concat(tag.targets, ","))
361 return primary_screen("no targets specified")
365 local function move_tag_to_target_screen(tag)
366 tag.screen = get_target_screen_for_tag(tag)
369 local function move_tags_to_target_screens()
370 for _,tag in ipairs(root.tags()) do
371 move_tag_to_target_screen(tag)
375 tag.connect_signal("request::screen", function(t)
376 -- throw the tag onto any other screen, it'll get reassigned later when
377 -- a new profile has been processed.
379 if s ~= t.screen then
386 title = "Screen removed",
387 text = "Salvaged tab " .. t.name .. " onto screen " .. t.screen.name,
391 function handle_new_autorandr_profile(newprofile)
392 -- The main idea here is that autorandr invokes this via awesome-client
393 -- after switching to a new profile. Awesome will have already set up all
394 -- the screens long before this function is called. Therefore, we just do
395 -- the necessary modifications to the existing screens, and move tags
398 if not newprofile then
399 error("Missing new profile name")
403 preset = naughty.config.presets.low,
404 title = "New autorandr profile",
405 text = "Reconfiguring for profile <b>" .. newprofile .. "</b>",
409 s:set_profile(newprofile)
411 move_tags_to_target_screens()
414 local function initialise_to_autorandr_profile()
418 local function process_line(line)
419 if profile then return end
420 local match = string.match(line, "^([^%s]+) %(detected%)")
426 local function output_done()
428 error("autorandr detected no profile")
431 handle_new_autorandr_profile(profile)
434 local function handle_exit(reason, code)
435 if not (reason == "exit" and code == 0) then
436 error("autorandr error: " .. reason .. ": " .. tostring(code))
440 awful.spawn.with_line_callback('autorandr', {
441 stdout = process_line,
442 output_done = output_done,
446 awesome.connect_signal("startup", initialise_to_autorandr_profile)
453 local default_tag = {
456 layout = layouts.default,
460 local default_tags = {}
463 for k,v in pairs(default_tag) do
464 default_tags[i][k] = v
466 default_tags[i].name = tostring(i)
468 default_tags[1].selected = true
470 default_tags = gears.table.join(default_tags, {
475 master_width_factor = 0.33,
476 layout = layouts.tiled,
478 exec_once = { terminal .. " -name irc -e env MOSH_TITLE_NOPREFIX=true mosh -4 -- irc-host tmux new -As irc irssi" },
479 instance = { "irc" },
480 targets = { "catalyst/eDP1", "mtvic/eDP1", "gauting/eDP1", "lehel/DisplayPort-2" },
486 master_width_factor = 0.67,
487 layout = layouts.tiled,
489 exec_once = { "revolt" },
490 instance = { "Revolt" },
491 targets = { "catalyst/eDP1", "mtvic/eDP1", "gauting/eDP1", "lehel/DisplayPort-2" },
497 layout = layouts.floating,
505 layout = layouts.default,
506 exec_once = { "thunderbird" },
507 class = { "Thunderbird" },
508 targets = { "catalyst/HDMI1", "mtvic/eDP1", "gauting/eDP1", "lehel/DisplayPort-1" },
514 layout = layouts.default,
515 exec_once = { "chromium" },
516 class = { "Chromium" },
517 targets = { "catalyst/HDMI1", "mtvic/eDP1", "gauting/eDP1", "lehel/DisplayPort-1" },
523 layout = layouts.default,
524 exec_once = { "firefox" },
525 class = { "Firefox" },
526 targets = { "catalyst/HDMI1", "mtvic/eDP1", "gauting/eDP1", "lehel/DisplayPort-1" },
530 if not tyrannical then
532 for _,t in ipairs(default_tags) do
534 t.screen = t.screen or screen.primary
535 t.layout = t.layout or layouts.default
536 local newt = th.add_tag(t.name, t, false)
540 else -- {{{ tyrannical is loaded
541 tyrannical.settings.default_layout = layouts.default
542 tyrannical.settings.master_width_factor = 0.5
543 tyrannical.settings.block_children_focus_stealing = true
544 tyrannical.settings.group_children = true
546 tyrannical.tags = default_tags
548 tyrannical.properties.size_hints_honor = { URxvt = false }
550 --XX---- Ignore the tag "exclusive" property for the following clients (matched by classes)
551 --XX--tyrannical.properties.intrusive = {
552 --XX-- "ksnapshot" , "pinentry" , "gtksu" , "kcalc" , "xcalc" ,
553 --XX-- "feh" , "Gradient editor", "About KDE" , "Paste Special", "Background color" ,
554 --XX-- "kcolorchooser" , "plasmoidviewer" , "Xephyr" , "kruler" , "plasmaengineexplorer",
557 --XX---- Ignore the tiled layout for the matching clients
558 --XX--tyrannical.properties.floating = {
559 --XX-- "MPlayer" , "pinentry" , "ksnapshot" , "pinentry" , "gtksu" ,
560 --XX-- "xine" , "feh" , "kmix" , "kcalc" , "xcalc" ,
561 --XX-- "yakuake" , "Select Color$" , "kruler" , "kcolorchooser", "Paste Special" ,
562 --XX-- "New Form" , "Insert Picture" , "kcharselect", "mythfrontend" , "plasmoidviewer"
565 --XX---- Make the matching clients (by classes) on top of the default layout
566 --XX--tyrannical.properties.ontop = {
567 --XX-- "Xephyr" , "ksnapshot" , "kruler"
570 --XX---- Force the matching clients (by classes) to be centered on the screen on init
571 --XX--tyrannical.properties.centered = {
578 -- {{{ Mouse bindings
579 root.buttons(gears.table.join(
580 awful.button({ }, 3, function () mymainmenu:toggle() end),
581 awful.button({ }, 4, awful.tag.viewnext),
582 awful.button({ }, 5, awful.tag.viewprev)
588 local function toggle_tag_by_name(tagname, exclusive)
590 local t = awful.tag.find_by_name(nil, tagname)
595 awful.tag.viewtoggle(t)
597 cf = awful.client.getmaster(t.screen)
605 globalkeys = gears.table.join(
606 awful.key({ modkey, }, "s", hotkeys_popup.show_help,
607 {description="show help", group="awesome"}),
608 awful.key({ modkey, }, "Left", awful.tag.viewprev,
609 {description = "view previous", group = "tag"}),
610 awful.key({ modkey, }, "Right", awful.tag.viewnext,
611 {description = "view next", group = "tag"}),
612 awful.key({ modkey, }, "Escape", awful.tag.history.restore,
613 {description = "go back", group = "tag"}),
615 awful.key({ modkey, }, "k",
617 awful.client.focus.byidx( 1)
619 {description = "focus next by index", group = "client"}
621 awful.key({ modkey, }, "j",
623 awful.client.focus.byidx(-1)
625 {description = "focus previous by index", group = "client"}
628 -- Layout manipulation
629 awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( 1) end,
630 {description = "swap with next client by index", group = "client"}),
631 awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( -1) end,
632 {description = "swap with previous client by index", group = "client"}),
633 awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative( 1) end,
634 {description = "focus the next screen", group = "screen"}),
635 awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative(-1) end,
636 {description = "focus the previous screen", group = "screen"}),
637 awful.key({ modkey, "Shift" }, "Return", awful.client.urgent.jumpto,
638 {description = "jump to urgent client", group = "client"}),
639 awful.key({ modkey, }, "Tab",
641 awful.client.focus.history.previous()
646 {description = "go back", group = "client"}),
649 awful.key({ modkey, }, "Return", function () awful.spawn(terminal) end,
650 {description = "open a terminal", group = "launcher"}),
651 awful.key({ modkey, }, "r", function()
652 package.loaded.rc = nil
655 {description = "reload rc.lua", group = "awesome"}),
656 awful.key({ modkey, "Control" }, "r", awesome.restart,
657 {description = "reload awesome", group = "awesome"}),
658 awful.key({ modkey, "Shift" }, "q", awesome.quit,
659 {description = "quit awesome", group = "awesome"}),
661 awful.key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end,
662 {description = "increase master width factor", group = "layout"}),
663 awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end,
664 {description = "decrease master width factor", group = "layout"}),
665 awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1, nil, true) end,
666 {description = "increase the number of master clients", group = "layout"}),
667 awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1, nil, true) end,
668 {description = "decrease the number of master clients", group = "layout"}),
669 awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1, nil, true) end,
670 {description = "increase the number of columns", group = "layout"}),
671 awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1, nil, true) end,
672 {description = "decrease the number of columns", group = "layout"}),
673 awful.key({ modkey, }, "space", function () awful.layout.inc( 1) end,
674 {description = "select next", group = "layout"}),
675 awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(-1) end,
676 {description = "select previous", group = "layout"}),
678 awful.key({ modkey, "Control" }, "n",
680 local c = awful.client.restore()
681 -- Focus restored client
687 {description = "restore minimized", group = "client"}),
690 awful.key({ cmdkey }, "r",
692 local widget = awful.screen.focused().mypromptbox.widget
693 local function spawn(command, args)
694 gears.debug.dump(args)
695 awful.spawn(command, args)
700 bg_cursor = '#ff0000',
702 history_path = awful.util.get_cache_dir() .. "/history",
703 completion_callback = awful.completion.shell,
705 -- Replace the 'normal' Return with a custom one
706 {{ }, 'Return', function(command)
709 -- Spawn method to spawn in the current tag
710 {{'Mod1' }, 'Return', function(command)
713 tag = mouse.screen.selected_tag
716 -- Spawn in the current tag as floating and on top
717 {{'Shift' }, 'Return', function(command)
721 tag = mouse.screen.selected_tag
724 -- Spawn in a new tag
725 {{'Control'}, 'Return', function(command)
728 layout = layouts.default,
733 {{ }, 'Escape', function(_) return end},
737 {description = "run prompt", group = "launcher"}),
739 awful.key({ modkey }, "x",
743 bg_cursor = '#ff0000',
744 textbox = awful.screen.focused().mypromptbox.widget,
745 exe_callback = awful.util.eval,
746 history_path = awful.util.get_cache_dir() .. "/history_eval"
749 {description = "lua execute prompt", group = "awesome"}),
751 awful.key({ modkey }, "w", function() menubar.show() end,
752 {description = "show the menubar", group = "launcher"}),
755 awful.key({ modkey, }, "a", function()
756 th.add_tag(nil, {layout=layouts.default} ,true)
758 {description = "add a tag", group = "tag"}),
759 awful.key({ modkey, }, "d", th.delete_tag,
760 {description = "delete the current tag", group = "tag"}),
761 awful.key({ modkey, "Shift", }, "a", function()
762 th.move_to_new_tag(nil,nil,true,true,true)
764 {description = "add a volatile tag with the focused client", group = "tag"}),
765 awful.key({ modkey, "Shift", "Control" }, "a", function()
766 th.move_to_new_tag(nil,nil,false,true,true)
768 {description = "add a permanent tag with the focused client", group = "tag"}),
769 awful.key({ modkey, "Mod1" }, "a", th.copy_tag,
770 {description = "create a copy of the current tag", group = "tag"}),
771 awful.key({ modkey, "Control" }, "a", th.rename_tag,
772 {description = "rename the current tag", group = "tag"}),
773 awful.key({ modkey, "Control", "Shift", "Mod1" }, "a", th.collect_orphan_clients_to_tag,
774 {description = "collect all orphaned clients", group = "client"}),
776 awful.key({ modkey }, "y", toggle_tag_by_name("irc", true),
777 {description = "view tag 'irc'", group = "tag"}),
778 awful.key({ modkey, "Control" }, "y", toggle_tag_by_name("irc"),
779 {description = "toggle tag 'irc'", group = "tag"}),
780 awful.key({ modkey }, "u", toggle_tag_by_name("[m]", true),
781 {description = "view tag '[m]'", group = "tag"}),
782 awful.key({ modkey, "Control" }, "u", toggle_tag_by_name("[m]"),
783 {description = "toggle tag '[m]'", group = "tag"}),
784 awful.key({ modkey }, "i", toggle_tag_by_name("cal", true),
785 {description = "view tag 'cal'", group = "tag"}),
786 awful.key({ modkey, "Control" }, "i", toggle_tag_by_name("cal"),
787 {description = "toggle tag 'cal'", group = "tag"}),
788 awful.key({ modkey }, "o", toggle_tag_by_name("chr", true),
789 {description = "view tag 'chr'", group = "tag"}),
790 awful.key({ modkey, "Control" }, "o", toggle_tag_by_name("chr"),
791 {description = "toggle tag 'chr'", group = "tag"}),
792 awful.key({ modkey }, "p", toggle_tag_by_name("ffx", true),
793 {description = "view tag 'ff'", group = "tag"}),
794 awful.key({ modkey, "Control" }, "p", toggle_tag_by_name("ffx"),
795 {description = "toggle tag 'ff'", group = "tag"}),
798 clientkeys = gears.table.join(
799 awful.key({ modkey, }, "f",
801 c.fullscreen = not c.fullscreen
804 {description = "toggle fullscreen", group = "client"}),
805 awful.key({ modkey, "Shift" }, "c", function (c) c:kill() end,
806 {description = "close", group = "client"}),
807 awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle ,
808 {description = "toggle floating", group = "client"}),
809 awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end,
810 {description = "move to master", group = "client"}),
811 awful.key({ modkey, }, "t", function (c) c.ontop = not c.ontop end,
812 {description = "toggle keep on top", group = "client"}),
813 awful.key({ modkey, }, "n",
815 -- The client currently has the input focus, so it cannot be
816 -- minimized, since minimized clients can't have the focus.
819 {description = "minimize", group = "client"}),
820 awful.key({ modkey, }, "m",
822 c.maximized = not c.maximized
823 c.maximized_horizontal = false
824 c.maximized_vertical = false
827 {description = "(un)maximize", group = "client"}),
828 awful.key({ modkey, "Control" }, "m",
830 c.maximized_vertical = not c.maximized_vertical
833 {description = "(un)maximize vertically", group = "client"}),
834 awful.key({ modkey, "Shift" }, "m",
836 c.maximized_horizontal = not c.maximized_horizontal
839 {description = "(un)maximize horizontally", group = "client"})
842 -- Bind all key numbers to tags.
843 -- Be careful: we use keycodes to make it work on any keyboard layout.
844 -- This should map on the top row of your keyboard, usually 1 to 9.
846 globalkeys = gears.table.join(globalkeys,
848 awful.key({ modkey }, "#" .. i + 9, toggle_tag_by_name(tostring(i), true),
849 {description = "view tag #"..i, group = "tag"}),
850 -- Toggle tag display.
851 awful.key({ modkey, "Control" }, "#" .. i + 9, toggle_tag_by_name(tostring(i)),
852 {description = "toggle tag #" .. i, group = "tag"}),
853 -- Move client to tag.
854 awful.key({ modkey, "Shift" }, "#" .. i + 9,
857 local tag = awful.tag.find_by_name(screen.primary, tostring(i))
859 client.focus:move_to_tag(tag)
863 {description = "move focused client to tag #"..i, group = "tag"}),
864 -- Toggle tag on focused client.
865 awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
868 local tag = awful.tag.find_by_name(screen.primary, tostring(i))
870 client.focus:toggle_tag(tag)
874 {description = "toggle focused client on tag #" .. i, group = "tag"})
878 clientbuttons = gears.table.join(
879 awful.button({ }, 1, function (c) client.focus = c; c:raise() end),
880 awful.button({ modkey }, 1, awful.mouse.client.move),
881 awful.button({ modkey }, 3, awful.mouse.client.resize))
884 globalkeys = awful.util.table.join(globalkeys,
885 awful.key({ cmdkey }, "n", function () awful.spawn("firefox") end),
886 awful.key({ cmdkey }, "m", function () awful.spawn("chromium --enable-remote-extensions") end),
887 awful.key({ cmdkey }, "y", function () awful.spawn(terminal .. " -e python") end),
888 awful.key({ cmdkey }, "c", function () awful.spawn("thunderbird") end),
889 awful.key({ cmdkey }, "g", function () awful.spawn("gscan2pdf") end),
890 awful.key({ cmdkey }, "v", function () awful.spawn("virt-manager") end),
891 awful.key({ cmdkey }, "l", function () awful.spawn("libreoffice") end),
892 awful.key({ cmdkey }, "f", function () awful.spawn("thunar") end),
893 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),
894 awful.key({ cmdkey }, "x", function ()
895 awful.spawn("/usr/bin/xscreensaver -no-capture-stderr")
896 os.execute("sleep 5")
897 awful.spawn("xscreensaver-command -lock")
899 awful.key({ cmdkey, "Shift" }, "x", function () awful.spawn("xscreensaver-command -exit") end),
902 awful.key(nil, "XF86ScreenSaver", function () awful.spawn("xset dpms force off") end),
903 awful.key(nil, "XF86AudioMute", function () awful.spawn("pactl set-sink-mute 0 toggle") end),
904 awful.key({ cmdkey }, "End", function () awful.spawn("pactl set-sink-mute 0 toggle") end),
905 awful.key(nil, "XF86AudioLowerVolume", function () awful.spawn("pactl set-sink-volume 0 -2%") end),
906 awful.key({ cmdkey }, "Next", function () awful.spawn("pactl set-sink-volume 0 -2%") end),
907 awful.key(nil, "XF86AudioRaiseVolume", function () awful.spawn("pactl set-sink-volume 0 +2%") end),
908 awful.key({ cmdkey }, "Prior", function () awful.spawn("pactl set-sink-volume 0 +2%") end),
909 awful.key(nil, "XF86AudioMicMute", function () awful.spawn("pactl set-source-mute 1 toggle") end),
910 awful.key({ cmdkey }, "Home", function () awful.spawn("pactl set-source-mute 1 toggle") end),
911 awful.key(nil, "XF86MonBrightnessDown", function () awful.spawn("xbacklight -dec 5%") end),
912 awful.key(nil, "XF86MonBrightnessUp", function () awful.spawn("xbacklight -inc 5%") end),
913 awful.key(nil, "XF86Display", function () awful.spawn("autorandr --change --force"); initialise_to_autorandr_profile() end),
914 awful.key(nil, "XF86WLAN", function () awful.spawn("") end),
915 awful.key(nil, "XF86Tools", function () awful.spawn("") end),
916 awful.key(nil, "XF86Search", function () awful.spawn("") end),
917 awful.key(nil, "XF86LaunchA", function () awful.spawn("") end),
918 awful.key(nil, "XF86Explorer", function () awful.spawn("") end),
920 awful.key({ cmdkey }, "Left", function () awful.spawn("xmms2 prev") end),
921 awful.key({ cmdkey }, "Right", function () awful.spawn("xmms2 next") end),
922 awful.key({ cmdkey }, "space", function () awful.spawn("xmms2 toggle") end),
923 awful.key({ cmdkey }, "\\", function () run_output_notify("xmms2 list") end)
926 function run_output_notify(cmd)
927 awful.spawn.easy_async(cmd, function(stdout, stderr, reason, exit_code)
929 preset = naughty.config.presets.low,
930 title = "XMMS2 playlist",
936 root.keys(globalkeys)
940 -- Rules to apply to new clients (through the "manage" signal).
942 local function float_client_in_the_middle_with_margins(client, leftright, topbottom)
943 local wa = client.screen.workarea
945 client.y = wa.y + topbottom
946 client.height = wa.height - 2*topbottom
948 client.y = wa.y + (wa.height - client.height)/2
951 client.x = wa.x + leftright
952 client.width = wa.width - 2*leftright
954 client.x = wa.x + (wa.width - client.width)/2
958 local function move_to_tag_by_name(s, tagname)
960 local t = awful.tag.find_by_name(s, tagname)
962 error("No tag by the name of " .. tagname)
969 awful.rules.rules = {
970 -- All clients will match this rule.
972 properties = { border_width = beautiful.border_width,
973 border_color = beautiful.border_normal,
974 focus = awful.client.focus.filter,
977 buttons = clientbuttons,
978 screen = awful.screen.preferred,
979 placement = awful.placement.no_overlap+awful.placement.no_offscreen,
983 { rule = { type = "dialog" },
984 properties = { floating = true,
989 --switchtotag = true,
990 placement = awful.placement.centered
993 { rule = { class = "URxvt" },
994 properties = { size_hints_honor = false, }
996 { rule = { instance = "irc" },
997 callback = move_to_tag_by_name(nil, "irc"),
999 { rule = { class = "Revolt" },
1000 callback = move_to_tag_by_name(nil, "[m]"),
1002 { rule = { class = "Firefox" },
1003 callback = move_to_tag_by_name(nil, "ffx"),
1005 { rule = { class = "Chromium" },
1006 callback = move_to_tag_by_name(nil, "chr"),
1008 { rule = { class = "Thunderbird" },
1009 callback = move_to_tag_by_name(nil, "cal"),
1011 { rule_any = { class = {
1017 properties = { floating = true,
1020 placement = awful.placement.centered,
1023 { rule_any = { instance = {
1027 properties = { floating = true,
1030 placement = awful.placement.centered,
1033 -- { rule_any = { class = {
1041 -- properties = { new_tag = {
1042 -- layout = layouts.maximised,
1045 -- switchtotag = true,
1049 --XX-- { rule = { class = "Gscan2pdf" },
1050 --XX-- properties = {
1051 --XX-- switchtotag = true
1053 --XX-- callback = move_to_tag(1, 5)
1055 --XX-- { rule = { name = "gscan2pdf .*" },
1056 --XX-- properties = {
1057 --XX-- floating = false,
1060 --XX-- { rule = { class = "Thunar", type = "normal" },
1061 --XX-- properties = {
1062 --XX-- floating = false,
1065 --XX-- { rule = { class = "Pinentry", instance = "pinentry" },
1066 --XX-- properties = {
1067 --XX-- floating = true,
1070 --XX-- { rule = { class = "Gxmessage" },
1071 --XX-- properties = {
1072 --XX-- floating = true,
1080 -- Signal function to execute when a new client appears.
1081 client.connect_signal("manage", function (c)
1082 -- Set the windows at the slave,
1083 -- i.e. put it at the end of others instead of setting it master.
1084 -- if not awesome.startup then awful.client.setslave(c) end
1086 if awesome.startup and
1087 not c.size_hints.user_position
1088 and not c.size_hints.program_position then
1089 -- Prevent clients from being unreachable after screen count changes.
1090 awful.placement.no_offscreen(c)
1093 c.maximized_horizontal = false
1094 c.maximized_vertical = false
1097 -- Add a titlebar if titlebars_enabled is set to true in the rules.
1098 client.connect_signal("request::titlebars", function(c)
1099 -- buttons for the titlebar
1100 local buttons = gears.table.join(
1101 awful.button({ }, 1, function()
1104 awful.mouse.client.move(c)
1106 awful.button({ }, 3, function()
1109 awful.mouse.client.resize(c)
1113 awful.titlebar(c) : setup {
1115 awful.titlebar.widget.iconwidget(c),
1117 layout = wibox.layout.fixed.horizontal
1122 widget = awful.titlebar.widget.titlewidget(c)
1125 layout = wibox.layout.flex.horizontal
1128 awful.titlebar.widget.floatingbutton (c),
1129 awful.titlebar.widget.maximizedbutton(c),
1130 awful.titlebar.widget.stickybutton (c),
1131 awful.titlebar.widget.ontopbutton (c),
1132 awful.titlebar.widget.closebutton (c),
1133 layout = wibox.layout.fixed.horizontal()
1135 layout = wibox.layout.align.horizontal
1139 -- Enable sloppy focus, so that focus follows mouse.
1140 client.connect_signal("mouse::enter", function(c)
1141 if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
1142 and awful.client.focus.filter(c) then
1147 client.connect_signal("focus", function(c)
1148 c.border_color = beautiful.border_focus
1150 client.connect_signal("unfocus", function(c)
1151 c.border_color = beautiful.border_normal
1154 awful.ewmh.add_activate_filter(function(c, context, hints)
1155 if context == "ewmh" then
1156 if (c.class == "Firefox-esr" or c.class == "Firefox") then
1162 client.connect_signal("request::activate", function(c, context, hints)
1163 if gears.table.hasitem({
1164 "client.focus.byidx",
1166 "autofocus.check_focus",
1170 gears.timer.delayed_call(function()
1171 -- we need a delayed call so that we execute *after layout changes
1172 if hints.raise and c == client.focus and client.focus:isvisible() then
1173 move_mouse_to_area(client.focus)
1179 -- vim:ft=lua:sw=4:sts=4:ts=4:et