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()
417 local function process_line(line)
418 if profile then return end
419 local match = string.match(line, "^([^%s]+) %(detected%)$")
425 local function output_done()
427 error("autorandr detected no profile")
430 handle_new_autorandr_profile(profile)
433 local function handle_exit(reason, code)
434 if not (reason == "exit" and code == 0) then
435 error("autorandr error: " .. reason .. ": " .. tostring(code))
439 awful.spawn.with_line_callback('autorandr', {
440 stderr = process_line,
441 output_done = output_done,
445 awesome.connect_signal("startup", initialise_to_autorandr_profile)
452 local default_tag = {
455 layout = layouts.default,
459 local default_tags = {}
462 for k,v in pairs(default_tag) do
463 default_tags[i][k] = v
465 default_tags[i].name = tostring(i)
467 default_tags[1].selected = true
469 default_tags = gears.table.join(default_tags, {
474 master_width_factor = 0.33,
475 layout = layouts.tiled,
477 exec_once = { terminal .. " -name irc -e env MOSH_TITLE_NOPREFIX=true mosh -4 -- irc-host tmux new -As irc irssi" },
478 instance = { "irc" },
479 targets = { "catalyst/eDP1", "mtvic/eDP1", "lehel/DisplayPort-2" },
485 master_width_factor = 0.67,
486 layout = layouts.tiled,
488 exec_once = { "revolt" },
489 instance = { "Revolt" },
490 targets = { "catalyst/eDP1", "mtvic/eDP1", "lehel/DisplayPort-2" },
496 layout = layouts.floating,
504 layout = layouts.default,
505 exec_once = { "thunderbird" },
506 class = { "Thunderbird" },
507 targets = { "catalyst/HDMI1", "mtvic/eDP1", "lehel/DisplayPort-1" },
513 layout = layouts.default,
514 exec_once = { "chromium" },
515 class = { "Chromium" },
516 targets = { "catalyst/HDMI1", "mtvic/eDP1", "lehel/DisplayPort-1" },
522 layout = layouts.default,
523 exec_once = { "firefox" },
524 class = { "Firefox" },
525 targets = { "catalyst/HDMI1", "mtvic/eDP1", "lehel/DisplayPort-1" },
529 if not tyrannical then
531 for _,t in ipairs(default_tags) do
533 t.screen = t.screen or screen.primary
534 t.layout = t.layout or layouts.default
535 local newt = th.add_tag(t.name, t, false)
539 else -- {{{ tyrannical is loaded
540 tyrannical.settings.default_layout = layouts.default
541 tyrannical.settings.master_width_factor = 0.5
542 tyrannical.settings.block_children_focus_stealing = true
543 tyrannical.settings.group_children = true
545 tyrannical.tags = default_tags
547 tyrannical.properties.size_hints_honor = { URxvt = false }
549 --XX---- Ignore the tag "exclusive" property for the following clients (matched by classes)
550 --XX--tyrannical.properties.intrusive = {
551 --XX-- "ksnapshot" , "pinentry" , "gtksu" , "kcalc" , "xcalc" ,
552 --XX-- "feh" , "Gradient editor", "About KDE" , "Paste Special", "Background color" ,
553 --XX-- "kcolorchooser" , "plasmoidviewer" , "Xephyr" , "kruler" , "plasmaengineexplorer",
556 --XX---- Ignore the tiled layout for the matching clients
557 --XX--tyrannical.properties.floating = {
558 --XX-- "MPlayer" , "pinentry" , "ksnapshot" , "pinentry" , "gtksu" ,
559 --XX-- "xine" , "feh" , "kmix" , "kcalc" , "xcalc" ,
560 --XX-- "yakuake" , "Select Color$" , "kruler" , "kcolorchooser", "Paste Special" ,
561 --XX-- "New Form" , "Insert Picture" , "kcharselect", "mythfrontend" , "plasmoidviewer"
564 --XX---- Make the matching clients (by classes) on top of the default layout
565 --XX--tyrannical.properties.ontop = {
566 --XX-- "Xephyr" , "ksnapshot" , "kruler"
569 --XX---- Force the matching clients (by classes) to be centered on the screen on init
570 --XX--tyrannical.properties.centered = {
577 -- {{{ Mouse bindings
578 root.buttons(gears.table.join(
579 awful.button({ }, 3, function () mymainmenu:toggle() end),
580 awful.button({ }, 4, awful.tag.viewnext),
581 awful.button({ }, 5, awful.tag.viewprev)
587 local function toggle_tag_by_name(tagname, exclusive)
589 local t = awful.tag.find_by_name(nil, tagname)
594 awful.tag.viewtoggle(t)
596 cf = awful.client.getmaster(t.screen)
604 globalkeys = gears.table.join(
605 awful.key({ modkey, }, "s", hotkeys_popup.show_help,
606 {description="show help", group="awesome"}),
607 awful.key({ modkey, }, "Left", awful.tag.viewprev,
608 {description = "view previous", group = "tag"}),
609 awful.key({ modkey, }, "Right", awful.tag.viewnext,
610 {description = "view next", group = "tag"}),
611 awful.key({ modkey, }, "Escape", awful.tag.history.restore,
612 {description = "go back", group = "tag"}),
614 awful.key({ modkey, }, "k",
616 awful.client.focus.byidx( 1)
618 {description = "focus next by index", group = "client"}
620 awful.key({ modkey, }, "j",
622 awful.client.focus.byidx(-1)
624 {description = "focus previous by index", group = "client"}
627 -- Layout manipulation
628 awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( 1) end,
629 {description = "swap with next client by index", group = "client"}),
630 awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( -1) end,
631 {description = "swap with previous client by index", group = "client"}),
632 awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative( 1) end,
633 {description = "focus the next screen", group = "screen"}),
634 awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative(-1) end,
635 {description = "focus the previous screen", group = "screen"}),
636 awful.key({ modkey, "Shift" }, "Return", awful.client.urgent.jumpto,
637 {description = "jump to urgent client", group = "client"}),
638 awful.key({ modkey, }, "Tab",
640 awful.client.focus.history.previous()
645 {description = "go back", group = "client"}),
648 awful.key({ modkey, }, "Return", function () awful.spawn(terminal) end,
649 {description = "open a terminal", group = "launcher"}),
650 awful.key({ modkey, }, "r", function()
651 package.loaded.rc = nil
654 {description = "reload rc.lua", group = "awesome"}),
655 awful.key({ modkey, "Control" }, "r", awesome.restart,
656 {description = "reload awesome", group = "awesome"}),
657 awful.key({ modkey, "Shift" }, "q", awesome.quit,
658 {description = "quit awesome", group = "awesome"}),
660 awful.key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end,
661 {description = "increase master width factor", group = "layout"}),
662 awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end,
663 {description = "decrease master width factor", group = "layout"}),
664 awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1, nil, true) end,
665 {description = "increase the number of master clients", group = "layout"}),
666 awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1, nil, true) end,
667 {description = "decrease the number of master clients", group = "layout"}),
668 awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1, nil, true) end,
669 {description = "increase the number of columns", group = "layout"}),
670 awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1, nil, true) end,
671 {description = "decrease the number of columns", group = "layout"}),
672 awful.key({ modkey, }, "space", function () awful.layout.inc( 1) end,
673 {description = "select next", group = "layout"}),
674 awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(-1) end,
675 {description = "select previous", group = "layout"}),
677 awful.key({ modkey, "Control" }, "n",
679 local c = awful.client.restore()
680 -- Focus restored client
686 {description = "restore minimized", group = "client"}),
689 awful.key({ cmdkey }, "r",
691 local widget = awful.screen.focused().mypromptbox.widget
692 local function spawn(command, args)
693 gears.debug.dump(args)
694 awful.spawn(command, args)
699 bg_cursor = '#ff0000',
701 history_path = awful.util.get_cache_dir() .. "/history",
702 completion_callback = awful.completion.shell,
704 -- Replace the 'normal' Return with a custom one
705 {{ }, 'Return', function(command)
708 -- Spawn method to spawn in the current tag
709 {{'Mod1' }, 'Return', function(command)
712 tag = mouse.screen.selected_tag
715 -- Spawn in the current tag as floating and on top
716 {{'Shift' }, 'Return', function(command)
720 tag = mouse.screen.selected_tag
723 -- Spawn in a new tag
724 {{'Control'}, 'Return', function(command)
727 layout = layouts.default,
732 {{ }, 'Escape', function(_) return end},
736 {description = "run prompt", group = "launcher"}),
738 awful.key({ modkey }, "x",
742 bg_cursor = '#ff0000',
743 textbox = awful.screen.focused().mypromptbox.widget,
744 exe_callback = awful.util.eval,
745 history_path = awful.util.get_cache_dir() .. "/history_eval"
748 {description = "lua execute prompt", group = "awesome"}),
750 awful.key({ modkey }, "w", function() menubar.show() end,
751 {description = "show the menubar", group = "launcher"}),
754 awful.key({ modkey, }, "a", function()
755 th.add_tag(nil, {layout=layouts.default} ,true)
757 {description = "add a tag", group = "tag"}),
758 awful.key({ modkey, }, "d", th.delete_tag,
759 {description = "delete the current tag", group = "tag"}),
760 awful.key({ modkey, "Shift", }, "a", function()
761 th.move_to_new_tag(nil,nil,true,true,true)
763 {description = "add a volatile tag with the focused client", group = "tag"}),
764 awful.key({ modkey, "Shift", "Control" }, "a", function()
765 th.move_to_new_tag(nil,nil,false,true,true)
767 {description = "add a permanent tag with the focused client", group = "tag"}),
768 awful.key({ modkey, "Mod1" }, "a", th.copy_tag,
769 {description = "create a copy of the current tag", group = "tag"}),
770 awful.key({ modkey, "Control" }, "a", th.rename_tag,
771 {description = "rename the current tag", group = "tag"}),
772 awful.key({ modkey, "Control", "Shift", "Mod1" }, "a", th.collect_orphan_clients_to_tag,
773 {description = "collect all orphaned clients", group = "client"}),
775 awful.key({ modkey }, "y", toggle_tag_by_name("irc", true),
776 {description = "view tag 'irc'", group = "tag"}),
777 awful.key({ modkey, "Control" }, "y", toggle_tag_by_name("irc"),
778 {description = "toggle tag 'irc'", group = "tag"}),
779 awful.key({ modkey }, "u", toggle_tag_by_name("[m]", true),
780 {description = "view tag '[m]'", group = "tag"}),
781 awful.key({ modkey, "Control" }, "u", toggle_tag_by_name("[m]"),
782 {description = "toggle tag '[m]'", group = "tag"}),
783 awful.key({ modkey }, "i", toggle_tag_by_name("cal", true),
784 {description = "view tag 'cal'", group = "tag"}),
785 awful.key({ modkey, "Control" }, "i", toggle_tag_by_name("cal"),
786 {description = "toggle tag 'cal'", group = "tag"}),
787 awful.key({ modkey }, "o", toggle_tag_by_name("chr", true),
788 {description = "view tag 'chr'", group = "tag"}),
789 awful.key({ modkey, "Control" }, "o", toggle_tag_by_name("chr"),
790 {description = "toggle tag 'chr'", group = "tag"}),
791 awful.key({ modkey }, "p", toggle_tag_by_name("ffx", true),
792 {description = "view tag 'ff'", group = "tag"}),
793 awful.key({ modkey, "Control" }, "p", toggle_tag_by_name("ffx"),
794 {description = "toggle tag 'ff'", group = "tag"}),
797 clientkeys = gears.table.join(
798 awful.key({ modkey, }, "f",
800 c.fullscreen = not c.fullscreen
803 {description = "toggle fullscreen", group = "client"}),
804 awful.key({ modkey, "Shift" }, "c", function (c) c:kill() end,
805 {description = "close", group = "client"}),
806 awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle ,
807 {description = "toggle floating", group = "client"}),
808 awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end,
809 {description = "move to master", group = "client"}),
810 awful.key({ modkey, }, "t", function (c) c.ontop = not c.ontop end,
811 {description = "toggle keep on top", group = "client"}),
812 awful.key({ modkey, }, "n",
814 -- The client currently has the input focus, so it cannot be
815 -- minimized, since minimized clients can't have the focus.
818 {description = "minimize", group = "client"}),
819 awful.key({ modkey, }, "m",
821 c.maximized = not c.maximized
822 c.maximized_horizontal = false
823 c.maximized_vertical = false
826 {description = "(un)maximize", group = "client"}),
827 awful.key({ modkey, "Control" }, "m",
829 c.maximized_vertical = not c.maximized_vertical
832 {description = "(un)maximize vertically", group = "client"}),
833 awful.key({ modkey, "Shift" }, "m",
835 c.maximized_horizontal = not c.maximized_horizontal
838 {description = "(un)maximize horizontally", group = "client"})
841 -- Bind all key numbers to tags.
842 -- Be careful: we use keycodes to make it work on any keyboard layout.
843 -- This should map on the top row of your keyboard, usually 1 to 9.
845 globalkeys = gears.table.join(globalkeys,
847 awful.key({ modkey }, "#" .. i + 9, toggle_tag_by_name(tostring(i), true),
848 {description = "view tag #"..i, group = "tag"}),
849 -- Toggle tag display.
850 awful.key({ modkey, "Control" }, "#" .. i + 9, toggle_tag_by_name(tostring(i)),
851 {description = "toggle tag #" .. i, group = "tag"}),
852 -- Move client to tag.
853 awful.key({ modkey, "Shift" }, "#" .. i + 9,
856 local tag = awful.tag.find_by_name(screen.primary, tostring(i))
858 client.focus:move_to_tag(tag)
862 {description = "move focused client to tag #"..i, group = "tag"}),
863 -- Toggle tag on focused client.
864 awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
867 local tag = awful.tag.find_by_name(screen.primary, tostring(i))
869 client.focus:toggle_tag(tag)
873 {description = "toggle focused client on tag #" .. i, group = "tag"})
877 clientbuttons = gears.table.join(
878 awful.button({ }, 1, function (c) client.focus = c; c:raise() end),
879 awful.button({ modkey }, 1, awful.mouse.client.move),
880 awful.button({ modkey }, 3, awful.mouse.client.resize))
883 globalkeys = awful.util.table.join(globalkeys,
884 awful.key({ cmdkey }, "n", function () awful.spawn("firefox") end),
885 awful.key({ cmdkey }, "m", function () awful.spawn("chromium --enable-remote-extensions") end),
886 awful.key({ cmdkey }, "y", function () awful.spawn(terminal .. " -e python") end),
887 awful.key({ cmdkey }, "c", function () awful.spawn("thunderbird") end),
888 awful.key({ cmdkey }, "g", function () awful.spawn("gscan2pdf") end),
889 awful.key({ cmdkey }, "v", function () awful.spawn("virt-manager") end),
890 awful.key({ cmdkey }, "l", function () awful.spawn("libreoffice") end),
891 awful.key({ cmdkey }, "f", function () awful.spawn("thunar") end),
892 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),
893 awful.key({ cmdkey }, "x", function ()
894 awful.spawn("/usr/bin/xscreensaver -no-capture-stderr")
895 os.execute("sleep 5")
896 awful.spawn("xscreensaver-command -lock")
898 awful.key({ cmdkey, "Shift" }, "x", function () awful.spawn("xscreensaver-command -exit") end),
901 awful.key(nil, "XF86ScreenSaver", function () awful.spawn("xset dpms force off") end),
902 awful.key(nil, "XF86AudioMute", function () awful.spawn("pactl set-sink-mute 0 toggle") end),
903 awful.key({ cmdkey }, "End", function () awful.spawn("pactl set-sink-mute 0 toggle") end),
904 awful.key(nil, "XF86AudioLowerVolume", function () awful.spawn("pactl set-sink-volume 0 -2%") end),
905 awful.key({ cmdkey }, "Next", function () awful.spawn("pactl set-sink-volume 0 -2%") end),
906 awful.key(nil, "XF86AudioRaiseVolume", function () awful.spawn("pactl set-sink-volume 0 +2%") end),
907 awful.key({ cmdkey }, "Prior", function () awful.spawn("pactl set-sink-volume 0 +2%") end),
908 awful.key(nil, "XF86AudioMicMute", function () awful.spawn("pactl set-source-mute 1 toggle") end),
909 awful.key({ cmdkey }, "Home", function () awful.spawn("pactl set-source-mute 1 toggle") end),
910 awful.key(nil, "XF86MonBrightnessDown", function () awful.spawn("xbacklight -dec 5%") end),
911 awful.key(nil, "XF86MonBrightnessUp", function () awful.spawn("xbacklight -inc 5%") end),
912 awful.key(nil, "XF86Display", function () awful.spawn("") end),
913 awful.key(nil, "XF86WLAN", function () awful.spawn("") end),
914 awful.key(nil, "XF86Tools", function () awful.spawn("") end),
915 awful.key(nil, "XF86Search", function () awful.spawn("") end),
916 awful.key(nil, "XF86LaunchA", function () awful.spawn("") end),
917 awful.key(nil, "XF86Explorer", function () awful.spawn("") end)
921 root.keys(globalkeys)
925 -- Rules to apply to new clients (through the "manage" signal).
927 local function float_client_in_the_middle_with_margins(client, leftright, topbottom)
928 local wa = client.screen.workarea
930 client.y = wa.y + topbottom
931 client.height = wa.height - 2*topbottom
933 client.y = wa.y + (wa.height - client.height)/2
936 client.x = wa.x + leftright
937 client.width = wa.width - 2*leftright
939 client.x = wa.x + (wa.width - client.width)/2
943 local function move_to_tag_by_name(s, tagname)
945 local t = awful.tag.find_by_name(s, tagname)
947 error("No tag by the name of " .. tagname)
954 awful.rules.rules = {
955 -- All clients will match this rule.
957 properties = { border_width = beautiful.border_width,
958 border_color = beautiful.border_normal,
959 focus = awful.client.focus.filter,
962 buttons = clientbuttons,
963 screen = awful.screen.preferred,
964 placement = awful.placement.no_overlap+awful.placement.no_offscreen,
968 { rule = { type = "dialog" },
969 properties = { floating = true,
974 --switchtotag = true,
975 placement = awful.placement.centered
978 { rule = { class = "URxvt" },
979 properties = { size_hints_honor = false, }
981 { rule = { instance = "irc" },
982 callback = move_to_tag_by_name(nil, "irc"),
984 { rule = { class = "Revolt" },
985 callback = move_to_tag_by_name(nil, "[m]"),
987 { rule = { class = "Firefox" },
988 callback = move_to_tag_by_name(nil, "ffx"),
990 { rule = { class = "Chromium" },
991 callback = move_to_tag_by_name(nil, "chr"),
993 { rule = { class = "Thunderbird" },
994 callback = move_to_tag_by_name(nil, "cal"),
996 { rule_any = { class = {
1002 properties = { floating = true,
1005 placement = awful.placement.centered,
1008 { rule_any = { instance = {
1012 properties = { floating = true,
1015 placement = awful.placement.centered,
1018 -- { rule_any = { class = {
1026 -- properties = { new_tag = {
1027 -- layout = layouts.maximised,
1030 -- switchtotag = true,
1034 --XX-- { rule = { class = "Gscan2pdf" },
1035 --XX-- properties = {
1036 --XX-- switchtotag = true
1038 --XX-- callback = move_to_tag(1, 5)
1040 --XX-- { rule = { name = "gscan2pdf .*" },
1041 --XX-- properties = {
1042 --XX-- floating = false,
1045 --XX-- { rule = { class = "Thunar", type = "normal" },
1046 --XX-- properties = {
1047 --XX-- floating = false,
1050 --XX-- { rule = { class = "Pinentry", instance = "pinentry" },
1051 --XX-- properties = {
1052 --XX-- floating = true,
1055 --XX-- { rule = { class = "Gxmessage" },
1056 --XX-- properties = {
1057 --XX-- floating = true,
1065 -- Signal function to execute when a new client appears.
1066 client.connect_signal("manage", function (c)
1067 -- Set the windows at the slave,
1068 -- i.e. put it at the end of others instead of setting it master.
1069 -- if not awesome.startup then awful.client.setslave(c) end
1071 if awesome.startup and
1072 not c.size_hints.user_position
1073 and not c.size_hints.program_position then
1074 -- Prevent clients from being unreachable after screen count changes.
1075 awful.placement.no_offscreen(c)
1078 c.maximized_horizontal = false
1079 c.maximized_vertical = false
1082 -- Add a titlebar if titlebars_enabled is set to true in the rules.
1083 client.connect_signal("request::titlebars", function(c)
1084 -- buttons for the titlebar
1085 local buttons = gears.table.join(
1086 awful.button({ }, 1, function()
1089 awful.mouse.client.move(c)
1091 awful.button({ }, 3, function()
1094 awful.mouse.client.resize(c)
1098 awful.titlebar(c) : setup {
1100 awful.titlebar.widget.iconwidget(c),
1102 layout = wibox.layout.fixed.horizontal
1107 widget = awful.titlebar.widget.titlewidget(c)
1110 layout = wibox.layout.flex.horizontal
1113 awful.titlebar.widget.floatingbutton (c),
1114 awful.titlebar.widget.maximizedbutton(c),
1115 awful.titlebar.widget.stickybutton (c),
1116 awful.titlebar.widget.ontopbutton (c),
1117 awful.titlebar.widget.closebutton (c),
1118 layout = wibox.layout.fixed.horizontal()
1120 layout = wibox.layout.align.horizontal
1124 -- Enable sloppy focus, so that focus follows mouse.
1125 client.connect_signal("mouse::enter", function(c)
1126 if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
1127 and awful.client.focus.filter(c) then
1132 client.connect_signal("focus", function(c)
1133 c.border_color = beautiful.border_focus
1135 client.connect_signal("unfocus", function(c)
1136 c.border_color = beautiful.border_normal
1139 awful.ewmh.add_activate_filter(function(c, context, hints)
1140 if context == "ewmh" then
1141 if (c.class == "Firefox-esr" or c.class == "Firefox") then
1147 client.connect_signal("request::activate", function(c, context, hints)
1148 if gears.table.hasitem({
1149 "client.focus.byidx",
1151 "autofocus.check_focus",
1155 gears.timer.delayed_call(function()
1156 -- we need a delayed call so that we execute *after layout changes
1157 if hints.raise and c == client.focus and client.focus:isvisible() then
1158 move_mouse_to_area(client.focus)
1164 -- vim:ft=lua:sw=4:sts=4:ts=4:et