diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2e082f8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +#Temp files +*swp +*swo diff --git a/README.md b/README.md new file mode 100644 index 0000000..46ac347 --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +# Masterkorp's Awesome configuration + +This is my Awesome WM config, originaly based on Guff's config. + +### Testing +You can test the config with the debug.sh script on the scripts folder. Opens a +nested X session, so it can be tested within another WM + +### Dependencies +[Awesome WM](http://awesome.naquadah.org/) 3.5 or higher + +[Xephyr](http://www.freedesktop.org/wiki/Software/Xephyr) for the debug script diff --git a/cfg/client-bindings.lua b/cfg/client-bindings.lua index eb20e94..5300f64 100644 --- a/cfg/client-bindings.lua +++ b/cfg/client-bindings.lua @@ -1,4 +1,7 @@ -clientkeys = awful.util.table.join( +local awful = require("awful") + +local clientbinds = {} +clientbinds.keys = 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 ), @@ -16,9 +19,9 @@ clientkeys = awful.util.table.join( awful.key({ modkey, }, "/", awful.mouse.client.resize) ) -clientbuttons = awful.util.table.join( +clientbinds.buttons = 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)) -shifty.config.clientkeys = clientkeys +return clientbinds diff --git a/cfg/global-bindings.lua b/cfg/global-bindings.lua index b179feb..0372f05 100644 --- a/cfg/global-bindings.lua +++ b/cfg/global-bindings.lua @@ -1,39 +1,30 @@ -require("misc.dict") +local awful = require("awful") +local brightness = require("cfg.widgets.brightness") +local volume = require("cfg.widgets.volume") -globalkeys = awful.util.table.join( +local globalkeys = awful.util.table.join( -- Special function keys - awful.key({ }, "XF86MonBrightnessUp", brightness_up), - awful.key({ }, "XF86MonBrightnessDown", brightness_down), - awful.key({ }, "XF86ScreenSaver", function () awful.util.spawn("lualock -n") end), - awful.key({ }, "XF86AudioLowerVolume", volume_down_and_update), - awful.key({ }, "XF86AudioRaiseVolume", volume_up_and_update), - awful.key({ }, "XF86AudioMute", volume_mute_and_update), - awful.key({ }, "Print", function () awful.util.spawn("scrot -e 'mv $f ~/Pictures/ && xdg-open ~/Pictures/$f'") end), - + -- Briteness is controled by hardware on this laptop + awful.key({ }, "XF86MonBrightnessDown", function () brightness:down(5) end), + awful.key({ }, "XF86MonBrightnessUp", function () brightness:up(5) end), + awful.key({ modkey, }, "f", function () awful.spawn.spawn("xscreensaver-command --lock") end), + awful.key({ modkey, }, "F12", function () volume:set(5) end), + awful.key({ modkey, }, "F11", function () volume:set(-5) end), + awful.key({ modkey, }, "F10", function () volume:mute() end), + awful.key({ }, "Print", function () awful.spawn.spawn("scrot -e 'mv $f ~/Pictures/ && xdg-open ~/Pictures/$f'") end), + -- MPD keys - awful.key({ modkey, "Shift" }, "Up", function () awful.util.spawn("ncmpcpp toggle") end), - awful.key({ modkey, "Shift" }, "Down", function () awful.util.spawn("ncmpcpp stop") end), - awful.key({ modkey, "Shift" }, "Left", function () awful.util.spawn("ncmpcpp prev") end), - awful.key({ modkey, "Shift" }, "Right", function () awful.util.spawn("ncmpcpp next") end), + awful.key({ modkey, "Shift" }, "Up", function () awful.spawn.spawn("ncmpcpp toggle") end), + awful.key({ modkey, "Shift" }, "Down", function () awful.spawn.spawn("ncmpcpp stop") end), + awful.key({ modkey, "Shift" }, "Left", function () awful.spawn.spawn("ncmpcpp prev") end), + awful.key({ modkey, "Shift" }, "Right", function () awful.spawn.spawn("ncmpcpp next") end), - -- Shifty keys - awful.key({ modkey, "Control" }, "t", function() shifty.add({ rel_index = 1 }) end), - awful.key({ modkey, "Shift" }, "t", function() shifty.add({ rel_index = 1, nopopup = true }) end), - awful.key({ modkey, "Control" }, "g", shifty.rename), - awful.key({ modkey, "Control" }, "w", shifty.del), - -- Launch my terminal setup - awful.key({ modkey, }, "g", - function() - awful.util.spawn("sakura") - awful.util.spawn("sakura -f \"Terminus (TTF) 9\"") - awful.util.spawn("sakura -f \"Terminus (TTF) 9\"") - end - ), + awful.key({ modkey, }, "Return", function() awful.spawn.spawn("urxvt") end ), awful.key({ modkey, }, "Left", awful.tag.viewprev ), awful.key({ modkey, }, "Right", awful.tag.viewnext ), awful.key({ modkey, }, "Escape", awful.tag.history.restore), - awful.key({ modkey, }, "e", function () awful.util.spawn("thunar") end), + awful.key({ modkey, }, "e", function () awful.spawn.spawn("urxvt -e ranger") end), awful.key({ modkey, }, "j", function () awful.client.focus.byidx( 1) @@ -61,7 +52,6 @@ globalkeys = awful.util.table.join( end), -- 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), @@ -75,25 +65,6 @@ globalkeys = awful.util.table.join( awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(layouts, -1) end), -- Prompt - awful.key({ modkey, }, ";", - function () - awful.prompt.run({ prompt = "Dict: " }, mypromptbox[mouse.screen].widget, - function(word) - local definition = awful.util.pread("dict " .. word .. " 2>&1") - naughty.notify({ text = definition, timeout = 13, title = word, - width = 400, font = "Sans 7" }) - end, dict_cb, awful.util.getdir("cache") .. "/dict") - end - ), - awful.key({ modkey, "Control" }, ";", - function () - if selection() then - definition = awful.util.pread("dict " .. selection() .. " 2>&1") - naughty.notify({ text = definition, timeout = 13, - title = selection(), width = 400, font = "Sans 7" }) - end - end - ), awful.key({ modkey }, "r", function () mypromptbox[mouse.screen]:run() end), awful.key({ modkey }, "x", @@ -103,8 +74,8 @@ globalkeys = awful.util.table.join( awful.util.eval, nil, awful.util.getdir("cache") .. "/history_eval") end), - -- all minimized clients are restored - awful.key({ modkey, "Shift" }, "n", + -- all minimized clients are restored + awful.key({ modkey, "Shift" }, "n", function() local tags = awful.tag.selectedlist() for j=1, #tags do @@ -115,7 +86,7 @@ globalkeys = awful.util.table.join( end end), -- show desktop/unminimize - awful.key({ modkey }, "d", + awful.key({ modkey }, "d", function() local tag = awful.tag.selected() for i=1, #tag:clients() do @@ -127,38 +98,46 @@ globalkeys = awful.util.table.join( end) ) -for i=1, ( shifty.config.maxtags or 9 ) do - - globalkeys = awful.util.table.join(globalkeys, awful.key({ modkey }, i, - function () - local t = awful.tag.viewonly(shifty.getpos(i)) - end)) - globalkeys = awful.util.table.join(globalkeys, awful.key({ modkey, "Control" }, i, - function () - local t = shifty.getpos(i) - t.selected = not t.selected - end)) - globalkeys = awful.util.table.join(globalkeys, awful.key({ modkey, "Control", "Shift" }, i, - function () - if client.focus then - awful.client.toggletag(shifty.getpos(i)) +for i = 1, 9 do + globalkeys = awful.util.table.join(globalkeys, + -- Move to another tag + awful.key({ modkey }, "#" .. i + 9, + function () + local screen = mouse.screen + local tag = screen.tags[i] + if tag then + tag:view_only() end - end)) - -- move clients to other tags - globalkeys = awful.util.table.join(globalkeys, awful.key({ modkey, "Shift" }, i, - function () - if client.focus then - local t = shifty.getpos(i) - awful.client.movetotag(t) - --awful.tag.viewonly(t) + end + ), + -- Merge two tags + awful.key({ modkey, "Control" }, "#" .. i + 9, + function () + local screen = mouse.screen + local tag = screen.tags[i] + if tag then + awful.tag.viewtoggle(tag) + end + end + ), + -- Move client to tag + awful.key({ modkey, "Shift" }, "#" .. i + 9, + function () + local tag = client.focus.screen.tags[i] + if client.focus and tag then + awful.client.movetotag(tag) end - end)) + end + ), + -- Toggle client on another tag too + awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9, + function () + local tag = client.focus.screen.tags[i] + if client.focus and tag then + awful.client.toggletag(tag) + end + end + ) + ) end - -globalbuttons = awful.util.table.join( - awful.button({ }, 3, function () mymainmenu:toggle() end), - awful.button({ }, 4, awful.tag.viewnext), - awful.button({ }, 5, awful.tag.viewprev) -) - -shifty.config.globalkeys = globalkeys +root.keys(globalkeys) diff --git a/cfg/rules.lua b/cfg/rules.lua index 1078414..2751d58 100644 --- a/cfg/rules.lua +++ b/cfg/rules.lua @@ -1,21 +1,30 @@ -client.add_signal("manage", function (c, startup) +local awful = require("awful") +awful.rules = require("awful.rules") +local beautiful = require("beautiful") +local clientbinds = require("cfg.client-bindings") - -- Enable sloppy focus - c:add_signal("mouse::enter", function(c) - if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier - and awful.client.focus.filter(c) then - client.focus = c - end - end) +awful.rules.rules = { + -- Rules to all the clients + { rule = { }, + properties = { + border_width = beautiful.border_width, + border_color = beautiful.border_normal, + focus = awful.client.focus.filter, + keys = clientbinds.keys, + buttons = clientbinds.buttons + } + }, + { rule = { class = "mpv" }, + properties = { + floating = true, + centered = true + } + }, + { rule = { class = "Xephyr" }, + properties = { + floating = true, + centered = true + } + } +} - if not startup then - -- 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.add_signal("focus", function(c) c.border_color = beautiful.border_focus end) -client.add_signal("unfocus", function(c) c.border_color = beautiful.border_normal end) diff --git a/cfg/signals.lua b/cfg/signals.lua new file mode 100644 index 0000000..902a6a4 --- /dev/null +++ b/cfg/signals.lua @@ -0,0 +1,61 @@ +local awful = require("awful") +local wibox = require("wibox") +local beautiful = require("beautiful") + +client.connect_signal("manage", function (c, startup) + -- Enable sloppy focus + c:connect_signal("mouse::enter", function(c) + if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier and awful.client.focus.filter(c) then + client.focus = c + end + end) + + if not startup then + -- 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 + + local titlebars_enabled = false + if titlebars_enabled and (c.type == "normal" or c.type == "dialog") then + -- Widgets that are aligned to the left + local left_layout = wibox.layout.fixed.horizontal() + left_layout:add(awful.titlebar.widget.iconwidget(c)) + + -- Widgets that are aligned to the right + local right_layout = wibox.layout.fixed.horizontal() + right_layout:add(awful.titlebar.widget.floatingbutton(c)) + right_layout:add(awful.titlebar.widget.maximizedbutton(c)) + right_layout:add(awful.titlebar.widget.stickybutton(c)) + right_layout:add(awful.titlebar.widget.ontopbutton(c)) + right_layout:add(awful.titlebar.widget.closebutton(c)) + + -- The title goes in the middle + local title = awful.titlebar.widget.titlewidget(c) + title:buttons(awful.util.table.join( + awful.button({ }, 1, function() + client.focus = c + c:raise() + awful.mouse.client.move(c) + end), + awful.button({ }, 3, function() + client.focus = c + c:raise() + awful.mouse.client.resize(c) + end) + ) + ) + + -- Now bring it all together + local layout = wibox.layout.align.horizontal() + layout:set_left(left_layout) + layout:set_right(right_layout) + layout:set_middle(title) + awful.titlebar(c):set_widget(layout) + 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) diff --git a/cfg/tags.lua b/cfg/tags.lua index 2426820..8baf299 100644 --- a/cfg/tags.lua +++ b/cfg/tags.lua @@ -1,67 +1,27 @@ -require("shifty") +local awful = require("awful") -layouts = -{ - awful.layout.suit.floating, - awful.layout.suit.tile, - awful.layout.suit.tile.left, - awful.layout.suit.tile.bottom, - awful.layout.suit.tile.top, - awful.layout.suit.fair, - awful.layout.suit.fair.horizontal, - awful.layout.suit.magnifier +layouts = { + awful.layout.suit.floating, + awful.layout.suit.tile, + awful.layout.suit.tile.left, + awful.layout.suit.tile.bottom, + awful.layout.suit.tile.top, + awful.layout.suit.fair, + awful.layout.suit.fair.horizontal, + awful.layout.suit.spiral, + awful.layout.suit.spiral.dwindle, + awful.layout.suit.max, + awful.layout.suit.max.fullscreen, + awful.layout.suit.magnifier } -mytags = { "☉", "⌨", "☐", "☷", "♪", "⚈", "⌘", "⌥" } +tags = {} +for s = 1, screen.count() do + -- Each screen has its own tag table. + tags[s] = awful.tag( + { "main", "www", "dev", "admin", "⚈","⌘", "⌥", "☉", "♪"}, + s, + {layouts[2], layouts[10], layouts[4], layouts[2], layouts[2] ,layouts[1], layouts[1], layouts[1], layouts[1]} + ) +end --- All have init = true, because trying to move a client to a not-yet-created --- tag seems to be problematic, i.e. takes two attempts -shifty.config.tags = { - [mytags[1]] = { position = 1, init = true, layout = "floating", }, - [mytags[2]] = { position = 2, init = true, layout = "floating", }, - [mytags[3]] = { position = 3, init = true, layout = "tilebottom", - mwfact = 0.7, }, - [mytags[4]] = { position = 4, init = true, layout = "tiletop", }, - [mytags[5]] = { position = 5, }, - [mytags[6]] = { position = 6, }, - [mytags[7]] = { position = 7, mwfact = 0.1943359375, - layout = "tileleft", }, - [mytags[8]] = { position = 8, }, - -} - -local tags = shifty.config.tags - -shifty.config.apps = { - { match = { "Firefox.*", "xchat", "liferea", }, tag = mytags[1], }, - { match = { "geany" }, tag = mytags[2], }, - { match = { "gimp%-toolbox" }, float = false, tag = mytags[7], slave = false, }, - { match = { "gimp%-image%-window" }, tag = mytags[7], slave = true, }, - { match = { "color%-dialog" }, float = true, }, - -- Heck, if it has dialog in the name, safe to assume it should float - { match = { ".*dialog.*" }, float = true, }, - { match = { "inkscape", "Blender" }, tag = mytags[7], maximized_horizontal = true, - maximized_vertical = true, }, - { match = { "devhelp", "evince" }, tag = mytags[4], maximized_horizontal = true, - maximized_vertical = true, }, - { match = { "banshee", "totem", "gmpc", "vlc", }, tag = mytags[5], }, - { match = { "sakura", }, tag = mytags[3], }, - { match = { "Pidgin", "File Operation Progress", "pinentry", "Thunderbird", }, - float = true, }, - { match = { "" }, buttons = 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)), - border_width = beautiful.border_width, border_color = beautiful.border_color, - focus = true, - }, -} - -shifty.config.defaults = { - layout = "floating", - run = function(tag) naughty.notify({ text = "Created " .. tag.name }) end, -} - -shifty.config.layouts = layouts -shifty.config.guess_name = false -shifty.config.guess_position = false diff --git a/cfg/wibox.lua b/cfg/wibox.lua index 7d5b003..4f9dba0 100644 --- a/cfg/wibox.lua +++ b/cfg/wibox.lua @@ -1,408 +1,120 @@ --- widgets -require("vicious") -require("misc.notifications") +local awful = require("awful") +local battery = require("cfg.widgets.battery") +local brightness = require("cfg.widgets.brightness") +local volume = require("cfg.widgets.volume") +local wibox = require("wibox") -- freedesktop menu -require("cfg.menu") - -mytextclock = widget({ type = "textbox" }) -vicious.register(mytextclock, vicious.widgets.date, "%a %b %d, %l:%M %p") - -wifi_info = { ssid = "N/A" } -wifi_text = widget({ type = "textbox" }) - -wifi_icon = widget({ type = "imagebox" }) - -function update_wifi_icon() - local icon_dir = awful.util.getdir("config") .. "/icons/wireless-" - local icon_str = "disconnected" - if wifi_info.ssid ~= "N/A" then - if wifi_info.qual >= 75 then icon_str = "full" - elseif wifi_info.qual >= 50 then icon_str = "high" - elseif wifi_info.qual >= 25 then icon_str = "medium" - elseif wifi_info.qual > 0 then icon_str = "low" - else icon_str = "none" end - end - wifi_icon.image = image(icon_dir .. icon_str .. ".png") -end - -vicious.register(wifi_text, vicious.widgets.wifi, - function(widget, args) - wifi_info.ssid = args["{ssid}"] - wifi_info.qual = args["{linp}"] - update_wifi_icon() - return wifi_info.qual .. "%" - end, 1, "wlan0") -update_wifi_icon() - -myweather = widget({ type = "textbox" }) -wdata = { tempf = "N/A", } --- Need to siphon off the data for use in the tooltips later -vicious.register(myweather, vicious.widgets.weather, - function(widget, args) - if args["{tempf}"] ~= "N/A" then - wdata.tempf = args["{tempf}"] - end - wdata.weather = args["{weather}"] - wdata.sky = args["{sky}"] - wdata.city = args["{city}"] - wdata.wind = args["{windmph}"] - wdata.wind_dir = args["{wind}"] - wdata.humidity = args["{humid}"] - return wdata.tempf .. "° " - end, 600, "KGIF") - -fs_info = {} -fsdummy = widget({ type = "textbox" }) -vicious.register(fsdummy, vicious.widgets.fs, - function(widget, args) - fs_info.rootsize = args["{/ size_gb}"] - fs_info.homesize = args["{/home size_gb}"] - fs_info.rootfree = args["{/ avail_gb}"] - fs_info.homefree = args["{/home avail_gb}"] - end, 60 -) - -mem_bar = awful.widget.progressbar() --- Progressbar properties -mem_bar:set_width(8) -mem_bar:set_height(18) -mem_bar:set_vertical(true) -mem_bar:set_background_color("#494B4F") -mem_bar:set_border_color("#000000") -mem_bar:set_color("#AECF96") -mem_bar:set_gradient_colors({ "#AECF96", "#88A175", "#FF5656" }) - -mem_info = {} -vicious.register(mem_bar, vicious.widgets.mem, - function(widget, args) - mem_info.percent = args[1] - mem_info.usage = args[2] - mem_info.total = args[3] - mem_info.swapused = args[6] - mem_info.swaptotal = args[7] - return mem_info.percent - end, 10 -) - ---cputext = widget( { type = "textbox" }) ---vicious.register(cputext, vicious.widgets.cpu, "$1%", 2) -cpu_bar = awful.widget.progressbar() -cpu_bar:set_width(8):set_height(18):set_vertical(true) -cpu_bar:set_background_color("#494b4f"):set_border_color("#000000") -cpu_bar:set_color("#AD8488"):set_gradient_colors({ "#AD8488", "#964C53", "#FF3548" }) - -cpu_info = {} -vicious.register(cpu_bar, vicious.widgets.cpu, - function(widget, args) - cpu_info.load1 = args[1] - cpu_info.load2 = args[2] - return (cpu_info.load1 + cpu_info.load2) / 2 - end, 2 -) - -volume_icon = widget({ type = "imagebox" }) -volume_icon.image = image(volume_get_icon(get_volume())) - -function update_volume_icon(volume) - volume_icon.image = image(volume_get_icon(volume)) -end - -function volume_up_and_update() - local volume = volume_up() - update_volume_icon(volume) -end - -function volume_down_and_update() - local volume = volume_down() - update_volume_icon(volume) -end - -function volume_mute_and_update() - local volume = volume_mute() - update_volume_icon(volume) -end - -volume_icon:buttons(awful.util.table.join( - awful.button({}, 1, function () awful.util.spawn("pavucontrol") end), - awful.button({}, 2, volume_mute_and_update), - awful.button({}, 4, volume_up_and_update), - awful.button({}, 5, volume_down_and_update)) -) - -batt_info = {} -batt_text = widget({ type = "textbox" }) -vicious.register(batt_text, vicious.widgets.bat, - function(widget, args) - batt_info.state = args[1] - batt_info.level = args[2] - batt_info.remaining = args[3] - if batt_info.state == "-" or batt_info.state == "+" then - return " " .. args[3] - else - return nil - end - end, 5, "BAT0" -) - -batt_icon = widget({ type = "imagebox" }) -batt_icon_image = image(awful.util.getdir("config") .. "/icons/batticon.png") --- surprised this isn't in lua's math library -local function round(x) - if x - math.floor(x) >= 0.5 then return math.ceil(x) else return math.floor(x) end -end - -function update_batt_icon() - batt_icon.image = batt_icon_image - local off_x, off_y = 1, { top = 3, bot = 1 } - local w, h = batt_icon.image.width, batt_icon.image.height - local color = beautiful.batt_ok - if batt_info.level > 30 then color = beautiful.batt_ok - elseif batt_info.level > 10 then color = beautiful.batt_danger - else color = beautiful.batt_dying end - - local percent = batt_info.level / 100 - local rect_h = round((h - off_y.top - off_y.bot) * percent) - batt_icon.image:draw_rectangle(off_x, h - rect_h, w - 2 * off_x, rect_h - off_y.bot, true, color) - - if batt_info.state ~= "-" then - batt_icon.image:insert( - image(awful.util.getdir("config") .. "/icons/charging.png")) - end -end - -batt_timer = timer({ timeout = 5 }) -batt_timer:add_signal("timeout", update_batt_icon) -batt_timer:start() +--require("cfg.menu") -local batt_buttons = awful.util.table.join( - awful.button({ }, 1, - function() - run_or_raise("xfce4-power-information", { class = "xfce4-power-information" } ) - end - ), - awful.button({ }, 3, - function() - run_or_raise("xfce4-power-manager-settings", { class = "xfce4-power-manager-settings" } ) - end - ), - awful.button({ }, 4, - function() - os.execute("xbacklight -inc 10 > /dev/null 2>&1") - brightness_adjust(10) - end - ), - awful.button({ }, 5, - function() - os.execute("xbacklight -dec 10 > /dev/null 2>&1") - brightness_adjust(-10) - end - ) -) - -batt_text:buttons(batt_buttons) -batt_icon:buttons(batt_buttons) - -local sysmon_buttons = awful.button({}, 1, - function() - run_or_raise("lxtask", { class = "lxtask" } ) - end -) - -mem_bar.widget:buttons(sysmon_buttons) -cpu_bar.widget:buttons(sysmon_buttons) - -awful.tooltip({ objects = { batt_icon, batt_text }, timer_function = function() - return string.format("Battery:\nLevel: %s%%\nState: %s\n" - .. "Time remaining: %s", batt_info.level, batt_info.state, batt_info.remaining) - end, timeout = 10 -}) - -awful.tooltip({ objects = { mem_bar.widget, cpu_bar.widget }, timer_function = function() - return string.format("CPU0: %s%%; CPU1: %s%%\n\nMemory used: " - .. "%sMB, %s%% \nMemory total: %sMB\nSwap used: %sMB\nSwap total: " - .. "%sMB\n\nFilesystems:\n/: size %sGB, free %sGB\n/home: size" - .. " %sGB, free %sGB\n%s %s", cpu_info.load1, cpu_info.load2, mem_info.usage, - mem_info.percent, mem_info.total, mem_info.swapused, mem_info.swaptotal, - fs_info.rootsize, fs_info.rootfree, fs_info.homesize, fs_info.homefree, - awful.util.pread('uptime | sed "s/\\(.*users\\).*/\\1/"'), - awful.util.pread("cut -d\" \" -f1,2,3 /proc/loadavg")) - end, - timeout = 1 -}) - -awful.tooltip({ objects = { wifi_icon, }, timer_function = function() - return string.format("%s: %d%%", wifi_info.ssid, wifi_info.qual) -end, timeout = 1 }) - -awful.tooltip({ objects = { mytextclock, myweather, }, timer_function = function() - return string.format("Winter Haven, FL\n%s\nSky: %s\n%s, " - .. "%s°\nHumidity: %s%%", os.date("%a %b %d, %l:%M:%S %p"), wdata.sky, - wdata.weather, wdata.tempf, wdata.humidity) - end, timeout = 1 }) - -awful.tooltip({ objects = { volume_icon, }, timer_function = function() - if get_muted() then return "Volume: " .. get_volume() .. "%," .. " muted" - else return "Volume: " .. get_volume() .. "%" end -end, timeout = 1 }) - -local calendar = nil -local offset = 0 - -function remove_calendar() - if calendar ~= nil then - naughty.destroy(calendar) - calendar = nil - offset = 0 - end -end - -function add_calendar(inc_offset) - local save_offset = offset - remove_calendar() - offset = save_offset + inc_offset - local datespec = os.date("*t") - local today = datespec.day - datespec = datespec.year * 12 + datespec.month - 1 + offset - datespec = (datespec % 12 + 1) .. " " .. math.floor(datespec / 12) - local cal = awful.util.pread("cal -m " .. datespec) - cal = string.gsub(cal, "^%s*(.-)%s*$", "%1") - cal = string.gsub(cal, "([^%d]" .. today .. "[ \n])", - '%1', 1) - calendar = naughty.notify({ - text = string.format('%s', "monospace", - os.date("%a, %d %B %Y") .. "\n" .. cal), - timeout = 0, hover_timeout = 0.5, - width = 160, - }) -end - -mytextclock:add_signal("mouse::leave", remove_calendar) - -mytextclock:buttons(awful.util.table.join( - awful.button({ }, 1, function() - if calendar ~= nil then - remove_calendar() - else - add_calendar(0) - end - end), - awful.button({ }, 4, function() - add_calendar(1) - end), - awful.button({ }, 5, function() - add_calendar(-1) - end) -)) - - --- Create a systray -mysystray = widget({ type = "systray" }) +-- widgets +local mybattery = battery() +local mybrightness = brightness().widget +local mysystray= wibox.widget.systray() +local mytextclock = wibox.widget.textclock() +local myvolume = volume().widget -- Create a wibox for each screen and add it mywibox = {} mypromptbox = {} mylayoutbox = {} mytaglist = {} +mytasklist = {} 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, awful.tag.viewnext), - awful.button({ }, 5, awful.tag.viewprev) + awful.button({ }, 1, function(t) t:view_only() end), + 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(t.screen) end), + awful.button({ }, 5, function(t) awful.tag.viewprev(t.screen) end) ) -mytasklist = {} mytasklist.buttons = awful.util.table.join( - awful.button({ }, 1, - function (c) - if not c:isvisible() then awful.tag.viewonly(c:tags()[1]) end - if client.focus == c then - c.minimized = not c.minimized - else - client.focus = c - c:raise() - end - end - ), - awful.button({ }, 2, function (c) c:kill() end), - awful.button({ }, 3, - function () - if instance then - instance:hide() - instance = nil - else - instance = awful.menu.clients({ 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 + awful.button({ }, 1, + function (c) + if client.focus == c then + c.minimized = true + else + -- Without this, the following :ivisible() makes no sense + c.minimized = false + if not c:isvisible() then + c:tags()[1]:view_only() end - ) + -- This will also un-minimize the client, if needed + client.focus = c + c:raise() + end + end + ), + awful.button({ }, 2, function (c) c:kill() end), + awful.button({ }, 3, + function () + if instance then + instance:hide() + instance = nil + else + instance = awful.menu.clients({ 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 + ) ) for s = 1, screen.count() do -- Create a promptbox for each screen - mypromptbox[s] = awful.widget.prompt({ layout = awful.widget.layout.horizontal.leftright }) + mypromptbox[s] = awful.widget.prompt() -- 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)) + 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)) ) -- Create a taglist widget - mytaglist[s] = awful.widget.taglist(s, awful.widget.taglist.label.noempty, mytaglist.buttons) + mytaglist[s] = awful.widget.taglist(s, awful.widget.taglist.filter.all, mytaglist.buttons) -- Create a tasklist widget - mytasklist[s] = awful.widget.tasklist( - function(c) - return awful.widget.tasklist.label.currenttags(c, s) - end, mytasklist.buttons - ) + mytasklist[s] = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, mytasklist.buttons) + -- Create the wibox - mywibox[s] = awful.wibox({ position = "top", height="18", screen = s }) - -- Space out a few widgets - - -- Add widgets to the wibox - order matters - mywibox[s].widgets = { - { - --mylauncher, - mytaglist[s], - mypromptbox[s], - layout = awful.widget.layout.horizontal.leftright - }, - - mylayoutbox[s], - batt_text, - batt_icon, - wifi_icon, - volume_icon, - s == 1 and mysystray or nil, - mem_bar.widget, - cpu_bar.widget, - mytextclock, - myweather, - mytasklist[s], - layout = awful.widget.layout.horizontal.rightleft - - } + mywibox[s] = awful.wibar({ position = "top", screen = s }) + + -- Widgets that go on the left side of the bar, such as the taglist and the the promptbox + local left_layout = wibox.layout.fixed.horizontal() + left_layout:add(mytaglist[s]) + left_layout:add(mypromptbox[s]) + + -- Widgets that go on the right, such as the layoutbox + local right_layout = wibox.layout.fixed.horizontal() + right_layout:add(mybattery) + right_layout:add(myvolume) + right_layout:add(mybrightness) + right_layout:add(mytextclock) + right_layout:add(mysystray) + right_layout:add(mylayoutbox[s]) + + -- Join the widgets, 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) + + -- Set it all on the wibox + mywibox[s]:set_widget(layout) end - -shifty.taglist = mytaglist -shifty.promptbox = mypromptbox - -awful.widget.layout.margins[cpu_bar.widget] = { left = 5 } -awful.widget.layout.margins[myweather] = { left = 5 } -awful.widget.layout.margins[batt_icon] = { left = 2, right = 2 } diff --git a/cfg/widgets/battery.lua b/cfg/widgets/battery.lua new file mode 100644 index 0000000..7623cd7 --- /dev/null +++ b/cfg/widgets/battery.lua @@ -0,0 +1,99 @@ +local awful = require("awful") +local wibox = require("wibox") +local naughty = require("naughty") +local surface = require("gears.surface") +local beautiful = require("beautiful") +local color = require("gears.color") +local gears = require("gears") + +local __bat = {} +local base_string = "/sys/class/power_supply/BAT0" +local batticon = {} +batticon["width"] = 10 +batticon["height"] = 14 +batticon["icon"] = surface(beautiful.theme_path .. "/icons/batticon.png") +batticon["charging"] = surface(beautiful.theme_path .. "/icons/charging.png") +batticon["status"] = "" +batticon["danger"] = 0.35 +batticon["dying"] = 0.10 +-- The battery charge +local total = .5 + +local function update(textbox) + -- Battery status + local status = "" + local f = io.open(base_string .. "/status") + if f then + status = f:read() + local charge = assert(io.open(base_string .. "/energy_now"):read()) + local capacity = assert(io.open(base_string .. "/energy_full"):read()) + + -- Calculate charge + total = charge / capacity + + textbox:set_text(math.floor(total * 100)) + + elseif result == nil then + -- Battery is not present + status = "Not connected" + total = 0 + else + end + -- Notifcation of events. + if status ~= batticon["status"] then + naughty.notify({text = status, title = "Battery"}) + end + batticon["status"] = status +end + +local function new(args) + local args = args or {} + + -- A layout widget that contains the 3 widgets for the diferent + __bat.widget = wibox.layout.fixed.horizontal() + local textbox = wibox.widget.textbox() + __bat.widget:add(textbox) + + -- The icon + -- http://awesome.naquadah.org/wiki/Writing_own_widgets + local icon = wibox.widget.base.make_widget() + icon.fit = function(icon, width, height) + return batticon["width"], batticon["height"] + end + icon.draw = function(_, wibox, cr, width, height) + -- This not really documented use the cairo to get bearings in. + -- http://cairographics.org/manual/cairo-cairo-t.html + -- Another example is: + -- https://github.com/Elv13/awesome-configs/blob/master/widgets/battery.lua + cr:set_source_surface(batticon.icon, 0, 0) + cr:paint() + -- It must not overlap, and since y is the counting from the top, you need to translate the rectangle to the bottom of the icon + cr:translate(.5, (2 + batticon["height"] * (1 - total))) + cr:rectangle(1, 1, batticon["width"] - 3, batticon["height"] * total) + if total > batticon["danger"] then + cr:set_source_rgb(color.parse_color(beautiful.batt_ok)) + elseif total > batticon["dying"] and total <= batticon["danger"] then + cr:set_source_rgb(color.parse_color(beautiful.batt_danger)) + elseif total <= batticon["danger"] then + cr:set_source_rgb(color.parse_color(beautiful.batt_dying)) + end + cr:fill() + + if batticon["status"] == "Charging" then + cr:set_source_surface(batticon["charging"], -1, -4) + cr:paint() + end + + end + __bat.widget:add(icon) + + + + local battery_timer = gears.timer ({timeout = 10}) + battery_timer:connect_signal("timeout", function() update(textbox) end) + battery_timer:start() + + return __bat.widget +end + +return setmetatable(__bat, { __call = function(_, ...) return new(...) end }) diff --git a/cfg/widgets/brightness.lua b/cfg/widgets/brightness.lua new file mode 100644 index 0000000..073f96c --- /dev/null +++ b/cfg/widgets/brightness.lua @@ -0,0 +1,78 @@ +local awful = require("awful") +local wibox = require("wibox") +local naughty = require("naughty") +local notify = require("lib.notify") +local gears = require("gears") +local beautiful = require("beautiful") + +local brightness = {} + +brightness["icon"] = beautiful.theme_path .. "/icons/brightness.png" + +local function notify_brightness() + -- Volume notification bar + -- Passing it trough avoids pop spaming + brightness:get(function(br_val) brightness_notification = notify:fancy(br_val, brightness["icon"] , brightness_notification) end ) +end + +function brightness:get(callback) + -- local brightness = math.floor(tonumber(awful.util.pread("xbacklight -display :0 -get"))) + awful.spawn.easy_async("xbacklight -display :0 -get", + function (stdout, stderr, exitreason, exitcode) + if exitcode == 0 + then + local brightness = math.floor(tonumber(stdout)) + callback(brightness) + else + naughty.notify({ + text = "Error: Could not get screen light brightness", + title = "Brightness" + }) + end + end + ) +end + +function brightness:up(increment) + awful.spawn.spawn("xbacklight -display :0 -inc " .. increment) + notify_brightness() + + return nil +end + +function brightness:down(decrement) + awful.spawn.spawn("xbacklight -display :0 -dec " .. decrement) + notify_brightness() + + return nil +end + +local function new(args) + if not args then + args = {} + end + + -- Using the layout scheme + brightness.widget = wibox.layout.fixed.horizontal() + + local textbox = wibox.widget.textbox() + brightness:get(textbox.set_text) + brightness.widget:add(textbox) + + local imagebox = wibox.widget.imagebox() + imagebox:set_image(brightness["icon"]) + brightness.widget:add(imagebox) + + local brightness_timer = gears.timer ({timeout = 10}) + brightness_timer:connect_signal("timeout", + function() + brightness:get(textbox.set_text) + imagebox:set_image(brightness["icon"]) + end + ) + brightness_timer:start() + + return brightness +end + +return setmetatable(brightness, { __call = function(_, ...) return new(...) end }) diff --git a/cfg/widgets/volume.lua b/cfg/widgets/volume.lua new file mode 100644 index 0000000..f133503 --- /dev/null +++ b/cfg/widgets/volume.lua @@ -0,0 +1,109 @@ +local awful = require("awful") +local wibox = require("wibox") +local naughty = require("naughty") +local notify = require("notify") +local gears = require("gears") +local beautiful = require("beautiful") + +local volume = {} + + +volume["high"] = beautiful.theme_path .. "/icons/volume-high.png" +volume["medium"] = beautiful.theme_path .. "/icons/volume-medium.png" +volume["low"] = beautiful.theme_path .. "/icons/volume-low.png" +volume["muted"] = beautiful.theme_path .. "/icons/volume-muted.png" +volume["off"] = beautiful.theme_path .. "/icons/volume-off.png" + +local function get_icon(vol, is_muted) + local percentage = vol + if is_muted then + icon = volume["muted"] + elseif percentage == 0 then + icon = volume["off"] + elseif percentage < 30 then + icon = volume["low"] + elseif percentage > 30 and percentage < 70 then + icon = volume["medium"] + elseif percentage > 70 then + icon = volume["high"] + end + return icon +end + +local function notify_volume() + -- Volume notification bar + -- Passing it trough avoids pop spaming + volume:get(function(vol, is_muted) vol_notification = notify:fancy(vol, get_icon(vol, is_muted) , vol_notification) end) +end + +function volume:get(callback) + awful.spawn.easy_async("amixer get Master", + function(stdout, stderr, exitreason, exitcode) + if exitcode == 0 + then + local volume = tonumber(string.match(stdout, "(%d+)%%")) + local is_muted = string.find(stdout, '%[on%]') == nil + callback(volume, is_muted) + else + naughty.notify({ + text = "Error: Could not get volume information", + title = "Volume" + }) + end + end) +end + +function volume:set(increment) + local amixer_param = "" + if increment < 0 then + amixer_param = math.abs(increment) .. "%-" + elseif increment > 0 then + amixer_param = math.abs(increment) .. "%+" + end + + awful.spawn.spawn("amixer set Master " .. amixer_param) + notify_volume() + + return nil +end + +function volume:mute() + awful.spawn.spawn("amixer -D pulse set Master 1+ toggle") + notify_volume() +end + +local function new(args) + if not args then + args = {} + end + + -- Using the layout scheme + volume.widget = wibox.layout.fixed.horizontal() + + local textbox = wibox.widget.textbox() + local imagebox = wibox.widget.imagebox() + + volume.widget:add(textbox) + volume.widget:add(imagebox) + + volume:get(function(vol, is_muted) + textbox:set_text(vol) + imagebox:set_image(get_icon(vol, is_muted)) + end) + + local volume_timer = gears.timer ({timeout = 10}) + volume_timer:connect_signal("timeout", + function() + volume:get(function(vol, is_muted) + textbox:set_text(vol) + imagebox:set_image(get_icon(vol, is_muted)) + end) + end + ) + volume_timer:start() + + + return volume +end + +return setmetatable(volume, { __call = function(_, ...) return new(...) end }) diff --git a/doc/common-mistakes.md b/doc/common-mistakes.md new file mode 100644 index 0000000..8ae2980 --- /dev/null +++ b/doc/common-mistakes.md @@ -0,0 +1,36 @@ +# Common mistakes + +Awesome WM error messages are not the most friendly ones. + +#### draw is not a function + +While trying to set up my [laptop backlight](http://news.gmane.org/gmane.comp.window-managers.awesome) +whenever instancing an Widget, if the object does not exist, a message +containing: + +``` +error while running function +stack traceback: + [C]: in function 'error' + /usr/share/awesome/lib/gears/debug.lua:23: in function 'gears.debug.assert' + /usr/share/awesome/lib/wibox/widget/base.lua:120: in function 'wibox.widget.base.check_widget' + /usr/share/awesome/lib/wibox/layout/fixed.lua:55: in function 'wibox.layout.fixed.add' + ./cfg/wibox.lua:108: in main chunk + [C]: in function 'require' + ...rp/path/to/awesome-config-files/rc.lua:31: in main chunk +error: /usr/share/awesome/lib/gears/debug.lua:23: Assertion failed: 'draw is not a function' +stack traceback: + /usr/share/awesome/lib/gears/debug.lua:23: in function 'gears.debug.assert' + /usr/share/awesome/lib/wibox/widget/base.lua:120: in function 'wibox.widget.base.check_widget' + /usr/share/awesome/lib/wibox/layout/fixed.lua:55: in function 'wibox.layout.fixed.add' + ./cfg/wibox.lua:108: in main chunk + [C]: in function 'require' + ...rp/path/to/awesome-config-files/rc.lua:31: in main chunk +``` + +As pointed out in [this issue](https://github.com/pefimo/awpomodoro/issues/5) +This usually happens because the object passed to the widget layout does not +exist or it isn't a valid widget object, and thus does not have the draw +function as a member. + + diff --git a/lib/notify.lua b/lib/notify.lua new file mode 100644 index 0000000..4c4fa8d --- /dev/null +++ b/lib/notify.lua @@ -0,0 +1,37 @@ +local awful = require("awful") +local cairo = require("lgi").cairo +local gears = require("gears") +local beautiful = require("beautiful") +local naughty = require("naughty") + + +local notify = {} + +function notify:fancy(percent, icon, notification) + local img = cairo.ImageSurface(cairo.Format.ARGB32, 200, 50) + local cr = cairo.Context(img) + cr:set_source(gears.color(beautiful.bg_normal)) cr:paint() + cr:set_source_surface(gears.surface.load(icon, 0, 1)) + cr:paint() + cr:set_source(gears.color(beautiful.bg_focus)) + cr:rectangle(60, 20, 130, 10) + cr:fill() + cr:set_source(gears.color(beautiful.fg_focus)) + cr:rectangle(62, 22, 126 * percent / 100, 6) + cr:fill() + + local id = nil + if notification then + id = notification.id + end + return naughty.notify({ icon = img, replaces_id = id, + text = "\n" .. math.ceil(percent) .. "%", + font = "Sans Bold 10" }) +end + +function new() + -- nothing to here yet +end + + +return setmetatable(notify, { __call = function(_, ...) return new(...) end }) diff --git a/misc/notifications.lua b/misc/notifications.lua deleted file mode 100644 index af26634..0000000 --- a/misc/notifications.lua +++ /dev/null @@ -1,93 +0,0 @@ --- Show fancy notifications for backlight and volume hotkeys - -function fancy_notify(percent, icon_function, notification) - local img = image.argb32(200, 50, nil) - img:draw_rectangle(0, 0, img.width, img.height, true, beautiful.bg_normal) - img:insert(image(icon_function(percent)), 0, 1) - img:draw_rectangle(60, 20, 130, 10, true, beautiful.bg_focus) - img:draw_rectangle(62, 22, 126 * percent / 100, 6, true, beautiful.fg_focus) - - local id = nil - if notification then id = notification.id end - return naughty.notify({ icon = img, replaces_id = id, - text = "\n" .. math.ceil(percent) .. "%", - font = "Sans Bold 10" }) -end - --- Brightness notifications -function brightness_down() - brightness_adjust(-10) -end - -function brightness_up() - brightness_adjust(10) -end - -local bright_notification = nil -function brightness_adjust(inc) - -- Uncomment if your backlight keys don't work automatically - --os.execute("xbacklight -inc " .. inc .. " > /dev/null 2>&1") - local brightness = tonumber(awful.util.pread("xbacklight -get")) - bright_notification = - fancy_notify(brightness, brightness_get_icon, bright_notification) -end - -function brightness_get_icon(brightness) - return awful.util.getdir("config") .. "/icons/brightness.png" -end - --- Volume notifications - --- Each of these functions returns the current volume, so that it can be used --- by my volume icon widget to update its icon. It's not necessary for the --- notifications alone, however -function volume_down() - return volume_adjust(-5) -end - -function volume_up() - return volume_adjust(5) -end - -function volume_mute() - return volume_adjust(0) -end - -function get_volume() - return tonumber( - string.match(awful.util.pread("amixer -c0 get Master"), "(%d+)%%") - ) -end - -function get_muted() - return string.find(awful.util.pread("amixer -c0 get Master"), - '%[on%]') == nil -end - -local vol_notification = nil -function volume_adjust(inc) - if inc < 0 then inc = math.abs(inc) .. "%-" - elseif inc > 0 then inc = inc .. "%+" - else inc = "toggle" end - local volume, is_muted = - string.match(awful.util.pread("amixer -c0 set Master " .. inc), - "(%d+)%%.*%[(%a+)%]") - is_muted = is_muted == "off" - volume = tonumber(volume) - --local volume = get_volume() - --local is_muted = get_muted() - if is_muted then volume = 0 end - vol_notification = fancy_notify(volume, volume_get_icon, vol_notification) - return volume -end - -function volume_get_icon(volume) - local is_muted = get_muted() - local icon_str = nil - if volume > 70 then icon_str = "high.png" - elseif volume > 30 then icon_str = "medium.png" - elseif volume > 0 then icon_str = "low.png" - elseif volume == 0 then icon_str = "off.png" end - if is_muted then icon_str = "muted.png" end - return awful.util.getdir("config") .. "/icons/volume-" .. icon_str -end diff --git a/cfg/misc.lua b/misc/run.lua similarity index 82% rename from cfg/misc.lua rename to misc/run.lua index ce0a97f..b6196ae 100644 --- a/cfg/misc.lua +++ b/misc/run.lua @@ -1,15 +1,4 @@ --- This is used later as the default terminal and editor to run. -terminal = "lxterminal" -editor = "vim" -editor_cmd = terminal .. " -e " .. editor -browser = "firefox" - -modkey = "Mod4" - -local oldspawn = awful.util.spawn -awful.util.spawn = function (s) - oldspawn(s, false) -end +local awful = require("awful") --- Spawns cmd if no client can be found matching properties -- If such a client can be found, pop to first tag where it is visible, and give it focus @@ -44,14 +33,14 @@ function run_or_raise(cmd, properties) awful.client.movetotag(curtag, c) else -- Otherwise, pop to first tag client is visible on - awful.tag.viewonly(ctags[1]) + ctags[1]:view_only() end -- And then focus the client client.focus = c c:raise() return end - awful.util.spawn(cmd) + awful.spawn.spawn(cmd) end -- Returns true if all pairs in table1 are present in table2 diff --git a/rc.lua b/rc.lua index e5f3211..f5b6857 100644 --- a/rc.lua +++ b/rc.lua @@ -1,30 +1,32 @@ --- Standard awesome library -require("awful") +local awful = require("awful") require("awful.autofocus") -require("awful.rules") -require("awful.remote") --- Theme handling library -require("beautiful") +local naughty = require("naughty") +local beautiful = require("beautiful") +local gears = require("gears") + +-- This is used later as the default terminal and editor to run. +terminal = "urxvt" +editor = "nvim" +editor_cmd = terminal .. " -e " .. editor +browser = "firefox" + +modkey = "Mod4" + +-- Start theme beautiful.init(awful.util.getdir("config") .. "/theme/theme.lua") --- Notification library -require("naughty") +if beautiful.wallpaper then + for s = 1, screen.count() do + -- True is for no offset + gears.wallpaper.maximized(beautiful.wallpaper, s, true) + end +end --- Misc. settings and tools -require("cfg.misc") -- Load layouts and tags require("cfg.tags") -require("misc.notifications") +require("cfg.rules") -- Load wibox require("cfg.wibox") +require("cfg.signals") -- Key bindings require("cfg.global-bindings") -require("cfg.client-bindings") - --- Set keys and buttons -root.keys(globalkeys) -root.buttons(globalbuttons) - -require("cfg.rules") - -shifty.init() diff --git a/scripts/debug.sh b/scripts/debug.sh new file mode 100755 index 0000000..17c7280 --- /dev/null +++ b/scripts/debug.sh @@ -0,0 +1,74 @@ +# If rc.lua.new is missing, make a default one. +rc_lua=${PWD}/rc.lua +test -f $rc_lua + +echo $rc_lua +# Just in case we're not running from /usr/bin +awesome=`which awesome` +xephyr=`which Xephyr` +pidof=`which pidof` + +test -x $awesome || { echo "Awesome executable not found. Please install Awesome"; exit 1; } +test -x $xephyr || { echo "Xephyr executable not found. Please install Xephyr"; exit 1; } + +function usage() +{ + cat < 0 then return ret end -end - -function name2tag(name, scr, idx) - local ts = name2tags(name, scr) - if ts then return ts[idx or 1] end -end ---}}} - ---{{{ tag2index: finds index of a tag object --- @param scr : screen number to look for tag on --- @param tag : the tag object to find --- @return the index [or zero] or end of the list -function tag2index(scr, tag) - for i,t in ipairs(screen[scr]:tags()) do - if t == tag then return i end - end -end ---}}} - ---{{{ rename ---@param tag: tag object to be renamed ---@param prefix: if any prefix is to be added ---@param no_selectall: -function rename(tag, prefix, no_selectall) - local theme = beautiful.get() - local t = tag or awful.tag.selected(mouse.screen) - local scr = t.screen - local bg = nil - local fg = nil - local text = prefix or t.name - local before = t.name - - if t == awful.tag.selected(scr) then - bg = theme.bg_focus or '#535d6c' - fg = theme.fg_urgent or '#ffffff' - else - bg = theme.bg_normal or '#222222' - fg = theme.fg_urgent or '#ffffff' - end - - awful.prompt.run({ - fg_cursor = fg, bg_cursor = bg, ul_cursor = "single", - text = text, selectall = not no_selectall, prompt = "Rename tag: ", }, - promptbox[mouse.screen].widget, - function (name) if name:len() > 0 then t.name = name; end end, - completion, - awful.util.getdir("cache") .. "/history_tags", nil, - function () - if t.name == before then - if awful.tag.getproperty(t, "initial") then del(t) end - else - awful.tag.setproperty(t, "initial", true) - set(t) - end - tagkeys(screen[scr]) - t:emit_signal("property::name") - end - ) -end ---}}} - ---{{{ send: moves client to tag[idx] --- maybe this isn't needed here in shifty? --- @param idx the tag number to send a client to -function send(idx) - local scr = client.focus.screen or mouse.screen - local sel = awful.tag.selected(scr) - local sel_idx = tag2index(scr,sel) - local tags = screen[scr]:tags() - local target = awful.util.cycle(#tags, sel_idx + idx) - awful.client.movetotag(tags[target], client.focus) - awful.tag.viewonly(tags[target]) -end - -function send_next() send(1) end -function send_prev() send(-1) end ---}}} - ---{{{ pos2idx: translate shifty position to tag index ---@param pos: position (an integer) ---@param scr: screen number -function pos2idx(pos, scr) - local v = 1 - if pos and scr then - for i = #screen[scr]:tags() , 1, -1 do - local t = screen[scr]:tags()[i] - if awful.tag.getproperty(t,"position") and awful.tag.getproperty(t,"position") <= pos then - v = i + 1 - break - end - end - end - return v -end ---}}} - ---{{{ select : helper function chooses the first non-nil argument ---@param args - table of arguments -function select(args) - for i, a in pairs(args) do - if a ~= nil then - return a - end - end -end ---}}} - ---{{{ tagtoscr : move an entire tag to another screen --- ---@param scr : the screen to move tag to ---@param t : the tag to be moved [awful.tag.selected()] ---@return the tag -function tagtoscr(scr, t) - -- break if called with an invalid screen number - if not scr or scr < 1 or scr > screen.count() then return end - -- tag to move - local otag = t or awful.tag.selected() - - -- set screen and then reset tag to order properly - if #otag:clients() > 0 then - for _ , c in ipairs(otag:clients()) do - if not c.sticky then - c.screen = scr - c:tags( { otag } ) - else - awful.client.toggletag(otag,c) - end - end - end - return otag -end ----}}} - ---{{{ set : set a tags properties ---@param t: the tag ---@param args : a table of optional (?) tag properties ---@return t - the tag object -function set(t, args) - if not t then return end - if not args then args = {} end - - -- set the name - t.name = args.name or t.name - - -- attempt to load preset on initial run - local preset = (awful.tag.getproperty(t, "initial") and config.tags[t.name]) or {} - - -- pick screen and get its tag table - local scr = args.screen or (not t.screen and preset.screen) or t.screen or mouse.screen - if scr > screen.count() then scr = screen.count() end - if t.screen and scr ~= t.screen then - tagtoscr(scr, t) - t.screen = nil - end - local tags = screen[scr]:tags() - - -- try to guess position from the name - local guessed_position = nil - if not (args.position or preset.position) and config.guess_position then - local num = t.name:find('^[1-9]') - if num then guessed_position = tonumber(t.name:sub(1,1)) end - end - - -- select from args, preset, getproperty, config.defaults.configs or defaults - local props = { - layout = select{ args.layout, preset.layout, awful.tag.getproperty(t,"layout"), config.defaults.layout, awful.layout.suit.tile }, - mwfact = select{ args.mwfact, preset.mwfact, awful.tag.getproperty(t,"mwfact"), config.defaults.mwfact, 0.55 }, - nmaster = select{ args.nmaster, preset.nmaster, awful.tag.getproperty(t,"nmaster"), config.defaults.nmaster, 1 }, - ncol = select{ args.ncol, preset.ncol, awful.tag.getproperty(t,"ncol"), config.defaults.ncol, 1 }, - matched = select{ args.matched, awful.tag.getproperty(t,"matched") }, - exclusive = select{ args.exclusive, preset.exclusive, awful.tag.getproperty(t,"exclusive"), config.defaults.exclusive }, - persist = select{ args.persist, preset.persist, awful.tag.getproperty(t,"persist"), config.defaults.persist }, - nopopup = select{ args.nopopup, preset.nopopup, awful.tag.getproperty(t,"nopopup"), config.defaults.nopopup }, - leave_kills = select{ args.leave_kills, preset.leave_kills, awful.tag.getproperty(t,"leave_kills"), config.defaults.leave_kills }, - max_clients = select{ args.max_clients, preset.max_clients, awful.tag.getproperty(t,"max_clients"), config.defaults.max_clients }, - position = select{ args.position, preset.position, guessed_position, awful.tag.getproperty(t,"position" ) }, - icon = select{ args.icon and image(args.icon), preset.icon and image(preset.icon), awful.tag.getproperty(t,"icon"), config.defaults.icon and image(config.defaults.icon) }, - icon_only = select{ args.icon_only, preset.icon_only, awful.tag.getproperty(t,"icon_only"), config.defaults.icon_only }, - sweep_delay = select{ args.sweep_delay, preset.sweep_delay, awful.tag.getproperty(t,"sweep_delay"), config.defaults.sweep_delay }, - overload_keys = select{ args.overload_keys, preset.overload_keys, awful.tag.getproperty(t,"overload_keys"), config.defaults.overload_keys }, - } - - -- get layout by name if given as string - if type(props.layout) == "string" then - props.layout = getlayout(props.layout) - end - - -- set keys - if args.keys or preset.keys then - local keys = awful.util.table.join(config.globalkeys, args.keys or preset.keys) - if props.overload_keys then - props.keys = keys - else - props.keys = squash_keys(keys) - end - end - - -- calculate desired taglist index - local index = args.index or preset.index or config.defaults.index - local rel_index = args.rel_index or preset.rel_index or config.defaults.rel_index - local sel = awful.tag.selected(scr) - local sel_idx = (sel and tag2index(scr,sel)) or 0 --TODO: what happens with rel_idx if no tags selected - local t_idx = tag2index(scr,t) - local limit = (not t_idx and #tags + 1) or #tags - local idx = nil - - if rel_index then - idx = awful.util.cycle(limit, (t_idx or sel_idx) + rel_index) - elseif index then - idx = awful.util.cycle(limit, index) - elseif props.position then - idx = pos2idx(props.position, scr) - if t_idx and t_idx < idx then idx = idx - 1 end - elseif config.remember_index and index_cache[scr][t.name] then - idx = index_cache[scr][t.name] - elseif not t_idx then - idx = #tags + 1 - end - - -- if we have a new index, remove from old index and insert - if idx then - if t_idx then table.remove(tags, t_idx) end - table.insert(tags, idx, t) - index_cache[scr][t.name] = idx - end - - -- set tag properties and push the new tag table - screen[scr]:tags(tags) - for prop, val in pairs(props) do awful.tag.setproperty(t, prop, val) end - - -- execute run/spawn - if awful.tag.getproperty(t, "initial") then - local spawn = args.spawn or preset.spawn or config.defaults.spawn - local run = args.run or preset.run or config.defaults.run - if spawn and args.matched ~= true then awful.util.spawn_with_shell(spawn, scr) end - if run then run(t) end - awful.tag.setproperty(t, "initial", nil) - end - - return t -end - -function shift_next() set(awful.tag.selected(), { rel_index = 1 }) end -function shift_prev() set(awful.tag.selected(), { rel_index = -1 }) end ---}}} - ---{{{ add : adds a tag ---@param args: table of optional arguments --- -function add(args) - if not args then args = {} end - local name = args.name or " " - - -- initialize a new tag object and its data structure - local t = tag{ name = name } - - -- tell set() that this is the first time - awful.tag.setproperty(t, "initial", true) - - -- apply tag settings - set(t, args) - - -- unless forbidden or if first tag on the screen, show the tag - if not (awful.tag.getproperty(t,"nopopup") or args.noswitch) or #screen[t.screen]:tags() == 1 then awful.tag.viewonly(t) end - - -- get the name or rename - if args.name then - t.name = args.name - else - -- FIXME: hack to delay rename for un-named tags for tackling taglist refresh - -- which disabled prompt from being rendered until input - awful.tag.setproperty(t, "initial", true) - local f - if args.position then - f = function() rename(t, args.rename, true); tmr:stop() end - else - f = function() rename(t); tmr:stop() end - end - tmr = timer({ timeout = 0.01 }) - tmr:add_signal("timeout", f) - tmr:start() - end - - return t -end ---}}} - ---{{{ del : delete a tag ---@param tag : the tag to be deleted [current tag] -function del(tag) - local scr = (tag and tag.screen) or mouse.screen or 1 - local tags = screen[scr]:tags() - local sel = awful.tag.selected(scr) - local t = tag or sel - local idx = tag2index(scr,t) - - -- return if tag not empty (except sticky) - local clients = t:clients() - local sticky = 0 - for i, c in ipairs(clients) do - if c.sticky then sticky = sticky + 1 end - end - if #clients > sticky then return end - - -- store index for later - index_cache[scr][t.name] = idx - - -- remove tag - t.screen = nil - - -- if the current tag is being deleted, restore from history - if t == sel and #tags > 1 then - awful.tag.history.restore(scr,1) - -- this is supposed to cycle if history is invalid? - -- e.g. if many tags are deleted in a row - if not awful.tag.selected(scr) then - awful.tag.viewonly(tags[awful.util.cycle(#tags, idx - 1)]) - end - end - - -- FIXME: what is this for?? - if client.focus then client.focus:raise() end -end ---}}} - ---{{{ match : handles app->tag matching, a replacement for the manage hook in --- rc.lua ---@param c : client to be matched -function match(c, startup) - local nopopup, intrusive, nofocus, run, slave, wfact, struts, geom, float - local target_tag_names, target_tags = {}, {} - local typ = c.type - local cls = c.class - local inst = c.instance - local role = c.role - local name = c.name - local keys = config.clientkeys or c:keys() or {} - local target_screen = mouse.screen - - c.border_color = beautiful.border_normal - c.border_width = beautiful.border_width - - -- try matching client to config.apps - for i, a in ipairs(config.apps) do - if a.match then - for k, w in ipairs(a.match) do - if - (cls and cls:find(w)) or - (inst and inst:find(w)) or - (name and name:find(w)) or - (role and role:find(w)) or - (typ and typ:find(w)) - then - if a.screen then target_screen = a.screen end - if a.tag then - if type(a.tag) == "string" then - target_tag_names = { a.tag } - else - target_tag_names = a.tag - end - end - if a.startup and startup then a = awful.util.table.join(a, a.startup) end - if a.geometry ~=nil then geom = { x = a.geometry[1], y = a.geometry[2], width = a.geometry[3], height = a.geometry[4] } end - if a.float ~= nil then float = a.float end - if a.slave ~=nil then slave = a.slave end - if a.border_width ~= nil then c.border_width = a.border_width end - if a.nopopup ~=nil then nopopup = a.nopopup end - if a.intrusive ~=nil then intrusive = a.intrusive end - if a.fullscreen ~=nil then c.fullscreen = a.fullscreen end - if a.honorsizehints ~=nil then c.size_hints_honor = a.honorsizehints end - if a.kill ~=nil then c:kill(); return end - if a.ontop ~= nil then c.ontop = a.ontop end - if a.above ~= nil then c.above = a.above end - if a.below ~= nil then c.below = a.below end - if a.buttons ~= nil then c:buttons(a.buttons) end - if a.nofocus ~= nil then nofocus = a.nofocus end - if a.keys ~= nil then keys = awful.util.table.join(keys, a.keys) end - if a.hidden ~= nil then c.hidden = a.hidden end - if a.minimized ~= nil then c.minimized = a.minimized end - if a.dockable ~= nil then awful.client.dockable.set(c, a.dockable) end - if a.urgent ~= nil then c.urgent = a.urgent end - if a.opacity ~= nil then c.opacity = a.opacity end - if a.run ~= nil then run = a.run end - if a.sticky ~= nil then c.sticky = a.sticky end - if a.wfact ~= nil then wfact = a.wfact end - if a.struts then struts = a.struts end - if a.skip_taskbar ~= nil then c.skip_taskbar = a.skip_taskbar end - if a.props then - for kk, vv in pairs(a.props) do awful.client.property.set(c, kk, vv) end - end - end - end - end - end - - -- set key bindings - c:keys(keys) - - -- set properties of floating clients - if awful.client.floating.get(c) then - awful.placement.centered(c, c.transient_for) - awful.placement.no_offscreen(c) -- this always seems to stick the client at 0,0 (incl titlebar) - end - - -- if not matched to some names try putting client in c.transient_for or current tags - local sel = awful.tag.selectedlist(target_screen) - if not target_tag_names or #target_tag_names == 0 then - if c.transient_for then - target_tags = c.transient_for:tags() - elseif #sel > 0 then - for i, t in ipairs(sel) do - local mc = awful.tag.getproperty(t,"max_clients") - if not (awful.tag.getproperty(t,"exclusive") or (mc and mc >= #t:clients())) or intrusive then - table.insert(target_tags, t) - end - end - end - end - - -- if we still don't know any target names/tags guess name from class or use default - if (not target_tag_names or #target_tag_names == 0) and (not target_tags or #target_tags == 0) then - if config.guess_name and cls then - target_tag_names = { cls:lower() } - else - target_tag_names = { config.default_name } - end - end - - -- translate target names to tag objects, creating missing ones - if #target_tag_names > 0 and #target_tags == 0 then - for i, tn in ipairs(target_tag_names) do - local res = {} - for j, t in ipairs(name2tags(tn, target_screen) or name2tags(tn) or {}) do - local mc = awful.tag.getproperty(t,"max_clients") - if not (mc and (#t:clients() >= mc)) or intrusive then - table.insert(res, t) - end - end - if #res == 0 then - table.insert(target_tags, add({ name = tn, noswitch = true, matched = true })) - else - target_tags = awful.util.table.join(target_tags, res) - end - end - end - - -- set client's screen/tag if needed - target_screen = target_tags[1].screen or target_screen - if c.screen ~= target_screen then c.screen = target_screen end - if slave then awful.client.setslave(c) end - c:tags( target_tags ) - if wfact then awful.client.setwfact(wfact, c) end - if float ~= nil then awful.client.floating.set(c, float) end - if geom then c:geometry(geom) end - if struts then c:struts(struts) end - - -- switch or highlight - local showtags = {} - local u = nil - if #target_tags > 0 and not startup then - for i,t in ipairs(target_tags) do - if not(awful.tag.getproperty(t,"nopopup") or nopopup) then - table.insert(showtags, t) - elseif not startup then - c.urgent = true - end - end - if #showtags > 0 then - local ident = true - for kk,vv in pairs(showtags) do - if sel[kk] ~= vv then ident = false; break end - end - if not ident then - awful.tag.viewmore(showtags, c.screen) - end - end - end - - -- focus and raise accordingly or lower if supressed - if not (nofocus or c.hidden or c.minimized) then - if (awful.tag.getproperty(target,"nopopup") or nopopup) and (target and target ~= sel) then - awful.client.focus.history.add(c) - else - client.focus = c - end - c:raise() - else - c:lower() - end - - -- execute run function if specified - if run then run(c, target) end -end ---}}} - ---{{{ sweep : hook function that marks tags as used, visited, deserted --- also handles deleting used and empty tags -function sweep() - for s = 1, screen.count() do - for i, t in ipairs(screen[s]:tags()) do - local clients = t:clients() - local sticky = 0 - for i, c in ipairs(clients) do - if c.sticky then sticky = sticky + 1 end - end - if #clients == sticky then - if not awful.tag.getproperty(t,"persist") and awful.tag.getproperty(t,"used") then - if awful.tag.getproperty(t,"deserted") or not awful.tag.getproperty(t,"leave_kills") then - local delay = awful.tag.getproperty(t,"sweep_delay") - if delay then - local f = function() del(t); tmr:stop() end - tmr = timer({ timeout = delay }) - tmr:add_signal("timeout", f) - tmr:start() - else - del(t) - end - else - if not t.selected and awful.tag.getproperty(t,"visited") then awful.tag.setproperty(t,"deserted", true) end - end - end - else - awful.tag.setproperty(t,"used",true) - end - if t.selected then awful.tag.setproperty(t,"visited",true) end - end - end -end ---}}} - ---{{{ getpos : returns a tag to match position --- * originally this function did a lot of client stuff, i think its --- * better to leave what can be done by awful to be done by awful --- * -perry --- @param pos : the index to find --- @return v : the tag (found or created) at position == 'pos' -function getpos(pos) - local v = nil - local existing = {} - local selected = nil - local scr = mouse.screen or 1 - -- search for existing tag assigned to pos - for i = 1, screen.count() do - local s = awful.util.cycle(screen.count(), scr + i - 1) - for j, t in ipairs(screen[s]:tags()) do - if awful.tag.getproperty(t,"position") == pos then - table.insert(existing, t) - if t.selected and s == scr then selected = #existing end - end - end - end - if #existing > 0 then - -- if makeing another of an existing tag, return the end of the list - if selected then v = existing[awful.util.cycle(#existing, selected + 1)] else v = existing[1] end - end - if not v then - -- search for preconf with 'pos' and create it - for i, j in pairs(config.tags) do - if j.position == pos then v = add({ name = i, position = pos, noswitch = not switch }) end - end - end - if not v then - -- not existing, not preconfigured - v = add({ position = pos, rename = pos .. ':', no_selectall = true, noswitch = not switch }) - end - return v -end ---}}} - ---{{{ init : search shifty.config.tags for initial set of tags to open -function init() - local numscr = screen.count() - - for i, j in pairs(config.tags) do - local scr = j.screen or 1 - if j.init and ( scr <= numscr ) then - add({ name = i, persist = true, screen = scr, layout = j.layout, mwfact = j.mwfact }) - end - end -end ---}}} - ---{{{ count : utility function returns the index of a table element ---FIXME: this is currently used only in remove_dup, so is it really necessary? -function count(table, element) - local v = 0 - for i, e in pairs(table) do - if element == e then v = v + 1 end - end - return v -end ---}}} - ---{{{ remove_dup : used by shifty.completion when more than one ---tag at a position exists -function remove_dup(table) - local v = {} - for i, entry in ipairs(table) do - if count(v, entry) == 0 then v[#v+ 1] = entry end - end - return v -end ---}}} - ---{{{ completion : prompt completion --- -function completion(cmd, cur_pos, ncomp, sources, matchers) - - -- get sources and matches tables - sources = sources or config.prompt_sources - matchers = matchers or config.prompt_matchers - - local get_source = { - -- gather names from config.tags - config_tags = function() - local ret = {} - for n, p in pairs(config.tags) do table.insert(ret, n) end - return ret - end, - -- gather names from config.apps - config_apps = function() - local ret = {} - for i, p in pairs(config.apps) do - if p.tag then - if type(p.tag) == "string" then - table.insert(ret, p.tag) - else - ret = awful.util.table.join(ret, p.tag) - end - end - end - return ret - end, - -- gather names from existing tags, starting with the current screen - existing = function() - local ret = {} - for i = 1, screen.count() do - local s = awful.util.cycle(screen.count(), mouse.screen + i - 1) - local tags = screen[s]:tags() - for j, t in pairs(tags) do table.insert(ret, t.name) end - end - return ret - end, - -- gather names from history - history = function() - local ret = {} - local f = io.open(awful.util.getdir("cache") .. "/history_tags") - for name in f:lines() do table.insert(ret, name) end - f:close() - return ret - end, - } - - -- if empty, match all - if #cmd == 0 or cmd == " " then cmd = "" end - - -- match all up to the cursor if moved or no matchphrase - if matchp == "" or cmd:sub(cur_pos, cur_pos+#matchp) ~= matchp then - matchp = cmd:sub(1, cur_pos) - end - - -- find matching commands - local matches = {} - for i, src in ipairs(sources) do - local source = get_source[src]() - for j, matcher in ipairs(matchers) do - for k, name in ipairs(source) do - if name:find(matcher .. matchp) then - table.insert(matches, name) - end - end - end - end - - -- no matches - if #matches == 0 then return cmd, cur_pos end - - -- remove duplicates - matches = remove_dup(matches) - - -- cycle - while ncomp > #matches do ncomp = ncomp - #matches end - - -- put cursor at the end of the matched phrase - if #matches == 1 then - cur_pos = #matches[ncomp] + 1 - else - cur_pos = matches[ncomp]:find(matchp) + #matchp - end - - -- return match and position - return matches[ncomp], cur_pos -end ---}}} - --- {{{ tagkeys : hook function that sets keybindings per tag -function tagkeys(s) - local sel = awful.tag.selected(s.index) - local keys = awful.tag.getproperty(sel, "keys") or config.globalkeys - if keys and sel.selected then root.keys(keys) end -end --- }}} - --- {{{ squash_keys: helper function which removes duplicate keybindings --- by picking only the last one to be listed in keys table arg -function squash_keys(keys) - local squashed = {} - local ret = {} - for i, k in ipairs(keys) do - squashed[table.concat(k.modifiers) .. k.key] = k - end - for i, k in pairs(squashed) do - table.insert(ret, k) - end - return ret -end --- }}} - --- {{{ getlayout: returns a layout by name -function getlayout(name) - for _, layout in ipairs(config.layouts) do - if awful.layout.getname(layout) == name then return layout end - end -end --- }}} - --- {{{ signals -client.add_signal("manage", match) -client.add_signal("unmanage", sweep) -client.remove_signal("manage", awful.tag.withcurrent) - -for s = 1, screen.count() do - awful.tag.attached_add_signal(s, "property::selected", sweep) - awful.tag.attached_add_signal(s, "tagged", sweep) - screen[s]:add_signal("tag::history::update", tagkeys) -end --- }}} - --- vim: foldmethod=marker:filetype=lua:expandtab:shiftwidth=2:tabstop=2:softtabstop=2:encoding=utf-8:textwidth=80 diff --git a/theme/defender.jpg b/theme/defender.jpg new file mode 100644 index 0000000..0d3e8d8 Binary files /dev/null and b/theme/defender.jpg differ diff --git a/icons/batticon.png b/theme/icons/batticon.png similarity index 100% rename from icons/batticon.png rename to theme/icons/batticon.png diff --git a/icons/brightness.png b/theme/icons/brightness.png similarity index 100% rename from icons/brightness.png rename to theme/icons/brightness.png diff --git a/icons/charging.png b/theme/icons/charging.png similarity index 100% rename from icons/charging.png rename to theme/icons/charging.png diff --git a/icons/volume-high.png b/theme/icons/volume-high.png similarity index 100% rename from icons/volume-high.png rename to theme/icons/volume-high.png diff --git a/icons/volume-low.png b/theme/icons/volume-low.png similarity index 100% rename from icons/volume-low.png rename to theme/icons/volume-low.png diff --git a/icons/volume-medium.png b/theme/icons/volume-medium.png similarity index 100% rename from icons/volume-medium.png rename to theme/icons/volume-medium.png diff --git a/icons/volume-muted.png b/theme/icons/volume-muted.png similarity index 100% rename from icons/volume-muted.png rename to theme/icons/volume-muted.png diff --git a/icons/volume-off.png b/theme/icons/volume-off.png similarity index 100% rename from icons/volume-off.png rename to theme/icons/volume-off.png diff --git a/icons/weather/weather-cloud.png b/theme/icons/weather/weather-cloud.png similarity index 100% rename from icons/weather/weather-cloud.png rename to theme/icons/weather/weather-cloud.png diff --git a/icons/weather/weather-clouds.png b/theme/icons/weather/weather-clouds.png similarity index 100% rename from icons/weather/weather-clouds.png rename to theme/icons/weather/weather-clouds.png diff --git a/icons/weather/weather-cloudy.png b/theme/icons/weather/weather-cloudy.png similarity index 100% rename from icons/weather/weather-cloudy.png rename to theme/icons/weather/weather-cloudy.png diff --git a/icons/weather/weather-fog.png b/theme/icons/weather/weather-fog.png similarity index 100% rename from icons/weather/weather-fog.png rename to theme/icons/weather/weather-fog.png diff --git a/icons/weather/weather-lightning.png b/theme/icons/weather/weather-lightning.png similarity index 100% rename from icons/weather/weather-lightning.png rename to theme/icons/weather/weather-lightning.png diff --git a/icons/weather/weather-moon-clouds.png b/theme/icons/weather/weather-moon-clouds.png similarity index 100% rename from icons/weather/weather-moon-clouds.png rename to theme/icons/weather/weather-moon-clouds.png diff --git a/icons/weather/weather-moon-fog.png b/theme/icons/weather/weather-moon-fog.png similarity index 100% rename from icons/weather/weather-moon-fog.png rename to theme/icons/weather/weather-moon-fog.png diff --git a/icons/weather/weather-moon.png b/theme/icons/weather/weather-moon.png similarity index 100% rename from icons/weather/weather-moon.png rename to theme/icons/weather/weather-moon.png diff --git a/icons/weather/weather-rain.png b/theme/icons/weather/weather-rain.png similarity index 100% rename from icons/weather/weather-rain.png rename to theme/icons/weather/weather-rain.png diff --git a/icons/weather/weather-snow.png b/theme/icons/weather/weather-snow.png similarity index 100% rename from icons/weather/weather-snow.png rename to theme/icons/weather/weather-snow.png diff --git a/icons/weather/weather-tornado.png b/theme/icons/weather/weather-tornado.png similarity index 100% rename from icons/weather/weather-tornado.png rename to theme/icons/weather/weather-tornado.png diff --git a/icons/weather/weather.png b/theme/icons/weather/weather.png similarity index 100% rename from icons/weather/weather.png rename to theme/icons/weather/weather.png diff --git a/icons/wireless-disconnected.png b/theme/icons/wireless-disconnected.png similarity index 100% rename from icons/wireless-disconnected.png rename to theme/icons/wireless-disconnected.png diff --git a/icons/wireless-full.png b/theme/icons/wireless-full.png similarity index 100% rename from icons/wireless-full.png rename to theme/icons/wireless-full.png diff --git a/icons/wireless-high.png b/theme/icons/wireless-high.png similarity index 100% rename from icons/wireless-high.png rename to theme/icons/wireless-high.png diff --git a/icons/wireless-low.png b/theme/icons/wireless-low.png similarity index 100% rename from icons/wireless-low.png rename to theme/icons/wireless-low.png diff --git a/icons/wireless-medium.png b/theme/icons/wireless-medium.png similarity index 100% rename from icons/wireless-medium.png rename to theme/icons/wireless-medium.png diff --git a/icons/wireless-none.png b/theme/icons/wireless-none.png similarity index 100% rename from icons/wireless-none.png rename to theme/icons/wireless-none.png diff --git a/theme/king_of_the_hammers.jpg b/theme/king_of_the_hammers.jpg new file mode 100644 index 0000000..c0231ce Binary files /dev/null and b/theme/king_of_the_hammers.jpg differ diff --git a/theme/snail.png b/theme/snail.png deleted file mode 100644 index bbaa2f2..0000000 Binary files a/theme/snail.png and /dev/null differ diff --git a/theme/theme.lua b/theme/theme.lua index 1d29e5d..ff9e9d7 100644 --- a/theme/theme.lua +++ b/theme/theme.lua @@ -1,8 +1,11 @@ +local awful = require("awful") +local beautiful = require("beautiful") + --------------------------- -- Smoked awesome theme -- --------------------------- -theme_base = awful.util.getdir("config") .. "/theme/" +theme_base = beautiful.theme_path theme = {} @@ -10,10 +13,10 @@ theme.font = "Droid Sans 8" theme.tasklist_font = "Droid Sans 8" theme.taglist_font = "Droid Sans 9" -theme.bg_normal = "#61645B" -theme.bg_focus = "#8D8873" +theme.bg_normal = "#323232" +theme.bg_focus = "#6D9E3F" theme.bg_urgent = "#DC8536" -theme.bg_minimize = "#352E2A" +theme.bg_minimize = "#5E788B" theme.fg_normal = "#E7E5DE" theme.fg_focus = "#F5F5F5" @@ -21,8 +24,8 @@ theme.fg_urgent = "#f7f7f7" theme.fg_minimize = "#b9bbbb" theme.border_width = "1" -theme.border_normal = "#cbc8c1" -theme.border_focus = "#282421" +theme.border_normal = "#303030" +theme.border_focus = "#A3D572" theme.border_marked = "#f7f7f7" -- There are another variables sets @@ -76,17 +79,13 @@ theme.titlebar_floating_button_focus_inactive = theme_base .. "titlebar/floating theme.titlebar_floating_button_normal_active = theme_base .. "titlebar/floating_normal_active.png" theme.titlebar_floating_button_focus_active = theme_base .. "titlebar/floating_focus_active.png" -theme.titlebar_maximized_button_normal_inactive = - theme_base .. "titlebar/maximized_normal_inactive.png" -theme.titlebar_maximized_button_focus_inactive = - theme_base .. "titlebar/maximized_focus_inactive.png" -theme.titlebar_maximized_button_normal_active = - theme_base .. "titlebar/maximized_normal_active.png" -theme.titlebar_maximized_button_focus_active = - theme_base .. "titlebar/maximized_focus_active.png" +theme.titlebar_maximized_button_normal_inactive = theme_base .. "titlebar/maximized_normal_inactive.png" +theme.titlebar_maximized_button_focus_inactive = theme_base .. "titlebar/maximized_focus_inactive.png" +theme.titlebar_maximized_button_normal_active = theme_base .. "titlebar/maximized_normal_active.png" +theme.titlebar_maximized_button_focus_active = theme_base .. "titlebar/maximized_focus_active.png" -- You can use your own command to set your wallpaper -theme.wallpaper_cmd = { "awsetbg " .. awful.util.getdir("config") .. "/theme/snail.png" } +theme.wallpaper = theme_base .. "king_of_the_hammers.jpg" -- You can use your own layout icons like this: theme.layout_fairh = theme_base .. "layouts/fairh.png" @@ -104,4 +103,4 @@ theme.layout_tiletop = theme_base .. "layouts/tiletop.png" theme.awesome_icon = theme_base .. "awesome-icon-3.png" return theme --- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 + diff --git a/theme/theme.lua~ b/theme/theme.lua~ deleted file mode 100644 index 25580ef..0000000 --- a/theme/theme.lua~ +++ /dev/null @@ -1,92 +0,0 @@ ---------------------------- --- Default awesome theme -- ---------------------------- - -theme = {} - -theme.font = "sans 8" - -theme.bg_normal = "#f7f7f7" -theme.bg_focus = "#535d6c" -theme.bg_urgent = "#ff0000" -theme.bg_minimize = "#444444" - -theme.fg_normal = "#535d6c" -theme.fg_focus = "#ffffff" -theme.fg_urgent = "#ffffff" -theme.fg_minimize = "#ffffff" - -theme.border_width = "1" -theme.border_normal = "#000000" -theme.border_focus = "#535d6c" -theme.border_marked = "#91231c" - --- There are another variables sets --- overriding the default one when --- defined, the sets are: --- [taglist|tasklist]_[bg|fg]_[focus|urgent] --- titlebar_[bg|fg]_[normal|focus] --- Example: ---taglist_bg_focus = #ff0000 - --- Display the taglist squares -theme.taglist_squares_sel = "/usr/share/awesome/themes/default/taglist/squarefw.png" -theme.taglist_squares_unsel = "/usr/share/awesome/themes/default/taglist/square.png" - -theme.tasklist_floating_icon = "/usr/share/awesome/themes/default/tasklist/floating.png" - --- Variables set for theming menu --- menu_[bg|fg]_[normal|focus] --- menu_[border_color|border_width] -theme.menu_submenu_icon = "/usr/share/awesome/themes/default/submenu.png" -theme.menu_height = "15" -theme.menu_width = "100" - --- You can add as many variables as --- you wish and access them by using --- beautiful.variable in your rc.lua ---bg_widget = #cc0000 - --- Define the image to load -theme.titlebar_close_button_normal = "/usr/share/awesome/themes/default/titlebar/close_normal.png" -theme.titlebar_close_button_focus = "/usr/share/awesome/themes/default/titlebar/close_focus.png" - -theme.titlebar_ontop_button_normal_inactive = "/usr/share/awesome/themes/default/titlebar/ontop_normal_inactive.png" -theme.titlebar_ontop_button_focus_inactive = "/usr/share/awesome/themes/default/titlebar/ontop_focus_inactive.png" -theme.titlebar_ontop_button_normal_active = "/usr/share/awesome/themes/default/titlebar/ontop_normal_active.png" -theme.titlebar_ontop_button_focus_active = "/usr/share/awesome/themes/default/titlebar/ontop_focus_active.png" - -theme.titlebar_sticky_button_normal_inactive = "/usr/share/awesome/themes/default/titlebar/sticky_normal_inactive.png" -theme.titlebar_sticky_button_focus_inactive = "/usr/share/awesome/themes/default/titlebar/sticky_focus_inactive.png" -theme.titlebar_sticky_button_normal_active = "/usr/share/awesome/themes/default/titlebar/sticky_normal_active.png" -theme.titlebar_sticky_button_focus_active = "/usr/share/awesome/themes/default/titlebar/sticky_focus_active.png" - -theme.titlebar_floating_button_normal_inactive = "/usr/share/awesome/themes/default/titlebar/floating_normal_inactive.png" -theme.titlebar_floating_button_focus_inactive = "/usr/share/awesome/themes/default/titlebar/floating_focus_inactive.png" -theme.titlebar_floating_button_normal_active = "/usr/share/awesome/themes/default/titlebar/floating_normal_active.png" -theme.titlebar_floating_button_focus_active = "/usr/share/awesome/themes/default/titlebar/floating_focus_active.png" - -theme.titlebar_maximized_button_normal_inactive = "/usr/share/awesome/themes/default/titlebar/maximized_normal_inactive.png" -theme.titlebar_maximized_button_focus_inactive = "/usr/share/awesome/themes/default/titlebar/maximized_focus_inactive.png" -theme.titlebar_maximized_button_normal_active = "/usr/share/awesome/themes/default/titlebar/maximized_normal_active.png" -theme.titlebar_maximized_button_focus_active = "/usr/share/awesome/themes/default/titlebar/maximized_focus_active.png" - --- You can use your own command to set your wallpaper -theme.wallpaper_cmd = { "awsetbg /usr/share/awesome/themes/default/background.png" } - --- You can use your own layout icons like this: -theme.layout_fairh = "/usr/share/awesome/themes/default/layouts/fairh.png" -theme.layout_fairv = "/usr/share/awesome/themes/default/layouts/fairv.png" -theme.layout_floating = "/usr/share/awesome/themes/default/layouts/floating.png" -theme.layout_magnifier = "/usr/share/awesome/themes/default/layouts/magnifier.png" -theme.layout_max = "/usr/share/awesome/themes/default/layouts/max.png" -theme.layout_fullscreen = "/usr/share/awesome/themes/default/layouts/fullscreen.png" -theme.layout_tilebottom = "/usr/share/awesome/themes/default/layouts/tilebottom.png" -theme.layout_tileleft = "/usr/share/awesome/themes/default/layouts/tileleft.png" -theme.layout_tile = "/usr/share/awesome/themes/default/layouts/tile.png" -theme.layout_tiletop = "/usr/share/awesome/themes/default/layouts/tiletop.png" - -theme.awesome_icon = "/usr/share/awesome/icons/awesome16.png" - -return theme --- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80