-- Standard awesome library local gears = require("gears") local awful = require("awful") awful.rules = require("awful.rules") require("awful.autofocus") -- Widget and layout library local wibox = require("wibox") -- Theme handling library local beautiful = require("beautiful") -- Notification library local naughty = require("naughty") local menubar = require("menubar") local lfs = require("lfs") local posix = require("posix") local hostname = posix.uname("%n") naughty.config.defaults.bg = "#3d3d3d" naughty.config.defaults.icon_size = 32 local maildir_base = os.getenv("HOME") .. "/documents/mail/" table.insert(menubar.menu_gen.all_menu_dirs, os.getenv("HOME") .. "/.local/share/applications/") function new_mail(maildir) local count = 0 local newmaildir = maildir_base .. maildir .. "/new" local curmaildir = maildir_base .. maildir .. "/cur" if posix.access(newmaildir) then for file in lfs.dir(newmaildir) do if file ~= "." and file ~= ".." then count = count + 1 end end end if posix.access(curmaildir) then for file in lfs.dir(curmaildir) do if string.sub(file, -1) ~= "S" and file ~= "." and file ~= ".." then count = count + 1 end end end return count end function shrink_to_picturefix_width() local g = client.focus:geometry() awful.client.floating.set(client.focus, true) client.focus:geometry({x = g.x, y = g.y, width = 1066, height = 1060}) end function oni_focus_relative(i) return awful.screen.focus(awful.util.cycle(screen.count(), client.focus.screen + i)) end -- {{{ Error handling -- Check if awesome encountered an error during startup and fell back to -- another config (This code will only ever execute for the fallback config) if awesome.startup_errors then naughty.notify({ preset = naughty.config.presets.critical, title = "Oops, there were errors during startup!", text = awesome.startup_errors }) end -- Handle runtime errors after startup do local in_error = false awesome.connect_signal("debug::error", function (err) -- Make sure we don't go into an endless error loop if in_error then return end in_error = true naughty.notify({ preset = naughty.config.presets.critical, title = "Oops, an error happened!", text = err }) in_error = false end) end -- }}} -- {{{ Variable definitions -- Themes define colours, icons, font and wallpapers. beautiful.init(os.getenv("HOME") .. "/.config/awesome/themes/default/theme.lua") -- This is used later as the default terminal and editor to run. terminal = "urxvtc" editor = "emacsclient" editor_cmd = editor -- Default modkey. -- Usually, Mod4 is the key with a logo between Control and Alt. -- If you do not like this or do not have such a key, -- I suggest you to remap Mod4 to another key using xmodmap or other tools. -- However, you can use another modifier like Mod1, but it may interact with others. modkey = "Mod4" -- Table of layouts to cover with awful.layout.inc, order matters. local layouts = {} if hostname == "phoenix" then layouts = { awful.layout.suit.max } else layouts = { awful.layout.suit.tile, awful.layout.suit.max } end -- }}} -- {{{ Wallpaper -- gears.wallpaper.tiled("/home/slash/pictures/wallpaper-962650.jpg") local wallpapers = { "/home/slash/pictures/wallpaper-2311191.jpg", "/home/slash/pictures/wallpaper-1518737-phoenix.png" } for idx, wall in ipairs(wallpapers) do if posix.access(wall) then gears.wallpaper.tiled(wall) break end end -- }}} -- {{{ Tags -- Define a tag table which hold all screen tags. tags = {} tags[1] = awful.tag({" Emacs"}, 1, awful.layout.suit.tile) if screen.count() > 1 then tags[2] = awful.tag({" Web"}, 2, awful.layout.suit.max) if screen.count() > 2 then for s = 3, screen.count() do -- Each screen has its own tag table. tags[s] = awful.tag({ 1, 2, 3, 4, 5, 6, 7, 8, 9 }, s, layouts[1]) end end end -- }}} -- {{{ Menu -- Create a laucher widget and a main menu myawesomemenu = { { "manual", terminal .. " -e man awesome" }, { "edit config", editor_cmd .. " " .. awesome.conffile }, { "restart", awesome.restart }, { "quit", awesome.quit } } mymainmenu = awful.menu({ items = { { "awesome", myawesomemenu, beautiful.awesome_icon }, { "open terminal", terminal } } }) mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon, menu = mymainmenu }) -- Menubar configuration menubar.utils.terminal = terminal -- Set the terminal for applications that require it -- }}} -- {{{ Wibox -- Create a textclock widget mytextclock = awful.widget.textclock() -- Create a wibox for each screen and add it mywibox = {} mypromptbox = {} mylayoutbox = {} mytaglist = {} mytaglist.buttons = awful.util.table.join( awful.button({ }, 1, awful.tag.viewonly), awful.button({ modkey }, 1, awful.client.movetotag), awful.button({ }, 3, awful.tag.viewtoggle), awful.button({ modkey }, 3, awful.client.toggletag), awful.button({ }, 4, function(t) awful.tag.viewnext(awful.tag.getscreen(t)) end), awful.button({ }, 5, function(t) awful.tag.viewprev(awful.tag.getscreen(t)) end) ) mytasklist = {} mytasklist.buttons = awful.util.table.join( awful.button({ }, 1, function (c) if c ~= client.focus then client.focus = c c:raise() end end), awful.button({ }, 3, function () if instance then instance:hide() instance = nil else instance = awful.menu.clients({ theme = { width = 250 } }) end end), awful.button({ }, 4, function () awful.client.focus.byidx(1) if client.focus then client.focus:raise() end end), awful.button({ }, 5, function () awful.client.focus.byidx(-1) if client.focus then client.focus:raise() end end)) function mailwidget(name, lighter) widget = wibox.widget.textbox() widget.set_mailcount = function (self) self:set_text(string.format(" %s: %d", lighter, new_mail(name .. '/inbox'))) end widget:set_mailcount() return widget end mailwidgets = {ryuslash = mailwidget('ryuslash.org', 'ryu'), picturefix = mailwidget('picturefix', 'pfx'), gmail = mailwidget('gmail', 'gmail'), ninthfloor = mailwidget('ninthfloor', '9f')} myrsslist = wibox.widget.textbox() myrsslist.set_count = function (self, count) if count then self:set_markup(" " .. count .. " ") else self:set_text("") end end function mailcount() mailboxes = { 'ryuslash.org', 'picturefix', 'gmail', 'ninthfloor' } count = 0 for i, box in ipairs(mailboxes) do count = count + new_mail(box .. '/inbox') end return count end mymailwidget = wibox.widget.textbox() mymailwidget.set_count = function (self) count = mailcount() if count then self:set_markup(" " .. count .. " ") else self:set_text("") end end mymailwidget:set_count() function unlocked() if awful.util.pread("keycheck login") == "Unlocked" then return " " else return " " end end mykeyringlist = wibox.widget.textbox() mykeyringlist:set_text(unlocked()) mykeyringlist:set_font("FontAwesome") mykeyringlist:buttons( awful.util.table.join( awful.button({ }, 2, function () mykeyringlist:set_text(unlocked()) end) ) ) mykeyringlisttimer = timer({ timeout = 60 }) mykeyringlisttimer:connect_signal( "timeout", function () mykeyringlist:set_text(unlocked()) end ) mykeyringlisttimer:start() for s = 1, screen.count() do -- Create a promptbox for each screen mypromptbox[s] = awful.widget.prompt() if #layouts > 1 then -- Create an imagebox widget which will contains an icon indicating which layout we're using. -- We need one layoutbox per screen. mylayoutbox[s] = awful.widget.layoutbox(s) mylayoutbox[s]:buttons(awful.util.table.join( awful.button({ }, 1, function () awful.layout.inc(layouts, 1) end), awful.button({ }, 3, function () awful.layout.inc(layouts, -1) end), awful.button({ }, 4, function () awful.layout.inc(layouts, 1) end), awful.button({ }, 5, function () awful.layout.inc(layouts, -1) end))) end -- Create a taglist widget mytaglist[s] = awful.widget.taglist(s, awful.widget.taglist.filter.all, mytaglist.buttons) -- Create a tasklist widget mytasklist[s] = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, mytasklist.buttons) -- Create the wibox mywibox[s] = awful.wibox({ position = "bottom", screen = s }) -- Widgets that are aligned to the left local left_layout = wibox.layout.fixed.horizontal() left_layout:add(mylauncher) left_layout:add(mytaglist[s]) left_layout:add(mypromptbox[s]) -- Widgets that are aligned to the right local right_layout = wibox.layout.fixed.horizontal() if s == 1 then right_layout:add(mykeyringlist) if hostname == "drd" then right_layout:add(myrsslist) end right_layout:add(mymailwidget) -- for k, w in pairs(mailwidgets) do -- right_layout:add(w) -- end right_layout:add(wibox.widget.systray()) end right_layout:add(mytextclock) if #layouts > 1 then right_layout:add(mylayoutbox[s]) end -- Now bring it all together (with the tasklist in the middle) local layout = wibox.layout.align.horizontal() layout:set_left(left_layout) layout:set_middle(mytasklist[s]) layout:set_right(right_layout) mywibox[s]:set_widget(layout) end -- }}} -- {{{ Mouse bindings root.buttons(awful.util.table.join( awful.button({ }, 3, function () mymainmenu:toggle() end), awful.button({ }, 4, awful.tag.viewnext), awful.button({ }, 5, awful.tag.viewprev) )) -- }}} function fraise (idx) awful.client.focus.byidx(idx) if client.focus then client.focus:raise() end end function hpraise () awful.client.focus.history.previous() if client.focus then client.focus:raise() end end function ror (prog, class) function inner () local matcher = function (c) return awful.rules.match(c, { class = class }) end awful.client.run_or_raise(prog, matcher) end return inner end -- {{{ Key bindings globalkeys = awful.util.table.join( awful.key({ modkey, }, "l", awful.tag.viewprev), awful.key({ modkey, }, "y", awful.tag.viewnext), awful.key({ modkey, }, "Escape", awful.tag.history.restore), awful.key({ modkey, }, "n", function () fraise(1) end), awful.key({ modkey, }, "p", function () fraise(-1) end), -- awful.key({ modkey, }, "w", function () mymainmenu:show() end), awful.key({ }, "Print", function () awful.util.spawn("scrot") end), -- awful.key({ "Control", }, "Print", function () awful.util.spawn("scrot -s") end), awful.key({ modkey, }, "c", ror("urxvtc", "URxvt")), awful.key({ modkey, }, "e", ror("emacsclient -c", "Emacs")), awful.key({ modkey, }, "w", ror("conkeror", "Conkeror")), -- Layout manipulation awful.key({ modkey, "Shift" }, "n", function () awful.client.swap.byidx( 1) end), awful.key({ modkey, "Shift" }, "p", function () awful.client.swap.byidx( -1) end), awful.key({ modkey, }, ".", function () oni_focus_relative( 1) end), awful.key({ modkey, }, ",", function () oni_focus_relative(-1) end), awful.key({ modkey, "Shift" }, ".", function () awful.client.movetoscreen(client.focus) end), awful.key({ modkey, "Shift" }, ",", function () awful.client.movetoscreen(client.focus, -1) end), awful.key({ modkey, }, "u", awful.client.urgent.jumpto), awful.key({ modkey, }, "Tab", hpraise), awful.key({ modkey, }, "g", shrink_to_picturefix_width), -- Standard program awful.key({ modkey, }, "Return", function () awful.util.spawn(terminal) end), awful.key({ modkey, "Control" }, "r", awesome.restart), awful.key({ modkey, "Shift" }, "q", awesome.quit), awful.key({ modkey, }, "j", function () awful.tag.incmwfact( 0.05) end), awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end), awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1) end), awful.key({ modkey, "Shift" }, "j", function () awful.tag.incnmaster(-1) end), awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1) end), awful.key({ modkey, "Control" }, "j", function () awful.tag.incncol(-1) end), awful.key({ modkey, }, "space", function () awful.layout.inc(layouts, 1) end), awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(layouts, -1) end), -- Prompt awful.key({ modkey }, "r", function () mypromptbox[mouse.screen]:run() end), awful.key({ modkey }, "x", function () awful.prompt.run({ prompt = "Run Lua code: " }, mypromptbox[mouse.screen].widget, awful.util.eval, nil, awful.util.getdir("cache") .. "/history_eval") end), -- Menubar awful.key({ modkey }, "k", function() menubar.show() end), awful.key({ "Control", "Mod1" }, "l", function () awful.util.spawn('i3lock -c000000') end) ) clientkeys = awful.util.table.join( awful.key({ modkey, }, "f", function (c) c.fullscreen = not c.fullscreen end), awful.key({ modkey, "Shift" }, "c", function (c) c:kill() end), awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle ), awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end), awful.key({ modkey, }, "o", awful.client.movetoscreen ), awful.key({ modkey, }, "t", function (c) c.ontop = not c.ontop end), awful.key({ modkey, }, "m", function (c) c.maximized_horizontal = not c.maximized_horizontal c.maximized_vertical = not c.maximized_vertical end) ) -- Bind all key numbers to tags. -- Be careful: we use keycodes to make it works on any keyboard layout. -- This should map on the top row of your keyboard, usually 1 to 9. for i = 1, 9 do globalkeys = awful.util.table.join(globalkeys, -- View tag only. awful.key({ modkey }, "#" .. i + 9, function () local screen = mouse.screen local tag = awful.tag.gettags(screen)[i] if tag then awful.tag.viewonly(tag) end end), -- Toggle tag. awful.key({ modkey, "Control" }, "#" .. i + 9, function () local screen = mouse.screen local tag = awful.tag.gettags(screen)[i] if tag then awful.tag.viewtoggle(tag) end end), -- Move client to tag. awful.key({ modkey, "Shift" }, "#" .. i + 9, function () if client.focus then local tag = awful.tag.gettags(client.focus.screen)[i] if tag then awful.client.movetotag(tag) end end end), -- Toggle tag. awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9, function () if client.focus then local tag = awful.tag.gettags(client.focus.screen)[i] if tag then awful.client.toggletag(tag) end end end)) end clientbuttons = awful.util.table.join( awful.button({ }, 1, function (c) client.focus = c; c:raise() end), awful.button({ modkey }, 1, awful.mouse.client.move), awful.button({ modkey }, 3, awful.mouse.client.resize)) -- Set keys root.keys(globalkeys) -- }}} -- {{{ Rules -- Rules to apply to new clients (through the "manage" signal). awful.rules.rules = { -- All clients will match this rule. { rule = { }, properties = { border_width = beautiful.border_width, border_color = beautiful.border_normal, focus = awful.client.focus.filter, raise = true, keys = clientkeys, buttons = clientbuttons } }, { rule = { class = "MPlayer" }, properties = { floating = true } }, { rule = { class = "pinentry" }, properties = { floating = true } }, { rule = { class = "gimp" }, properties = { floating = true } }, { rule = { instance = "SteamWorldDig.exe" }, properties = { fullscreen = true } }, { rule = { instance = "RogueLegacy.exe" }, properties = { fullscreen = true } }, { rule = { class = "Emacs" }, properties = { tag = tags[1][1] } }, { rule = { class = "URxvt" }, properties = { size_hints_honor = false } }, -- Set Firefox to always map on tags number 2 of screen 1. -- { rule = { class = "Firefox" }, -- properties = { tag = tags[1][2] } }, } -- If there is more than one list of tags, add a rule that puts all -- "Conkeror" windows on tag 1 of screen 2 (the second list of tags). if #tags > 1 then awful.rules.rules = awful.util.table.join(awful.rules.rules, { { rule = { class = "Conkeror" }, properties = { tag = tags[2][1] } } }) end -- }}} -- {{{ Signals imp_classes = { "Dia", "Firefox", "Pencil", "Filezilla", "Gimp" } -- Signal function to execute when a new client appears. client.connect_signal("manage", function (c, startup) if not startup then -- Set the windows at the slave, -- i.e. put it at the end of others instead of setting it master. if not awful.rules.match_any(c, { class = { "Emacs", "Dia" } }) then awful.client.setslave(c) end if awful.rules.match_any(c, { class = imp_classes }) then tags[c.class] = tags[c.class] or awful.tag.add(" " .. c.class, {layout = awful.layout.suit.tile}) awful.tag.viewonly(tags[c.class]) awful.client.movetotag(tags[c.class], c) end if awful.rules.match(c, { class = "Dia" }) then awful.tag.setmwfact(0.90, tags["Dia"]) end -- Put windows in a smart way, only if they does not set an initial position. if not c.size_hints.user_position and not c.size_hints.program_position then awful.placement.no_overlap(c) awful.placement.no_offscreen(c) end end end) client.connect_signal("unmanage", function(c) if awful.rules.match_any(c, { class = imp_classes }) then if tags[c.class] and #tags[c.class]:clients() == 0 then awful.tag.delete(tags[c.class]) tags[c.class] = nil end end end) client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end) client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end) -- }}} -- Set the master window factor so that terminal windows show up with -- 80 columns on the main screen. This is meant for a 1920x1080 -- resolution. awful.tag.setmwfact(0.623, tags[1][1])