-- Include awesome library, with lots of useful function!
require("awful")
-require("eminent")
-require("wicked")
+require("awful.autofocus")
+require("awful.rules")
+require("vicious")
require("beautiful")
-terminal = "x-terminal-emulator"
+terminal = "urxvtcd"
lock = 'xscreensaver-command -lock'
beautiful.init(awful.util.getdir("config").."/theme")
alt = "Mod1"
control = "Control"
-k_n = {}
-k_m = {modkey}
-k_ms = {modkey, shift}
-k_ma = {modkey, alt}
-k_mc = {modkey, control}
-k_a = {alt}
-k_ac = {alt, control}
-k_c = {control}
-k_cs = {control, shift}
-k_s = {shift}
+k_n = {}
+k_m = {modkey}
+k_ms = {modkey, shift}
+k_ma = {modkey, alt}
+k_mc = {modkey, control}
+k_mcs = {modkey, control, shift}
+k_a = {alt}
+k_ac = {alt, control}
+k_c = {control}
+k_cs = {control, shift}
+k_s = {shift}
-- }}}
-
-- {{{ Markup helper functions
-- Inline markup is a tad ugly, so use these functions
-- to dynamically create markup.
return '<span color="'..color..'">'..text..'</span>'
end
-function heading(text)
- return fg(beautiful.fg_focus, text)
-end
-
-- }}}
--- {{{ Functions
--- Toggle whether we're viewing a tag
-function tag_toggleview(tag)
- tag:view(not tag:isselected())
+
+-- {{{ Tags
+
+tags = {}
+for s = 1, screen.count() do
+ -- Each screen has its own tag table.
+ local p = {}
+ for i = 1, 10 do
+ table.insert(p, "work-"..i)
+ end
+ tags[s] = awful.tag(p, s, awful.layout.suit.tile)
end
-- Get the screen number we're on
-function getscreen()
- local sel = client.focus
- return (sel and sel.screen) or mouse.screen
+local mtag = { }
+function mtag.getn(idx, s)
+ return tags[s or mouse.screen][idx]
+end
+function mtag.viewonly (idx, s)
+ local t = mtag.getn(idx, s)
+ if t then awful.tag.viewonly(t) end
end
+function mtag.viewtoggle (idx, s)
+ local t = mtag.getn(idx, s)
+ if t then awful.tag.viewtoggle(t) end
+end
+function mtag.isoccupied(s, t)
+ local clients = (t and t:clients()) or {}
+ return #clients > 0
+end
+function mtag.occupied(s)
+ local p = {}
--- Move current client to a specific screen
-function client_movetoscreen(i)
- client.focus.screen = i
+ if not s then s = mouse.screen end
+ for t in pairs(tags[s]) do
+ t = tags[s][t]
+ if mtag.isoccupied(s, t) then table.insert(p, t) end
+ end
+ return p
end
+function mtag.getnext(s)
+ if s == nil then s = mouse.screen end
--- }}}
--- {{{ Set tag names
+ local p = mtag.occupied(s)
+ local curtag = awful.tag.selected()
-for s = 1, screen.count() do
- eminent.newtag(s, 5)
- for i = 1, 10 do
- eminent.tag.name(i, s, 'work-'..i)
+ local t = 0
+
+ -- Get tag #
+ if mtag.isoccupied(s, curtag) then
+ for x in pairs(p) do
+ if curtag == p[x] then t = x end
+ end
end
+
+ local lasto = 1
+ local o = 0
+
+ for x in pairs(tags[s]) do
+ if curtag == tags[s][x] then o = x end
+ if mtag.isoccupied(s, tags[s][x]) then lasto = x end
+ end
+
+ -- Now: t is # in non-empty, o is # in all
+ if o == table.maxn(tags[s]) then
+ -- We're the last tag, create a new one
+ if t == 0 then
+ -- We're empty, go to first
+ return tags[s][1]
+ else
+ -- We're occupied, create new
+ return newtag()
+ end
+ else
+ if t == 0 then
+ -- We're empty, check if we're last
+ if o > lasto then
+ -- We're also later than the last non-empty
+ -- Wrap to first
+ return tags[s][1]
+ else
+ -- Nevermind, get the next
+ return tags[s][o+1]
+ end
+ else
+ -- Return next tag
+ return tags[s][o+1]
+ end
+ end
+end
+function mtag.next(s)
+ awful.tag.viewonly(mtag.getnext(s))
+end
+function mtag.movetonext(s)
+ local t = mtag.getnext(s)
+ awful.client.movetotag(t)
+ awful.tag.viewonly(t)
end
+function mtag.getprev(s)
+ if s == nil then s = mouse.screen end
+
+ local p = mtag.occupied(s)
+ local curtag = awful.tag.selected()
+
+ local t = 0
+
+ -- Get tag #
+ if mtag.isoccupied(s, curtag) then
+ for x in pairs(p) do
+ if curtag == p[x] then t = x end
+ end
+ end
+
+ local lasto = 1
+ local o = 0
+
+ for x in pairs(tags[s]) do
+ if curtag == tags[s][x] then o = x end
+ if mtag.isoccupied(s, tags[s][x]) then lasto = x end
+ end
+
+ -- Now: t is # in non-empty, o is # in all
+ if o == 1 then
+ -- We're the very first tag, wrap around
+ return p[ table.maxn(p) ]
+ else
+ -- We're not first, just go prev
+ return tags[s][o-1]
+ end
+end
+function mtag.prev(s)
+ awful.tag.viewonly(mtag.getprev(s))
+end
+function mtag.movetoprev(s)
+ local t = mtag.getprev(s)
+ awful.client.movetotag(t)
+ awful.tag.viewonly(t)
+end
+
-- }}}
+-- {{{ Widgets
+
+local icondir = awful.util.getdir("config").."/icons/"
+
+function make_icon(fname, left, right, h, bg)
+ local icon = image(icondir..fname)
+ local ib = widget { type = 'imagebox' }
+ local w = left + icon.width + right
+ local i = image.argb32(w, h, nil)
+
+ i:draw_rectangle(0, 0, w, h, true, beautiful.bg_normal)
+ i:insert(icon, left, math.floor((h - icon.height) / 2))
+
+ ib.image = i
+ return ib
+end
+
+function draw_dashes_h(img, x, y, on, off, len, color)
+ for i = 0, len, on + off do
+ img:draw_line(x + i, y, x + i + on - 1, y, color)
+ end
+end
+
+function draw_dashes_v(img, x, y, on, off, len, color)
+ for i = 0, len, on + off do
+ img:draw_line(x, y + i, x, y + i + on - 1, color)
+ end
+end
+
+
+local mywidgets = {}
+
-- {{{ Taglist
maintaglist = {}
awful.button(k_n, 1, awful.tag.viewonly),
awful.button(k_s, 1, awful.client.toggletag)
)
+maintaglist.label = awful.widget.taglist.label.noempty
-- }}}
--- {{{ Widgets
-
--- {{{ Load Averages Widget
-
-loadwidget = widget({
- type = 'textbox',
- name = 'gpuwidget',
- align = 'right'
-})
-
-wicked.register(loadwidget, 'function', function (widget, args)
- -- Use /proc/loadavg to get the average system load on 1, 5 and 15 minute intervals
- local f = io.open('/proc/loadavg')
- local n = f:read()
- f:close()
-
- -- Find the third space
- local pos = n:find(' ', n:find(' ', n:find(' ')+1)+1)
-
- return heading('Load')..': '..n:sub(1,pos-1)
+-- {{{ Prompt box
-end, 2)
+mypromptbox = awful.widget.prompt{
+ layout = awful.widget.layout.horizontal.leftright
+}
-- }}}
--- {{{ CPU Usage Widget
+-- {{{ CPU Widgets
+
+local cpuwidgets = {}
+for i = 1, io.popen("grep -c ^cpu /proc/stat"):read("*n") do
+ local cpu = {}
+
+ cpu.widget = widget{ type = 'imagebox' }
+ cpu.update = function(cpu, value)
+ local color
+
+ if value < 25 then
+ color = beautiful.fg_focus
+ elseif value < 50 then
+ color = 'yellow'
+ elseif value < 75 then
+ color = 'orange'
+ else
+ color = 'red'
+ end
-cputextwidget = widget({
- type = 'textbox',
- name = 'cputextwidget',
- align = 'right'
-})
+ if cpu.color == color then return end
+ local img = image.argb32(11, 16, nil)
+ draw_dashes_h(img, 0, 4, 2, 1, 7, color)
+ draw_dashes_h(img, 0, 11, 2, 1, 7, color)
+ draw_dashes_v(img, 0, 4, 2, 1, 7, color)
+ draw_dashes_v(img, 7, 4, 2, 1, 7, color)
+ img:draw_rectangle(2, 6, 4, 4, true, color)
+ cpu.widget.image = img
+ cpu.percent = value
+ end
+ table.insert(mywidgets, cpu.widget)
+ cpuwidgets[i] = cpu
+end
-cputextwidget.text = heading('CPU')..': 00% '
-wicked.register(cputextwidget, 'cpu', function (widget, args)
+cputextwidget = widget{ type = 'textbox' }
+
+vicious.register(cputextwidget, vicious.widgets.cpu,
+function (widget, args)
local r = tonumber(args[1])
local percent = args[1]..'%'
+
+ for i = 1, #args do
+ cpuwidgets[i]:update(args[i])
+ end
+
if r < 10 then
percent = '0'..percent
end
if r < 25 then
- percent = fg('green', percent)
+ percent = fg(beautiful.fg_focus, percent)
elseif r < 50 then
percent = fg('yellow', percent)
elseif r < 75 then
else
percent = fg('red', percent)
end
- return heading('CPU')..': '..percent..' '
+ return percent..' '
end, 2)
--- }}}
--- {{{ CPU Graph Widget
-
-cpugraphwidget = widget({
- type = 'graph',
- name = 'cpugraphwidget',
- align = 'right'
-})
-
-cpugraphwidget.height = 0.85
-cpugraphwidget.width = 45
-cpugraphwidget.bg = '#333333'
-cpugraphwidget.border_color = '#0a0a0a'
-cpugraphwidget.grow = 'right'
-
-cpugraphwidget:plot_properties_set('cpu', {
- fg = '#AEC6D8',
- fg_center = '#285577',
- fg_end = '#285577',
- vertical_gradient = false
-})
-
-wicked.register(cpugraphwidget, 'cpu', '$1', 2, 'cpu')
+table.insert(mywidgets, cputextwidget)
-- }}}
-- {{{ Memory Usage Widget
-memtextwidget = widget({
- type = 'textbox',
- name = 'memtextwidget',
- align = 'right'
-})
+table.insert(mywidgets, make_icon('mem.png', 16, 4, 16))
+
+memtextwidget = widget{ type = 'textbox' }
-memtextwidget.text = heading('MEM')..': '
-wicked.register(memtextwidget, 'mem', function (widget, args)
+vicious.register(memtextwidget, vicious.widgets.mem, function (widget, args)
-- Add extra preceding zeroes when needed
local r = tonumber(args[1])
local percent = args[1]..'%'
percent = '0'..percent
end
if r < 50 then
- percent = fg('green', percent)
+ percent = fg(beautiful.fg_focus, percent)
elseif r < 80 then
percent = fg('orange', percent)
else
percent = fg('red', percent)
end
- return heading('MEM')..': '..percent..' '..args[2]..'M'
+ return percent..' '..args[2]..'M'
end, 2)
--- }}}
--- {{{ Battery widget
---[[
-batterywidget = widget({
- type = 'textbox',
- name = 'batterywidget',
- align = 'right'
-})
-
-function batterywidget_update()
- local v = io.popen("powersave -b|sed -ne 's/.*Remaining percent: \\(.*\\)/\\1/p'"):read()
- local r = tonumber(v)
-
- percent = v
- if r < 10 then
- percent = fg('red', percent)
- elseif r < 25 then
- percent = fg('orange', percent)
- else
- percent = fg('green', percent)
- end
- batterywidget.text = heading('BAT')..': '..percent
-end
-batterywidget_update()
-awful.hooks.timer.register(30, batterywidget_update)
---]]
--- }}}
--- {{{ spacers
-
-rspacer = widget({ type = 'textbox', name = 'rspacer', align = 'right' })
-rspacer.text = " │ "
+table.insert(mywidgets, memtextwidget)
-- }}}
-- {{{ Clock
-clockwidget = widget({ type = "textbox", name = "clockwidget", align = "right" })
-clock_update = function()
- clockwidget.text = fg("#dddddd", os.date("%a %d %b - %H:%M"))
-end
-clock_update()
-awful.hooks.timer.register(10, clock_update)
--- }}}
+table.insert(mywidgets, make_icon('clock.png', 16, 4, 16))
-mymenubox = widget{ type = "textbox", name = "mytextbox", align = "left" }
--- mysystray = widget{ type = "systray", name = "mysystray", align = "right" }
+clockwidget = widget{ type = "textbox" }
+vicious.register(clockwidget, vicious.widgets.date,
+ fg(theme.fg_focus, "%H:%M") .. " %a %d %b ", 10)
--- {{{ Statusbar
+table.insert(mywidgets, clockwidget)
-mainstatusbar = {}
+-- }}}
+-- {{{ Statusbar
for s = 1, screen.count() do
- mainstatusbar[s] = wibox{
- position = "top",
- height = 18,
- name = "mainstatusbar" .. s,
+ local tab = {
+ {
+ awful.widget.taglist(s, maintaglist.label, maintaglist.buttons),
+ mypromptbox.widget,
+ layout = awful.widget.layout.horizontal.leftright
+ },
}
- mainstatusbar[s].widgets = {
- awful.widget.taglist.new(s, awful.widget.taglist.label.noempty, maintaglist.buttons),
- maintaglist,
- mymenubox,
-
- rspacer, loadwidget,
- rspacer, cputextwidget, cpugraphwidget,
- rspacer, memtextwidget,
- rspacer, clockwidget,
- s == 1 and rspacer or nil,
- s == 1 and mysystray or nil,
- }
- mainstatusbar[s].screen = s
+ if (s == 1) then
+ table.insert(tab, widget{ type = 'systray' })
+ end
+ for i = #mywidgets, 1, -1 do
+ table.insert(tab, mywidgets[i])
+ end
+ tab["layout"] = awful.widget.layout.horizontal.rightleft
+ awful.wibox{ position = "top", height = 16, screen = s }.widgets = tab
end
-- }}}
-- }}}
-
-- {{{ Keys
---- {{{ Global keys
-local hist = os.getenv("HOME") .. "/.cache/awesome/history"
globalkeys = awful.util.table.join(
-- Mod+{A/S}: Switch to prev/next tag
- awful.key(k_m, "Left", eminent.tag.prev),
- awful.key(k_m, "Right", eminent.tag.next),
+ awful.key(k_m, "Left", mtag.prev),
+ awful.key(k_m, "Right", mtag.next),
-- Mod+Shift+{A/S}: Move window to Prev/Next tag
- awful.key(k_ms, "Left", function()
- awful.client.movetotag(eminent.tag.getprev())
- eminent.tag.prev()
- end),
- awful.key(k_ms, "Right", function()
- awful.client.movetotag(eminent.tag.getnext())
- eminent.tag.next()
- end),
+ awful.key(k_ms, "Left", mtag.movetoprev),
+ awful.key(k_ms, "Right", mtag.movetonext),
-- Mod+Shift_{E/D}: move window to next/prev screen
awful.key(k_mc, "Right", function()
- local s = getscreen() + 1
- while s > screen.count() do
- s = s-screen.count()
- end
- client_movetoscreen(s)
+ client.focus.screen = awful.util.cycle(screen.count(), mouse.screen + 1)
end),
awful.key(k_mc, "Left", function()
- local s = getscreen() - 1
- while s < 1 do
- s = s+screen.count()
- end
- client_movetoscreen(s)
+ client.focus.screen = awful.util.cycle(screen.count(), mouse.screen - 1)
end),
awful.key(k_ms, "k", function () awful.client.swap.byidx(-1) end),
-- Mod+{E/D}: Switch to next/previous screen
- awful.key(k_m, "Tab", function () awful.screen.focus(1) end),
- awful.key(k_ms, "Tab", function () awful.screen.focus(-1) end),
+ awful.key(k_m, "Tab", function () awful.screen.focus_relative(1) end),
+ awful.key(k_ms, "Tab", function () awful.screen.focus_relative(-1) end),
-- Mod+Enter: Launch a new terminal
- awful.key(k_m, "e", function() awful.util.spawn("firefox") end),
+ awful.key(k_m, "e", function() awful.util.spawn("chromium-browser") end),
awful.key(k_m, "Return", function() awful.util.spawn(terminal) end),
awful.key(k_ac, "r", awesome.restart),
awful.key(k_m, "F12", function() awful.util.spawn(lock) end),
awful.key(k_mc, "l", function () awful.tag.incncol(-1) end),
-- Menu
- awful.key(k_m, "r",
- function ()
- awful.prompt.run({ prompt = "Run: " },
- mymenubox,
- awful.util.spawn,
- awful.completion.bash,
- awful.util.getdir("cache").."/commands")
- end),
+ awful.key(k_m, "r", function () mypromptbox:run() end),
awful.key(k_m, "F4",
function ()
awful.prompt.run({ prompt = "Run Lua code: " },
- mymenubox,
- awful.util.eval,
- awful.prompt.bash,
+ mypromptbox.widget,
+ awful.util.eval, nil,
awful.util.getdir("cache").."/lua_commands")
end),
- awful.key({}, "#192", function() eminent.tag.goto(1, nil, true) end),
- awful.key({}, "#193", function() eminent.tag.goto(2, nil, true) end),
- awful.key({}, "#194", function() eminent.tag.goto(3, nil, true) end),
- awful.key({}, "#195", function() eminent.tag.goto(4, nil, true) end),
- awful.key({}, "#196", function() eminent.tag.goto(5, nil, true) end)
+ awful.key({}, "#192", function() mtag.viewonly(1) end),
+ awful.key({}, "#193", function() mtag.viewonly(2) end),
+ awful.key({}, "#194", function() mtag.viewonly(3) end),
+ awful.key({}, "#195", function() mtag.viewonly(4) end),
+ awful.key({}, "#196", function() mtag.viewonly(5) end)
)
-- Mod+#: Switch to tag
for i = 1, 10 do
globalkeys = awful.util.table.join(
globalkeys,
- awful.key(k_m, i % 10,
- function()
- eminent.tag.goto(i, nil, true)
- end),
-
- awful.key(k_ms, i % 10,
- function ()
- local t = eminent.tag.getn(i, nil, true)
- if t ~= nil then t.selected = not t.selected end
- end),
+ awful.key(k_m, i % 10, function() mtag.viewonly(i) end),
+ awful.key(k_ms, i % 10, function() mtag.viewtoggle(i) end),
awful.key(k_mc, i % 10,
- function ()
- local t = eminent.tag.getn(i, nil, true)
- if t ~= nil then awful.client.movetotag(t) end
- end)
+ function ()
+ if client.focus and tags[client.focus.screen][i] then
+ awful.client.movetotag(tags[client.focus.screen][i])
+ end
+ end),
+ awful.key(k_mcs, i % 10,
+ function ()
+ if client.focus and tags[client.focus.screen][i] then
+ awful.client.toggletag(tags[client.focus.screen][i])
+ end
+ end)
)
end
---- }}}
----- {{{ Client hotkeys
+---- {{{ Client hotkeys / buttons
-clientkeys = awful.util.table.join(
+local clientkeys = awful.util.table.join(
awful.key(k_m, "i", function (c)
- if mymenubox.text then
- mymenubox.text = ""
+ if mypromptbox.widget.text then
+ mypromptbox.widget.text = ""
else
- mymenubox.text = "Class: " .. c.class .. " Instance: ".. c.instance
+ mypromptbox.widget.text = "Class: " .. c.class .. " Instance: ".. c.instance
end
end),
-- Client manipulation
awful.key(k_m, "c", function (c) c:kill() end),
awful.key(k_m, "o", awful.client.floating.toggle),
- awful.key(k_m, "t", awful.client.togglemarked),
awful.key(k_m, "F11", function (c) c.fullscreen = not c.fullscreen end)
)
+local clientbuttons = awful.util.table.join(
+ awful.button({ }, 1, function (c) client.focus = c; c:raise() end),
+ awful.button(k_a, 1, awful.mouse.client.move),
+ awful.button(k_a, 3, awful.mouse.client.resize)
+)
+
---- }}}
root.keys(globalkeys)
-- }}}
--- {{{ Hooks
+-- {{{ Rules
+
+awful.rules.rules = {
+ -- All clients will match this rule.
+ {
+ rule = { },
+ properties = {
+ border_width = beautiful.border_width,
+ border_color = beautiful.border_normal,
+ focus = true,
+ keys = clientkeys,
+ buttons = clientbuttons,
+ size_hints_honor = false,
+ }
+ },
+ { rule = { class = "MPlayer" }, properties = { floating = true } },
+ { rule = { class = "pinentry" }, properties = { floating = true } },
+ -- Set Firefox to always map on tags number 2 of screen 1.
+ -- { rule = { class = "Firefox" },
+ -- properties = { tag = tags[1][2] } },
+}
+
+-- }}}
+-- {{{ Signals
-awful.hooks.focus.register(function (c)
+function warp_mouse(c)
+ local o = mouse.object_under_pointer()
+ if not o or (o ~= c and type(o) == "client") then
+ local g = c:geometry()
+ mouse.coords({ x = g.x + 5, y = g.y + 5 }, true)
+ end
+end
+
+client.add_signal("focus", function (c)
if not awful.client.ismarked(c) then
c.border_color = beautiful.border_focus
end
+ warp_mouse(c)
end)
-awful.hooks.unfocus.register(function (c)
+client.add_signal("unfocus", function (c)
if not awful.client.ismarked(c) then
c.border_color = beautiful.border_normal
end
end)
-awful.hooks.marked.register(function (c)
- c.border_color = beautiful.border_marked
-end)
-
-awful.hooks.unmarked.register(function (c)
- c.border_color = beautiful.border_focus
-end)
-
--- Hook function to execute when the mouse enters a client.
-awful.hooks.mouse_enter.register(function (c)
- -- Sloppy focus
- client.focus = c
+client.add_signal("manage", function (c, startup)
+ c:add_signal("mouse::enter", function(c) client.focus = c end)
end)
-awful.hooks.manage.register(function (c, startup)
- if not startup and awful.client.focus.filter(c) then
- c.screen = mouse.screen
- end
-
- -- Add mouse bindings
- c:buttons(awful.util.table.join(
- awful.button({ }, 1, function (c) client.focus = c; c:raise() end),
- awful.button(k_a, 1, awful.mouse.client.move),
- awful.button(k_a, 3, awful.mouse.client.resize)
- ))
-
- -- Create border
- c.border_width = beautiful.border_width
- c.border_color = beautiful.border_normal
-
- -- Make certain windows floating
- local class = c.class:lower()
- if class:find('pinentry')
- or class:find('kcalc')
- or class:find('gajim')
- then
- c.floating = true
- end
-
- -- Focus new clients
- client.focus = c
- c:keys(clientkeys)
- c.size_hints_honor = false
-end)
-
--- Hook function to execute when arranging the screen
--- (tag switch, new client, etc)
-awful.hooks.arrange.register(function (screen)
- local sel = client.focus
-
- if not sel then
- sel = awful.client.focus.history.get(screen, 0)
- if not sel then return end
- client.focus = sel
- end
-
- local o = mouse.object_under_pointer()
- if not o or (type(o) == "client" and o ~= sel) then
- local g = sel:geometry()
-
- mouse.coords { x = g.x + 5, y = g.y + 5 }
- end
-end)
+for s = 1, screen.count() do
+ screen[s]:add_signal("arrange", function ()
+ if client.focus and client.focus.screen == s then
+ warp_mouse(client.focus)
+ end
+ end)
+end
-- }}}
awful.util.spawn("xkbcomp -w 0 -R/usr/share/X11/xkb /home/madcoder/.Xkeyboard :0")
+awful.util.spawn("xsetroot -cursor_name left_ptr")