Initial commit

This commit is contained in:
crater2150 2009-10-24 16:50:19 +00:00
commit 344d6d533a
86 changed files with 4184 additions and 0 deletions

469
back.rc.lua Normal file
View file

@ -0,0 +1,469 @@
-- Standard awesome library
require("awful")
-- Theme handling library
require("beautiful")
-- Notification library
require("naughty")
-- Load Debian menu entries
require("debian.menu")
-- {{{ Variable definitions
-- Themes define colours, icons, and wallpapers
-- The default is a dark theme
theme_path = "/home/jack/.config/awesome/theme.lua"
-- Uncommment this for a lighter theme
-- theme_path = "/usr/share/awesome/themes/sky/theme.lua"
-- Actually load theme
beautiful.init(theme_path)
-- This is used later as the default terminal and editor to run.
terminal = "x-terminal-emulator"
editor = os.getenv("EDITOR") or "editor"
editor_cmd = terminal .. " -e " .. editor
-- Default modkey.
-- Usually, Mod4 is the key with a logo between Control and Alt.
-- If you do not like this or do not have such a key,
-- I suggest you to remap Mod4 to another key using xmodmap or other tools.
-- However, you can use another modifier like Mod1, but it may interact with others.
modkey = "Mod1"
-- Table of layouts to cover with awful.layout.inc, order matters.
layouts =
{
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.max,
awful.layout.suit.max.fullscreen,
awful.layout.suit.magnifier,
awful.layout.suit.floating
}
-- Table of clients that should be set floating. The index may be either
-- the application class or instance. The instance is useful when running
-- a console app in a terminal like (Music on Console)
-- x-terminal-emulator -name mocp -e mocp
floatapps =
{
-- by class
["MPlayer"] = true,
["pinentry"] = true,
["gimp"] = true,
-- by instance
["mocp"] = true
}
-- Applications to be moved to a pre-defined tag by class or instance.
-- Use the screen and tags indices.
apptags =
{
-- ["Firefox"] = { screen = 1, tag = 2 },
-- ["mocp"] = { screen = 2, tag = 4 },
}
-- Define if we want to use titlebar on all applications.
use_titlebar = false
-- }}}
-- {{{ Tags
-- Define tags table.
tags = {}
tags.setup = {
{ name = "terms" },
{ name = "web" },
{ name = "music" },
{ name = "dls" },
{ name = "files" },
{ name = "images" },
{ name = "videos" },
{ name = "exps" },
{ name = "other" },
{ name = "nil" }
}
for s = 1, screen.count() do
tags[s] = {}
for i, t in ipairs(tags.setup) do
tags[s][i] = tag({ name = t.name })
tags[s][i].screen = s
awful.layout.set(layouts[1], tags[s][i])
end
tags[s][1].selected = true
end
--local tags = {}
-- tags.setup = {
-- { name = "term", layout = layouts[3] },
-- { name = "emacs", layout = layouts[1] },
-- { name = "web", layout = layouts[1] },
--{ name = "mail", layout = layouts[5] },
--{ name = "im", layout = layouts[1], mwfact = 0.13 },
-- { name = "6", layout = layouts[7], hide = true },
-- { name = "7", layout = layouts[7], hide = true },
-- { name = "rss", layout = layouts[6] },
-- { name = "media", layout = layouts[7] }
-- }
-- for s = 1, screen.count() do
-- tags[s] = {}
-- for i, t in ipairs(tags.setup) do
-- tags[s][i] = tag({ name = t.name })
-- tags[s][i].screen = s
-- awful.tag.setproperty(tags[s][i], "layout", t.layout)
-- awful.tag.setproperty(tags[s][i], "mwfact", t.mwfact)
-- awful.tag.setproperty(tags[s][i], "hide", t.hide)
-- end
-- tags[s][1].selected = true
-- end
-- }}}
-- {{{ Wibox
-- Create a textbox widget
mytextbox = widget({ type = "textbox", align = "right" })
-- Set the default text in textbox
mytextbox.text = " loading... "
-- Create a laucher widget and a main menu
myawesomemenu = {
{ "manual", terminal .. " -e man awesome" },
{ "edit config", editor_cmd .. " " .. awful.util.getdir("config") .. "/rc.lua" },
{ "restart", awesome.restart },
{ "quit", awesome.quit }
}
mymainmenu = awful.menu.new({ items = { { "awesome", myawesomemenu, beautiful.awesome_icon },
{ "open terminal", terminal },
{ "Debian", debian.menu.Debian_menu.Debian }
}
})
mylauncher = awful.widget.launcher({ image = image(beautiful.awesome_icon),
menu = mymainmenu })
-- Create a systray
mysystray = widget({ type = "systray", align = "right" })
-- Create a wibox for each screen and add it
mywibox = {}
mypromptbox = {}
mylayoutbox = {}
mytaglist = {}
mytaglist.buttons = awful.util.table.join(
awful.button({ }, 1, awful.tag.viewonly),
awful.button({ modkey }, 1, awful.client.movetotag),
awful.button({ }, 3, function (tag) tag.selected = not tag.selected end),
awful.button({ modkey }, 3, awful.client.toggletag),
awful.button({ }, 4, awful.tag.viewnext),
awful.button({ }, 5, awful.tag.viewprev)
)
mytasklist = {}
mytasklist.buttons = awful.util.table.join(
awful.button({ }, 1, function (c)
if not c:isvisible() then
awful.tag.viewonly(c:tags()[1])
end
client.focus = c
c:raise()
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({ align = "left" })
-- Create an imagebox widget which will contains an icon indicating which layout we're using.
-- We need one layoutbox per screen.
mylayoutbox[s] = widget({ type = "imagebox", align = "right" })
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)))
-- Create a taglist widget
mytaglist[s] = awful.widget.taglist(s, awful.widget.taglist.label.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)
-- Create the wibox
mywibox[s] = wibox({ position = "top", fg = beautiful.fg_normal, bg = beautiful.bg_normal })
-- Add widgets to the wibox - order matters
mywibox[s].widgets = { mylauncher,
mytaglist[s],
--mylayoutbox[s],
--mytasklist[s],
mypromptbox[s],
mytextbox,
s == 1 and mysystray or nil }
mywibox[s].screen = s
end
-- }}}
-- {{{ Mouse bindings
root.buttons(awful.util.table.join(
awful.button({ }, 3, function () mymainmenu:toggle() end),
awful.button({ }, 4, awful.tag.viewnext),
awful.button({ }, 5, awful.tag.viewprev)
))
-- }}}
-- {{{ Key bindings
globalkeys = awful.util.table.join(
awful.key({ modkey, }, "comma", awful.tag.viewprev ),
awful.key({ modkey, }, "period", awful.tag.viewnext ),
awful.key({ modkey, }, "Escape", awful.tag.history.restore),
awful.key({ modkey, }, "t",
function ()
awful.client.focus.byidx( 1)
if client.focus then client.focus:raise() end
end),
awful.key({ modkey, }, "n",
function ()
awful.client.focus.byidx(-1)
if client.focus then client.focus:raise() end
end),
awful.key({ modkey, }, "w", function () mymainmenu:show(true) end),
-- Layout manipulation
awful.key({ modkey, "Shift" }, "t", function () awful.client.swap.byidx( 1) end),
awful.key({ modkey, "Shift" }, "n", function () awful.client.swap.byidx( -1) end),
awful.key({ modkey, "Control" }, "t", function () awful.screen.focus( 1) end),
awful.key({ modkey, "Control" }, "n", function () awful.screen.focus(-1) end),
awful.key({ modkey, }, "u", awful.client.urgent.jumpto),
awful.key({ modkey, }, "Tab",
function ()
awful.client.focus.history.previous()
if client.focus then
client.focus:raise()
end
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),
awful.key({ modkey, }, "s", function () awful.tag.incmwfact( 0.05) end),
awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end),
awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1) end),
awful.key({ modkey, "Shift" }, "s", function () awful.tag.incnmaster(-1) end),
awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1) end),
awful.key({ modkey, "Control" }, "s", function () awful.tag.incncol(-1) end),
awful.key({ modkey, }, "space", function () awful.layout.inc(layouts, 1) end),
awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(layouts, -1) end),
-- Prompt
awful.key({ modkey }, "apostrophe", function () mypromptbox[mouse.screen]:run() end),
awful.key({ modkey }, "x",
function ()
awful.prompt.run({ prompt = "Run Lua code: " },
mypromptbox[mouse.screen].widget,
awful.util.eval, nil,
awful.util.getdir("cache") .. "/history_eval")
end)
)
-- Client awful tagging: this is useful to tag some clients and then do stuff like move to tag on them
clientkeys = awful.util.table.join(
awful.key({ modkey, }, "f", function (c) c.fullscreen = not c.fullscreen end),
awful.key({ modkey, }, "semicolon", function (c) c:kill() end),
awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle ),
awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end),
awful.key({ modkey, }, "o", awful.client.movetoscreen ),
awful.key({ modkey, "Shift" }, "r", function (c) c:redraw() end),
awful.key({ modkey }, "w", awful.client.togglemarked),
awful.key({ modkey,}, "m",
function (c)
c.maximized_horizontal = not c.maximized_horizontal
c.maximized_vertical = not c.maximized_vertical
end)
)
-- Compute the maximum number of digit we need, limited to 9
keynumber = 0
for s = 1, screen.count() do
keynumber = math.min(9, math.max(#tags[s], keynumber));
end
for i = 1, keynumber do
globalkeys = awful.util.table.join(globalkeys,
awful.key({ modkey }, i,
function ()
local screen = mouse.screen
if tags[screen][i] then
awful.tag.viewonly(tags[screen][i])
end
end),
awful.key({ modkey, "Control" }, i,
function ()
local screen = mouse.screen
if tags[screen][i] then
tags[screen][i].selected = not tags[screen][i].selected
end
end),
awful.key({ modkey, "Shift" }, i,
function ()
if client.focus and tags[client.focus.screen][i] then
awful.client.movetotag(tags[client.focus.screen][i])
end
end),
awful.key({ modkey, "Control", "Shift" }, i,
function ()
if client.focus and tags[client.focus.screen][i] then
awful.client.toggletag(tags[client.focus.screen][i])
end
end),
awful.key({ modkey, "Shift" }, "F" .. i,
function ()
local screen = mouse.screen
if tags[screen][i] then
for k, c in pairs(awful.client.getmarked()) do
awful.client.movetotag(tags[screen][i], c)
end
end
end))
end
-- Set keys
root.keys(globalkeys)
-- }}}
-- {{{ Hooks
-- Hook function to execute when focusing a client.
awful.hooks.focus.register(function (c)
if not awful.client.ismarked(c) then
c.border_color = beautiful.border_focus
end
end)
-- Hook function to execute when unfocusing a client.
awful.hooks.unfocus.register(function (c)
if not awful.client.ismarked(c) then
c.border_color = beautiful.border_normal
end
end)
-- Hook function to execute when marking a client
awful.hooks.marked.register(function (c)
c.border_color = beautiful.border_marked
end)
-- Hook function to execute when unmarking a client.
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, but disabled for magnifier layout
if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
and awful.client.focus.filter(c) then
client.focus = c
end
end)
-- Hook function to execute when a new client appears.
awful.hooks.manage.register(function (c, startup)
-- If we are not managing this application at startup,
-- move it to the screen where the mouse is.
-- We only do it for filtered windows (i.e. no dock, etc).
if not startup and awful.client.focus.filter(c) then
c.screen = mouse.screen
end
if use_titlebar then
-- Add a titlebar
awful.titlebar.add(c, { modkey = modkey })
end
-- Add mouse bindings
c: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)
))
-- New client may not receive focus
-- if they're not focusable, so set border anyway.
c.border_width = beautiful.border_width
c.border_color = beautiful.border_normal
-- Check if the application should be floating.
local cls = c.class
local inst = c.instance
if floatapps[cls] ~= nil then
awful.client.floating.set(c, floatapps[cls])
elseif floatapps[inst] ~= nil then
awful.client.floating.set(c, floatapps[inst])
end
-- Check application->screen/tag mappings.
local target
if apptags[cls] then
target = apptags[cls]
elseif apptags[inst] then
target = apptags[inst]
end
if target then
c.screen = target.screen
awful.client.movetotag(tags[target.screen][target.tag], c)
end
c.size_hints_honor = false
-- Do this after tag mapping, so you don't see it on the wrong tag for a split second.
client.focus = c
-- Set key bindings
c:keys(clientkeys)
-- Set the windows at the slave,
-- i.e. put it at the end of others instead of setting it master.
-- awful.client.setslave(c)
-- Honor size hints: if you want to drop the gaps between windows, set this to false.
-- 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 layout = awful.layout.getname(awful.layout.get(screen))
if layout and beautiful["layout_" ..layout] then
mylayoutbox[screen].image = image(beautiful["layout_" .. layout])
else
mylayoutbox[screen].image = nil
end
-- Give focus to the latest client in history if no window has focus
-- or if the current window is a desktop or a dock one.
if not client.focus then
local c = awful.client.focus.history.get(screen, 0)
if c then client.focus = c end
end
end)
-- Hook called every minute
awful.hooks.timer.register(10, function ()
awful.util.spawn("awst")
end)
-- }}}

437
gitrc.lua Normal file
View file

@ -0,0 +1,437 @@
--###
-- Standard awesome library
require("awful")
-- Theme handling library
require("beautiful")
-- Notification library
require("naughty")
-- Dynamic tagging with shifty
require("lib/shifty")
-- Wicked
require("wicked")
-- {{{ Variable definitions
-- Themes define colours, icons, and wallpapers
-- Just link your theme to ~/.awesome_theme
theme_path = os.getenv("HOME") .. "/.config/awesome/theme.lua"
-- Actually load theme
beautiful.init(theme_path)
-- Default applications
terminal = "terminal"
-- Editor to use
editor = "terminal -e vim"
-- this is the default level when adding a todo note
todo_level = "high"
-- Default modkey. l
-- Usually, Mod4 is the key with a logo between Control and Alt.
-- If you do not like this or do not have such a key,
-- I suggest you to remap Mod4 to another key using xmodmap or other tools.
-- However, you can use another modifier like Mod1, but it may interact with others.
modkey = "Mod1"
-- Table of layouts to cover with awful.layout.inc, order matters.
layouts =
{
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.max,
awful.layout.suit.max.fullscreen,
awful.layout.suit.floating
}
-- Table of clients that should be set floating. The index may be either
-- the application class or instance. The instance is useful when running
-- a console app in a terminal like (Music on Console)
-- xterm -name mocp -e mocp
floatapps =
{
-- by class
["MPlayer"] = true,
["Xmessage"] = true,
["Wireshark"] = true,
["XBoard"] = true,
["feh"] = true,
["nitrogen"] = true,
["Wicd-client.py"] = true,
["gimp"] = true,
["XCalc"] = true,
["display"] = true,
["Preferences"] = true,
["XClipboard"] = true,
["Imagemagick"] = true,
["Snes9X"] = true,
["Add-ons"] = true,
["Wine desktop"] = true
}
-- Define if we want to use titlebar on all applications.
use_titlebar = false
-- }}}
--{{{ Shifty
shifty.config.defaults = {
layout = "tilebottom",
}
shifty.config.tags = {
["1:terms"] = { init = true, },
["2:web"] = { init = true, nopopup = true },
["3:music"] = { init =false, nopopup = true, position = 3, spawn = "ario" },
["4:dls"] = { init =false, nopopup =false, position = 4, spawn = "dtella && linuxdcpp" },
["5:files"] = { init =false, nopopup =false, position = 5 },
["6:images"] = { init =false, nopopup =false, position = 6, layout = "float" },
["7:videos"] = { init =false, nopopup =false, position = 7, layout = "float" },
["8:exps"] = { init =false, nopopup =false, position = 8, layout = "float" },
["9:work"] = { init =false, nopopup =false, position = 9 },
}
shifty.config.apps = {
{ match = { "VLC.*" }, float = true },
{ match = { "" }, honorsizehints= false,
buttons = {
button({ }, 1, function (c) client.focus = c; c:raise() end),
button({ modkey }, 1, function (c) awful.mouse.client.move() end),
button({ modkey }, 3, awful.mouse.client.resize ), }, },
}
-- tag defaults
shifty.config.defaults = {
layout = "tilebottom",
ncol = 1,
floatBars = true,
}
shifty.config.layouts = layouts
shifty.config.guess_position = true
shifty.config.remember_index = true
shifty.init()
-- }}}
-- {{{ Widgets
-- Create a systray
mysystray = widget({ type = "systray", align = "right" })
-- Create a wibox for each screen and add it
mywibox = {}
mypromptbox = {}
mylayoutbox = {}
mytaglist = {}
mytaglist.buttons = { button({ }, 1, awful.tag.viewonly),
button({ modkey }, 1, awful.client.movetotag),
button({ }, 3, function (tag) tag.selected = not tag.selected end),
button({ modkey }, 3, awful.client.toggletag),
button({ }, 4, awful.tag.viewnext),
button({ }, 5, awful.tag.viewprev) }
shifty.taglist = mytaglist
mytasklist = {}
mytasklist.buttons = { button({ }, 1, function (c) client.focus = c; c:raise() end),
button({ }, 3, function () awful.menu.clients({ width=250 }) end),
button({ }, 4, function () awful.client.focus.byidx(1) end),
button({ }, 5, function () awful.client.focus.byidx(-1) end) }
for s = 1, screen.count() do
-- Create a promptbox for each screen
mypromptbox[s] = widget({ type = "textbox" })
-- Create a datebox widget
datebox = widget({ type = "textbox", align = "right" })
-- Create an imagebox widget which will contains an icon indicating which layout we're using.
-- We need one layoutbox per screen.
mylayoutbox[s] = widget({ type = "imagebox" })
mylayoutbox[s]:buttons({ button({ }, 1, function () awful.layout.inc(layouts, 1) end),
button({ }, 3, function () awful.layout.inc(layouts, -1) end),
button({ }, 4, function () awful.layout.inc(layouts, 1) end),
button({ }, 5, function () awful.layout.inc(layouts, -1) end) })
-- Create a taglist widget
mytaglist[s] = awful.widget.taglist.new(s, awful.widget.taglist.label.all, mytaglist.buttons)
-- Create a tasklist widget
mytasklist[s] = awful.widget.tasklist.new(function(c)
return awful.widget.tasklist.label.currenttags(c, s)
end, mytasklist.buttons)
--}}}
--{{{ Wibox
mywibox[s] = wibox({ position = "top", fg = beautiful.fg_normal, bg = beautiful.bg_normal })
-- Add widgets to the wibox - order matters
mywibox[s].widgets = {
mylayoutbox[s],
mytaglist[s],
mypromptbox[s],
mysystray,
datebox,
}
mywibox[s].screen = s
end
--}}}
--{{{ Functions
--{{{ Add a todo note
function addtodo (todo)
infobox.text = "| <b><u>todo:</u></b> " .. "<span color='#FF00FF'>" .. awful.util.spawn("todo --add --priority high " .. "'" .. todo .. "'") .. "</span>"
end
--}}}
--{{{ Show todos
function show_todo()
local todo = awful.util.pread("todo --mono")
todo = naughty.notify({
text = string.format(os.date("%a, %d %B %Y") .. "\n" .. todo),
timeout = 6,
width = 300,
})
end
--}}}
--}}}
--{{{ Keybindings
-- {{{ Mouse bindings
root.buttons(awful.util.table.join(
awful.button({ }, 4, awful.tag.viewnext),
awful.button({ }, 5, awful.tag.viewprev)
))
-- }}}
-- {{{ Key bindings
globalkeys = awful.util.table.join(
-- Bindings for shifty
awful.key({ modkey, }, "comma", awful.tag.viewprev ),
awful.key({ modkey, "Shift" }, "comma", shifty.shift_prev ),
awful.key({ modkey, "Shift" }, "period", shifty.shift_next ),
awful.key({ modkey, }, "period", awful.tag.viewnext ),
awful.key({ modkey, }, "Escape", awful.tag.history.restore),
awful.key({ modkey }, "t", function() shifty.add({ rel_index = 1 }) end),
awful.key({ modkey, "Control" }, "t", function() shifty.add({ rel_index = 1, nopopup = true }) end),
awful.key({ modkey }, "r", shifty.rename),
awful.key({ modkey }, "w", shifty.delete),
awful.key({ modkey, "Shift" }, "o", function() shifty.set(awful.tag.selected(mouse.screen), { screen = awful.util.cycle(screen.count() , mouse.screen + 1) }) end),
awful.key({ modkey, }, "y", function() list = naughty.notify({
text = get_albumart(),
width = 400 }) end),
awful.key({ modkey, }, "j",
function ()
awful.client.focus.byidx( 1)
if client.focus then client.focus:raise() end
end),
awful.key({ modkey, }, "k",
function ()
awful.client.focus.byidx(-1)
if client.focus then client.focus:raise() end
end),
-- Layout manipulation
awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end),
awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( -1) end),
awful.key({ modkey, "Control" }, "j", function () awful.screen.focus( 1) end),
awful.key({ modkey, "Control" }, "k", function () awful.screen.focus(-1) end),
awful.key({ modkey, "Shift" }, "u", awful.client.urgent.jumpto),
awful.key({ modkey, }, "Tab",
function ()
awful.client.focus.byidx( 1)
if client.focus then client.focus:raise() end
end),
awful.key({ modkey, "Shift" }, "Tab",
function ()
awful.client.focus.byidx(-1)
if client.focus then client.focus:raise() end
end),
-- Standard program
awful.key({ modkey, }, "Return", function () awful.util.spawn(terminal) end),
awful.key({ modkey, "Shift" }, "Return", function () awful.util.spawn(editor) end),
awful.key({ modkey, "Control" }, "r", awesome.restart),
awful.key({ modkey, "Shift" }, "q", awesome.quit),
-- display playlist
awful.key({ modkey, }, "p", function() list = naughty.notify({
text = get_playlist(),
width = 400 }) end),
-- Display the todo list
awful.key({ modkey, }, "d", function () show_todo() end),
-- Paste content of the xbuffer
awful.key({ modkey, "Control" }, "p", function ()
awful.prompt.run({ prompt = "<b>Paste to:</b> "},
mypromptbox[mouse.screen],
function (s) paste(s) end,
awful.completion.shell) end),
-- Lock the screen
awful.key({ modkey }, "t", function() shifty.add({ rel_index = 1 }) end),
awful.key({ modkey, "Control" }, "t", function() shifty.add({ rel_index = 1, nopopup = true }) end),
awful.key({ modkey }, "r", shifty.rename),
awful.key({ modkey }, "w", shifty.del),
awful.key({ modkey, "Control" }, "o", function () shifty.set(awful.tag.selected(mouse.screen), { screen = awful.util.cycle(mouse.screen + 1, screen.count()) }) end),
awful.key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end),
awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end),
awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1) end),
awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1) end),
awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1) end),
awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1) end),
awful.key({ modkey, }, "space", function () awful.layout.inc(layouts, 1) end),
awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(layouts, -1) end),
-- Prompt
-- add a todo
awful.key({ modkey, "Shift" }, "d",
function ()
awful.prompt.run({ prompt = " Add Todo Note: " },
mypromptbox[mouse.screen],
addtodo(t), t,
awful.util.getdir("cache") .. "/todos")
end),
awful.key({ modkey }, "F2",
function ()
awful.prompt.run({ fg_cursor = 'orange', bg_cursor = beautiful.bg_normal,
ul_cursor = "single", prompt = " Run: " },
mypromptbox[mouse.screen],
awful.util.spawn, awful.completion.shell,
awful.util.getdir("cache") .. "/history")
end),
awful.key({ modkey }, "F4",
function ()
awful.prompt.run({ prompt = " Run Lua code: " },
mypromptbox[mouse.screen],
awful.util.eval, nil,
awful.util.getdir("cache") .. "/history_eval")
end)
)
-- Client awful tagging: this is useful to tag some clients and then do stuff like move to tag on them
clientkeys = awful.util.table.join(
awful.key({ modkey, }, "f", function (c) c.fullscreen = not c.fullscreen end),
awful.key({ modkey, "Shift" }, "c", function (c) c:kill() end),
awful.key({ modkey, }, "semicolon", function (c) c:kill() end),
awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle ),
awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end),
awful.key({ modkey, }, "o", awful.client.movetoscreen ),
awful.key({ modkey, "Shift" }, "r", function (c) c:redraw() end),
awful.key({ modkey }, "t", awful.client.togglemarked),
awful.key({ modkey,}, "m",
function (c)
c.maximized_horizontal = not c.maximized_horizontal
c.maximized_vertical = not c.maximized_vertical
end)
)
for i=1,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))
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
end))
end
-- Set keys
root.keys(globalkeys)
shifty.config.globalkeys = globalkeys
shifty.config.clientkeys = clientkeys
--}}}
--}}}
-- {{{ Hooks
-- Hook function to execute when focusing a client.
awful.hooks.focus.register(function (c)
if not awful.client.ismarked(c) then
c.border_color = beautiful.border_focus
end
end)
-- Hook function to execute when unfocusing a client.
awful.hooks.unfocus.register(function (c)
if not awful.client.ismarked(c) then
c.border_color = beautiful.border_normal
end
end)
-- Hook function to execute when marking a client
awful.hooks.marked.register(function (c)
c.border_color = beautiful.border_marked
end)
-- Hook function to execute when unmarking a client.
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, but disabled for magnifier layout
if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
and awful.client.focus.filter(c) then
client.focus = c
end
end)
-- Hook function to execute when arranging the screen.
-- (tag switch, new client, etc)
awful.hooks.arrange.register(function (screen)
local layout = awful.layout.getname(awful.layout.get(screen))
if layout and beautiful["layout_" ..layout] then
mylayoutbox[screen].image = image(beautiful["layout_" .. layout])
else
mylayoutbox[screen].image = nil
end
-- Give focus to the latest client in history if no window has focus
-- or if the current window is a desktop or a dock one.
if not client.focus then
local c = awful.client.focus.history.get(screen, 0)
if c then client.focus = c end
end
end)
-- Hook called every 15 seconds, displays info
function hook_date ()
-- writes status to .status
os.execute("echo $(mpc | grep -) $(gmail.py) $(acpi -b | sed -e 's/%.*/%/;s/.*, //') $(date +'%a %d %b') $(date +'%I:%M') > ~/.status")
-- read .status
io.input("/home/jack/.status")
datebox.text = io.read("*line")
end
-- Set timers for the hooks
awful.hooks.timer.register(15, hook_date)
-- run the hook so we don't have to wait
hook_date()
--}}}
-- startup commands
os.execute("xmodmap ~/.xmodmap &")
os.execute("xbindkeys &")
os.execute("nitrogen --restore &")
os.execute("xsetroot -cursor_name left_ptr &")
-- vim: foldmethod=marker:filetype=lua:expandtab:shiftwidth=2:tabstop=2:softtabstop=2:encoding=utf-8:textwidth=80

12
icons/LICENSE Normal file
View file

@ -0,0 +1,12 @@
All 'awesome' icons in this package were created by Adrian C. (anrxc).
They are licensed under the same terms as the awesome distribution itself
- GNU General Public License version 2. To view a human-readable summary
of this license, visit: http://creativecommons.org/licenses/GPL/2.0/
The widget icons with the exception of: 'chat', 'crypt', 'power' and
'rss' icons (which were made by me) were originally made by 'sm4tik'
for purposes of 'dzen', I could not find any licensing information
attached to those original bitmaps. Assuming they are in the public
domain I am licensing the widget icons under the terms of the
Creative Commons Attribution-Share Alike license. To view a copy of
this license, visit: http://creativecommons.org/licenses/by-sa/3.0/

BIN
icons/awesome.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

BIN
icons/background.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
icons/bat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 B

BIN
icons/cal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 B

BIN
icons/chat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 B

BIN
icons/cpu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

BIN
icons/crypto.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

BIN
icons/disk.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

BIN
icons/down.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

BIN
icons/info.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

BIN
icons/layouts/dwindle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 B

BIN
icons/layouts/fairh.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 B

BIN
icons/layouts/fairhw.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

BIN
icons/layouts/fairv.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

BIN
icons/layouts/fairvw.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

BIN
icons/layouts/floating.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 B

BIN
icons/layouts/floatingw.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

BIN
icons/layouts/magnifier.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 B

BIN
icons/layouts/max.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

BIN
icons/layouts/maxw.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

BIN
icons/layouts/spiral.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

BIN
icons/layouts/tile.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

BIN
icons/layouts/tileleft.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 B

BIN
icons/layouts/tileleftw.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

BIN
icons/layouts/tiletop.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

BIN
icons/layouts/tiletopw.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

BIN
icons/layouts/tilew.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

BIN
icons/mail.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 B

BIN
icons/mem.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

BIN
icons/music.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

BIN
icons/pacman.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 B

BIN
icons/phones.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

BIN
icons/power.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

BIN
icons/rss.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

BIN
icons/sat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 B

BIN
icons/submenu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

BIN
icons/sun.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

BIN
icons/taglist/squarefw.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 B

BIN
icons/taglist/squarefz.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 B

BIN
icons/taglist/squarefza.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

BIN
icons/taglist/squarew.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

BIN
icons/taglist/squarez.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 B

BIN
icons/taglist/squareza.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 B

BIN
icons/tasklist/floating.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 B

BIN
icons/temp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 B

92
icons/theme.lua Normal file
View file

@ -0,0 +1,92 @@
---------------------------
-- Default awesome theme --
---------------------------
theme = {}
theme.font = "fixed 6"
theme.bg_normal = "#222222"
theme.bg_focus = "#535d6c"
theme.bg_urgent = "#ff0000"
theme.bg_minimize = "#444444"
theme.fg_normal = "#aaaaaa"
theme.fg_focus = "#ffffff"
theme.fg_urgent = "#ffffff"
theme.fg_minimize = "#ffffff"
theme.border_width = "0"
theme.border_normal = "#00000000"
theme.border_focus = "#535d6c55"
theme.border_marked = "#91231c55"
-- 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/squarefw.png"
theme.tasklist_floating_icon = "/usr/share/awesome/themes/default/tasklist/floatingw.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 = "12"
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/fairhw.png"
theme.layout_fairv = "/usr/share/awesome/themes/default/layouts/fairvw.png"
theme.layout_floating = "/usr/share/awesome/themes/default/layouts/floatingw.png"
theme.layout_magnifier = "/usr/share/awesome/themes/default/layouts/magnifierw.png"
theme.layout_max = "/usr/share/awesome/themes/default/layouts/maxw.png"
theme.layout_fullscreen = "/usr/share/awesome/themes/default/layouts/fullscreenw.png"
theme.layout_tilebottom = "/usr/share/awesome/themes/default/layouts/tilebottomw.png"
theme.layout_tileleft = "/usr/share/awesome/themes/default/layouts/tileleftw.png"
theme.layout_tile = "/usr/share/awesome/themes/default/layouts/tilew.png"
theme.layout_tiletop = "/usr/share/awesome/themes/default/layouts/tiletopw.png"
theme.awesome_icon = "/usr/share/awesome/themes/default/layouts/taglist/squarew.png"
return theme
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80

BIN
icons/time.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 893 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 818 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 799 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 814 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,013 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 774 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 965 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 833 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 836 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 872 B

BIN
icons/up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

BIN
icons/vol.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

BIN
icons/wifi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 B

515
json.lua Normal file
View file

@ -0,0 +1,515 @@
--[[
JSON Encoder and Parser for Lua 5.1
Copyright © 2007 Shaun Brown (http://www.chipmunkav.com).
All Rights Reserved.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
If you find this software useful please give www.chipmunkav.com a mention.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Usage:
-- Lua script:
local t = {
["name1"] = "value1",
["name2"] = {1, false, true, 23.54, "a \021 string"},
name3 = Json.Null()
}
local json = Json.Encode (t)
print (json)
--> {"name1":"value1","name3":null,"name2":[1,false,true,23.54,"a \u0015 string"]}
local t = Json.Decode(json)
print(t.name2[4])
--> 23.54
Notes:
1) Encodable Lua types: string, number, boolean, table, nil
2) Use Json.Null() to insert a null value into a Json object
3) All control chars are encoded to \uXXXX format eg "\021" encodes to "\u0015"
4) All Json \uXXXX chars are decoded to chars (0-255 byte range only)
5) Json single line // and /* */ block comments are discarded during decoding
6) Numerically indexed Lua arrays are encoded to Json Lists eg [1,2,3]
7) Lua dictionary tables are converted to Json objects eg {"one":1,"two":2}
8) Json nulls are decoded to Lua nil and treated by Lua in the normal way
--]]
local string = string
local math = math
local table = table
local error = error
local tonumber = tonumber
local tostring = tostring
local type = type
local setmetatable = setmetatable
local pairs = pairs
local ipairs = ipairs
local assert = assert
local Chipmunk = Chipmunk
module("Json")
local StringBuilder = {
buffer = {}
}
function StringBuilder:New()
local o = {}
setmetatable(o, self)
self.__index = self
o.buffer = {}
return o
end
function StringBuilder:Append(s)
self.buffer[#self.buffer+1] = s
end
function StringBuilder:ToString()
return table.concat(self.buffer)
end
local JsonWriter = {
backslashes = {
['\b'] = "\\b",
['\t'] = "\\t",
['\n'] = "\\n",
['\f'] = "\\f",
['\r'] = "\\r",
['"'] = "\\\"",
['\\'] = "\\\\",
['/'] = "\\/"
}
}
function JsonWriter:New()
local o = {}
o.writer = StringBuilder:New()
setmetatable(o, self)
self.__index = self
return o
end
function JsonWriter:Append(s)
self.writer:Append(s)
end
function JsonWriter:ToString()
return self.writer:ToString()
end
function JsonWriter:Write(o)
local t = type(o)
if t == "nil" then
self:WriteNil()
elseif t == "boolean" then
self:WriteString(o)
elseif t == "number" then
self:WriteString(o)
elseif t == "string" then
self:ParseString(o)
elseif t == "table" then
self:WriteTable(o)
elseif t == "function" then
self:WriteFunction(o)
elseif t == "thread" then
self:WriteError(o)
elseif t == "userdata" then
self:WriteError(o)
end
end
function JsonWriter:WriteNil()
self:Append("null")
end
function JsonWriter:WriteString(o)
self:Append(tostring(o))
end
function JsonWriter:ParseString(s)
self:Append('"')
self:Append(string.gsub(s, "[%z%c\\\"/]", function(n)
local c = self.backslashes[n]
if c then return c end
return string.format("\\u%.4X", string.byte(n))
end))
self:Append('"')
end
function JsonWriter:IsArray(t)
local count = 0
local isindex = function(k)
if type(k) == "number" and k > 0 then
if math.floor(k) == k then
return true
end
end
return false
end
for k,v in pairs(t) do
if not isindex(k) then
return false, '{', '}'
else
count = math.max(count, k)
end
end
return true, '[', ']', count
end
function JsonWriter:WriteTable(t)
local ba, st, et, n = self:IsArray(t)
self:Append(st)
if ba then
for i = 1, n do
self:Write(t[i])
if i < n then
self:Append(',')
end
end
else
local first = true;
for k, v in pairs(t) do
if not first then
self:Append(',')
end
first = false;
self:ParseString(k)
self:Append(':')
self:Write(v)
end
end
self:Append(et)
end
function JsonWriter:WriteError(o)
error(string.format(
"Encoding of %s unsupported",
tostring(o)))
end
function JsonWriter:WriteFunction(o)
if o == Null then
self:WriteNil()
else
self:WriteError(o)
end
end
local StringReader = {
s = "",
i = 0
}
function StringReader:New(s)
local o = {}
setmetatable(o, self)
self.__index = self
o.s = s or o.s
return o
end
function StringReader:Peek()
local i = self.i + 1
if i <= #self.s then
return string.sub(self.s, i, i)
end
return nil
end
function StringReader:Next()
self.i = self.i+1
if self.i <= #self.s then
return string.sub(self.s, self.i, self.i)
end
return nil
end
function StringReader:All()
return self.s
end
local JsonReader = {
escapes = {
['t'] = '\t',
['n'] = '\n',
['f'] = '\f',
['r'] = '\r',
['b'] = '\b',
}
}
function JsonReader:New(s)
local o = {}
o.reader = StringReader:New(s)
setmetatable(o, self)
self.__index = self
return o;
end
function JsonReader:Read()
self:SkipWhiteSpace()
local peek = self:Peek()
if peek == nil then
error(string.format(
"Nil string: '%s'",
self:All()))
elseif peek == '{' then
return self:ReadObject()
elseif peek == '[' then
return self:ReadArray()
elseif peek == '"' then
return self:ReadString()
elseif string.find(peek, "[%+%-%d]") then
return self:ReadNumber()
elseif peek == 't' then
return self:ReadTrue()
elseif peek == 'f' then
return self:ReadFalse()
elseif peek == 'n' then
return self:ReadNull()
elseif peek == '/' then
self:ReadComment()
return self:Read()
else
error(string.format(
"Invalid input: '%s'",
self:All()))
end
end
function JsonReader:ReadTrue()
self:TestReservedWord{'t','r','u','e'}
return true
end
function JsonReader:ReadFalse()
self:TestReservedWord{'f','a','l','s','e'}
return false
end
function JsonReader:ReadNull()
self:TestReservedWord{'n','u','l','l'}
return nil
end
function JsonReader:TestReservedWord(t)
for i, v in ipairs(t) do
if self:Next() ~= v then
error(string.format(
"Error reading '%s': %s",
table.concat(t),
self:All()))
end
end
end
function JsonReader:ReadNumber()
local result = self:Next()
local peek = self:Peek()
while peek ~= nil and string.find(
peek,
"[%+%-%d%.eE]") do
result = result .. self:Next()
peek = self:Peek()
end
result = tonumber(result)
if result == nil then
error(string.format(
"Invalid number: '%s'",
result))
else
return result
end
end
function JsonReader:ReadString()
local result = ""
assert(self:Next() == '"')
while self:Peek() ~= '"' do
local ch = self:Next()
if ch == '\\' then
ch = self:Next()
if self.escapes[ch] then
ch = self.escapes[ch]
end
end
result = result .. ch
end
assert(self:Next() == '"')
local fromunicode = function(m)
return string.char(tonumber(m, 16))
end
return string.gsub(
result,
"u%x%x(%x%x)",
fromunicode)
end
function JsonReader:ReadComment()
assert(self:Next() == '/')
local second = self:Next()
if second == '/' then
self:ReadSingleLineComment()
elseif second == '*' then
self:ReadBlockComment()
else
error(string.format(
"Invalid comment: %s",
self:All()))
end
end
function JsonReader:ReadBlockComment()
local done = false
while not done do
local ch = self:Next()
if ch == '*' and self:Peek() == '/' then
done = true
end
if not done and
ch == '/' and
self:Peek() == "*" then
error(string.format(
"Invalid comment: %s, '/*' illegal.",
self:All()))
end
end
self:Next()
end
function JsonReader:ReadSingleLineComment()
local ch = self:Next()
while ch ~= '\r' and ch ~= '\n' do
ch = self:Next()
end
end
function JsonReader:ReadArray()
local result = {}
assert(self:Next() == '[')
local done = false
if self:Peek() == ']' then
done = true;
end
while not done do
local item = self:Read()
result[#result+1] = item
self:SkipWhiteSpace()
if self:Peek() == ']' then
done = true
end
if not done then
local ch = self:Next()
if ch ~= ',' then
error(string.format(
"Invalid array: '%s' due to: '%s'",
self:All(), ch))
end
end
end
assert(']' == self:Next())
return result
end
function JsonReader:ReadObject()
local result = {}
assert(self:Next() == '{')
local done = false
if self:Peek() == '}' then
done = true
end
while not done do
local key = self:Read()
if type(key) ~= "string" then
error(string.format(
"Invalid non-string object key: %s",
key))
end
self:SkipWhiteSpace()
local ch = self:Next()
if ch ~= ':' then
error(string.format(
"Invalid object: '%s' due to: '%s'",
self:All(),
ch))
end
self:SkipWhiteSpace()
local val = self:Read()
result[key] = val
self:SkipWhiteSpace()
if self:Peek() == '}' then
done = true
end
if not done then
ch = self:Next()
if ch ~= ',' then
error(string.format(
"Invalid array: '%s' near: '%s'",
self:All(),
ch))
end
end
end
assert(self:Next() == "}")
return result
end
function JsonReader:SkipWhiteSpace()
local p = self:Peek()
while p ~= nil and string.find(p, "[%s/]") do
if p == '/' then
self:ReadComment()
else
self:Next()
end
p = self:Peek()
end
end
function JsonReader:Peek()
return self.reader:Peek()
end
function JsonReader:Next()
return self.reader:Next()
end
function JsonReader:All()
return self.reader:All()
end
function Encode(o)
local writer = JsonWriter:New()
writer:Write(o)
return writer:ToString()
end
function Decode(s)
local reader = JsonReader:New(s)
return reader:Read()
end
function Null()
return Null
end

150
lib/mpd.lua Normal file
View file

@ -0,0 +1,150 @@
-- Small interface to MusicPD
-- use luasocket, with a persistant connection to the MPD server.
--
-- Author: Alexandre "kAworu" Perrin <kaworu at kaworu dot ch>
--
-- based on a netcat version from Steve Jothen <sjothen at gmail dot com>
-- (see http://github.com/otkrove/ion3-config/tree/master/mpd.lua)
require("socket")
-- Grab env
local socket = socket
local string = string
local tonumber = tonumber
local setmetatable = setmetatable
local os = os
-- Music Player Daemon Lua library.
module("mpd")
MPD = {
} MPD_mt = { __index = MPD }
-- create and return a new mpd client.
-- the settings argument is a table with theses keys:
-- hostname: the MPD's host (default localhost)
-- port: MPD's port to connect to (default 6600)
-- desc: server's description (default hostname)
-- password: the server's password (default nil, no password)
-- timeout: time in sec to wait for connect() and receive() (default 1)
-- retry: time in sec to wait before reconnect if error (default 60)
function new(settings)
local client = {}
if settings == nil then settings = {} end
client.hostname = settings.hostname or "localhost"
client.port = settings.port or 6600
client.desc = settings.desc or client.hostname
client.password = settings.password
client.timeout = settings.timeout or 1
client.retry = settings.retry or 60
setmetatable(client, MPD_mt)
return client
end
-- calls the action and returns the server's response.
-- Example: if the server's response to "status" action is:
-- volume: 20
-- repeat: 0
-- random: 0
-- playlist: 599
-- ...
-- then the returned table is:
-- { volume = 20, repeat = 0, random = 0, playlist = 599, ... }
function MPD:send(action)
local command = string.format("%s\n", action)
local values = {}
-- connect to MPD server if not already done.
if not self.connected then
if not self.last_try or (os.time() - self.last_try) > self.retry then
self.socket = socket.tcp()
self.socket:settimeout(self.timeout, 't')
self.last_try = os.time()
self.connected = self.socket:connect(self.hostname, self.port)
if self.connected and self.password then
self:send(string.format("password %s", self.password))
end
end
end
if not self.connected then
return {}
end
self.socket:send(command)
local line = ""
while not line:match("^OK$") do
line = self.socket:receive("*l")
if not line then -- closed,timeout (mpd killed?)
self.connected = false
return self:send(action)
end
if line:match(string.format("^ACK", action)) then
return { errormsg = line }
end
local _, _, key, value = string.find(line, "([^:]+):%s(.+)")
if key then
values[string.lower(key)] = value
end
end
return values
end
function MPD:next()
self:send("next")
end
function MPD:previous()
self:send("previous")
end
function MPD:stop()
self:send("stop")
end
-- no need to check the new value, mpd will set the volume in [0,100]
function MPD:volume_up(delta)
local stats = self:send("status")
local new_volume = tonumber(stats.volume) + delta
self:send(string.format("setvol %d", new_volume))
end
function MPD:volume_down(delta)
self:volume_up(-delta)
end
function MPD:toggle_random()
local stats = self:send("status")
if tonumber(stats.random) == 0 then
self:send("random 1")
else
self:send("random 0")
end
end
function MPD:toggle_repeat()
local stats = self:send("status")
if tonumber(stats["repeat"]) == 0 then
self:send("repeat 1")
else
self:send("repeat 0")
end
end
function MPD:toggle_play()
if self:send("status").state == "stop" then
self:send("play")
else
self:send("pause")
end
end
-- vim:filetype=lua:tabstop=8:shiftwidth=2:fdm=marker:

779
lib/shifty.lua Normal file
View file

@ -0,0 +1,779 @@
--- Shifty: Dynamic tagging library for awesome3-git
-- @author koniu &lt;gkusnierz@gmail.com&gt;
-- @author bioe007 &lt;perry.hargrave@gmail.com&gt;
--
-- http://awesome.naquadah.org/wiki/index.php?title=Shifty
-- package env
local type = type
local tag = tag
local ipairs = ipairs
local table = table
local client = client
local image = image
local string = string
local screen = screen
local button = button
local mouse = mouse
local beautiful = require("beautiful")
local awful = require("awful")
local pairs = pairs
local io = io
local tonumber = tonumber
local wibox = wibox
local root = root
local dbg= dbg
module("shifty")
config = {}
config.tags = {}
config.apps = {}
config.defaults = {}
config.guess_name = true
config.guess_position = true
config.remember_index = true
config.default_name = "new"
config.clientkeys = {}
config.globalkeys = nil
config.layouts = {}
config.prompt_sources = { "config_tags", "config_apps", "existing", "history" }
config.prompt_matchers = { "^", ":", "" }
local matchp = ""
local index_cache = {}
for i = 1, screen.count() do index_cache[i] = {} end
--{{{ name2tags: matches string 'name' to tag objects
-- @param name : tag name to find
-- @param scr : screen to look for tags on
-- @return table of tag objects or nil
function name2tags(name, scr)
local ret = {}
local a, b = scr or 1, scr or screen.count()
for s = a, b do
for i, t in ipairs(screen[s]:tags()) do
if name == t.name then
table.insert(ret, t)
end
end
end
if #ret > 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 = " " },
taglist[scr][tag2index(scr,t)*2],
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
awful.hooks.user.call("tags", scr)
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 target = awful.util.cycle(#screen[scr]:tags(), sel_idx + idx)
awful.tag.viewonly(screen[scr]:tags()[target])
awful.client.movetotag(screen[scr]:tags()[target], client.focus)
end
function send_next() send(1) end
function send_prev() send(-1) end
--}}}
function shift_next() set(awful.tag.selected(), { rel_index = 1 }) end
function shift_prev() set(awful.tag.selected(), { rel_index = -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
for prop, val in pairs(props) do awful.tag.setproperty(t, prop, val) end
screen[scr]:tags(tags)
-- 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
--}}}
--{{{ 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 )
-- 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)
if args.position then
f = function() rename(t, args.rename, true); awful.hooks.timer.unregister(f) end
else
f = function() rename(t); awful.hooks.timer.unregister(f) end
end
awful.hooks.timer.register(0.01, f)
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)
-- 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
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.float ~= nil then awful.client.floating.set(c, a.float) 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.slave ~=nil then slave = a.slave 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.hide ~= nil then c.hide = a.hide 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.titlebar ~= nil then awful.titlebar.add(c, { modkey = modkey }) 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
end
end
end
end
-- set key bindings
c:keys(keys)
-- set properties of floating clients
if awful.client.floating.get(c) then
if config.defaults.floatBars then -- add a titlebar if requested in config.defaults
awful.titlebar.add( c, { modkey = modkey } )
end
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
c:tags( target_tags )
if slave then awful.client.setslave(c) end
if wfact then awful.client.setwfact(wfact, c) 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 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
awful.tag.viewmore(showtags, c.screen)
end
end
-- focus and raise accordingly or lower if supressed
if not (nofocus or c.hide 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
--FIXME: global f, what if more than one at a time is being swept
f = function() del(t); awful.hooks.timer.unregister(f) end
awful.hooks.timer.register(delay, f)
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)
local keys = awful.tag.getproperty(sel, "keys") or config.globalkeys
if keys 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.keysym] = 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
-- }}}
awful.hooks.manage.unregister(awful.tag.withcurrent)
awful.hooks.tags.register(sweep)
awful.hooks.arrange.register(sweep)
awful.hooks.arrange.register(tagkeys)
awful.hooks.clients.register(sweep)
awful.hooks.manage.register(match)
-- vim: foldmethod=marker:filetype=lua:expandtab:shiftwidth=2:tabstop=2:softtabstop=2:encoding=utf-8:textwidth=80

335
rc.lua Normal file
View file

@ -0,0 +1,335 @@
-- Standard awesome library
require("awful")
require("awful.autofocus")
require("awful.rules")
-- Theme handling library
require("beautiful")
-- Notification library
require("naughty")
require("teardrop")
-- {{{ Variable definitions
-- Themes define colours, icons, and wallpapers
beautiful.init("/usr/share/awesome/themes/default/theme.lua")
-- This is used later as the default terminal and editor to run.
terminal = "terminal"
editor = os.getenv("EDITOR") or "vim"
editor_cmd = terminal .. " -e " .. editor
-- Default modkey.
-- Usually, Mod4 is the key with a logo between Control and Alt.
-- If you do not like this or do not have such a key,
-- I suggest you to remap Mod4 to another key using xmodmap or other tools.
-- However, you can use another modifier like Mod1, but it may interact with others.
modkey = "Mod4"
-- Table of layouts to cover with awful.layout.inc, order matters.
layouts =
{
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,
awful.layout.suit.floating
}
-- }}}
-- {{{ Tags
-- Define a tag table which hold all screen tags.
tags = {}
for s = 1, screen.count() do
-- Each screen has its own tag table.
tags[s] = awful.tag({ 1, 2, 3, 4, 5, 6, 7, 8, 9 }, s)
end
-- }}}
-- {{{ Menu
-- Create a laucher widget and a main menu
myawesomemenu = {
{ "manual", terminal .. " -e man awesome" },
{ "edit config", editor_cmd .. " " .. awful.util.getdir("config") .. "/rc.lua" },
{ "restart", awesome.restart },
{ "quit", awesome.quit }
}
mymainmenu = awful.menu({ items = { { "awesome", myawesomemenu, beautiful.awesome_icon },
{ "open terminal", terminal }
}
})
mylauncher = awful.widget.launcher({ image = image(beautiful.awesome_icon),
menu = mymainmenu })
-- }}}
-- {{{ Wibox
-- Create a textclock widget
mytextclock = awful.widget.textclock({ align = "right" })
-- Create a systray
mysystray = widget({ type = "systray" })
-- Create a wibox for each screen and add it
mywibox = {}
mypromptbox = {}
mylayoutbox = {}
mytaglist = {}
mytaglist.buttons = awful.util.table.join(
awful.button({ }, 1, awful.tag.viewonly),
awful.button({ modkey }, 1, awful.client.movetotag),
awful.button({ }, 3, awful.tag.viewtoggle),
awful.button({ modkey }, 3, awful.client.toggletag),
awful.button({ }, 4, awful.tag.viewnext),
awful.button({ }, 5, awful.tag.viewprev)
)
mytasklist = {}
mytasklist.buttons = awful.util.table.join(
awful.button({ }, 1, function (c)
if not c:isvisible() then
awful.tag.viewonly(c:tags()[1])
end
client.focus = c
c:raise()
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 })
-- 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)))
-- Create a taglist widget
mytaglist[s] = awful.widget.taglist(s, awful.widget.taglist.label.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)
-- Create the wibox
mywibox[s] = awful.wibox({ position = "top", screen = s })
-- Add widgets to the wibox - order matters
mywibox[s].widgets = {
{
mylauncher,
mytaglist[s],
mypromptbox[s],
layout = awful.widget.layout.horizontal.leftright
},
mylayoutbox[s],
mytextclock,
s == 1 and mysystray or nil,
mytasklist[s],
layout = awful.widget.layout.horizontal.rightleft
}
end
-- }}}
-- {{{ Mouse bindings
root.buttons(awful.util.table.join(
awful.button({ }, 3, function () mymainmenu:toggle() end),
awful.button({ }, 4, awful.tag.viewnext),
awful.button({ }, 5, awful.tag.viewprev)
))
-- }}}
-- {{{ Key bindings
globalkeys = awful.util.table.join(
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, }, "j",
function ()
awful.client.focus.byidx( 1)
if client.focus then client.focus:raise() end
end),
awful.key({ modkey, }, "k",
function ()
awful.client.focus.byidx(-1)
if client.focus then client.focus:raise() end
end),
awful.key({ modkey, }, "w", function () mymainmenu:show(true) end),
-- Layout manipulation
awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end),
awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( -1) end),
awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative( 1) end),
awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end),
awful.key({ modkey, }, "u", awful.client.urgent.jumpto),
awful.key({ modkey, }, "Tab",
function ()
awful.client.focus.history.previous()
if client.focus then
client.focus:raise()
end
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),
awful.key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end),
awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end),
awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1) end),
awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1) end),
awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1) end),
awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1) end),
awful.key({ modkey, }, "space", function () awful.layout.inc(layouts, 1) end),
awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(layouts, -1) end),
-- Prompt
awful.key({ modkey }, "r", function () mypromptbox[mouse.screen]:run() end),
awful.key({ modkey }, "x",
function ()
awful.prompt.run({ prompt = "Run Lua code: " },
mypromptbox[mouse.screen].widget,
awful.util.eval, nil,
awful.util.getdir("cache") .. "/history_eval")
end)
)
clientkeys = awful.util.table.join(
awful.key({ modkey, }, "f", function (c) c.fullscreen = not c.fullscreen end),
awful.key({ modkey, "Shift" }, "c", function (c) c:kill() end),
awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle ),
awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end),
awful.key({ modkey, }, "o", awful.client.movetoscreen ),
awful.key({ modkey, "Shift" }, "r", function (c) c:redraw() end),
awful.key({ modkey, }, "n", function (c) c.minimized = not c.minimized end),
awful.key({ modkey, }, "m",
function (c)
c.maximized_horizontal = not c.maximized_horizontal
c.maximized_vertical = not c.maximized_vertical
end)
)
-- Compute the maximum number of digit we need, limited to 9
keynumber = 0
for s = 1, screen.count() do
keynumber = math.min(9, math.max(#tags[s], keynumber));
end
-- Bind all key numbers to tags.
-- Be careful: we use keycodes to make it works on any keyboard layout.
-- This should map on the top row of your keyboard, usually 1 to 9.
for i = 1, keynumber do
globalkeys = awful.util.table.join(globalkeys,
awful.key({ modkey }, "#" .. i + 9,
function ()
local screen = mouse.screen
if tags[screen][i] then
awful.tag.viewonly(tags[screen][i])
end
end),
awful.key({ modkey, "Control" }, "#" .. i + 9,
function ()
local screen = mouse.screen
if tags[screen][i] then
awful.tag.viewtoggle(tags[screen][i])
end
end),
awful.key({ modkey, "Shift" }, "#" .. i + 9,
function ()
if client.focus and tags[client.focus.screen][i] then
awful.client.movetotag(tags[client.focus.screen][i])
end
end),
awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
function ()
if client.focus and tags[client.focus.screen][i] then
awful.client.toggletag(tags[client.focus.screen][i])
end
end))
end
clientbuttons = awful.util.table.join(
awful.button({ }, 1, function (c) client.focus = c; c:raise() end),
awful.button({ modkey }, 1, awful.mouse.client.move),
awful.button({ modkey }, 3, awful.mouse.client.resize))
-- Set keys
root.keys(globalkeys)
-- }}}
-- {{{ Rules
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 } },
{ rule = { class = "MPlayer" },
properties = { floating = true } },
{ rule = { class = "pinentry" },
properties = { floating = true } },
{ rule = { class = "gimp" },
properties = { floating = true } },
-- Set Firefox to always map on tags number 2 of screen 1.
-- { rule = { class = "Firefox" },
-- properties = { tag = tags[1][2] } },
}
-- }}}
-- {{{ Signals
-- Signal function to execute when a new client appears.
client.add_signal("manage", function (c, startup)
-- Add a titlebar
-- awful.titlebar.add(c, { modkey = modkey })
-- 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)
if not startup then
-- Set the windows at the slave,
-- i.e. put it at the end of others instead of setting it master.
-- awful.client.setslave(c)
-- 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)
-- }}}

136
scratchpad.lua Normal file
View file

@ -0,0 +1,136 @@
---------------------------------------------------------------
-- Basic scratchpad manager for the awesome window manager
---------------------------------------------------------------
-- Adrian C. <anrxc.sysphere.org>
-- Licensed under the WTFPL version 2
-- * http://sam.zoy.org/wtfpl/COPYING
---------------------------------------------------------------
-- To use this module add:
-- require("scratchpad")
-- to the top of your rc.lua, and call:
-- scratchpad.set(c, width, height, sticky, screen)
-- from a clientkeys binding, and:
-- scratchpad.toggle(screen)
-- from a globalkeys binding.
--
-- Parameters:
-- c - Client to scratch or un-scratch
-- width - Width in absolute pixels, or width percentage
-- when < 1 (0.50 (50% of the screen) by default)
-- height - Height in absolute pixels, or height percentage
-- when < 1 (0.50 (50% of the screen) by default)
-- sticky - Visible on all tags, false by default
-- screen - Screen (optional), mouse.screen by default
---------------------------------------------------------------
-- Grab environment
local awful = require("awful")
local capi = {
mouse = mouse,
client = client,
screen = screen
}
-- Scratchpad: Basic scratchpad manager for the awesome window manager
module("scratchpad")
local scratch = {}
-- Scratch the focused client, or un-scratch and tile it. If another
-- client is already scratched, replace it with the focused client.
function set(c, width, height, sticky, screen)
local width = width or 0.50
local height = height or 0.50
local sticky = sticky or false
local screen = screen or capi.mouse.screen
local function setscratch(c)
-- Scratchpad is floating
awful.client.floating.set(c, true)
-- Scratchpad geometry and placement
local screengeom = capi.screen[screen].workarea
if width < 1 then width = screengeom.width * width end
if height < 1 then height = screengeom.height * height end
c:geometry({ -- Client is always centered on screen
x = screengeom.x + (screengeom.width - width) / 2,
y = screengeom.y + (screengeom.height - height) / 2,
width = width, height = height
})
-- Scratchpad properties
c.ontop = true
c.above = true
c.skip_taskbar = true
if sticky then c.sticky = true end
if c.titlebar then awful.titlebar.remove(c) end
-- Scratchpad should not loose focus
c:raise()
capi.client.focus = c
end
-- Prepare a table for storing clients,
if not scratch["pad"] then scratch["pad"] = {}
-- add unmanage signal for scratchpad clients
capi.client.add_signal("unmanage", function (c)
local oc = scratch["pad"][screen]
if oc == c then
scratch["pad"][screen] = nil
end
end)
end
-- If the scratcphad is emtpy, store the client,
if not scratch["pad"][screen] then
scratch["pad"][screen] = c
-- then apply geometry and properties
setscratch(c)
else -- If a client is already scratched,
local oc = scratch["pad"][screen]
-- compare it with the focused client
if oc == c then
-- If it matches then unscratch and clear the table
awful.client.floating.toggle(oc); oc.sticky = false
oc.ontop = false; oc.above = false
scratch["pad"][screen] = nil
else -- If they don't match, unscratch and replace it
oc.hidden = false; oc.sticky = false
oc.ontop = false; oc.above = false
awful.client.floating.toggle(oc)
scratch["pad"][screen] = c
setscratch(c)
end
end
end
-- Move the scratchpad to the current workspace, focus and raise it
-- when it's hidden, or hide it when it's visible.
function toggle(screen)
local screen = screen or capi.mouse.screen
-- Check if we have a client on storage,
if scratch["pad"] and
scratch["pad"][screen] ~= nil
then -- and get it out, to play
local c = scratch["pad"][screen]
-- If it's visible on another tag hide it,
if c:isvisible() == false then c.hidden = true;
-- and move it to the current worskpace
awful.client.movetotag(awful.tag.selected(screen), c)
end
-- Focus and raise if it's hidden,
if c.hidden then
awful.placement.centered(c)
c.hidden = false
c:raise()
capi.client.focus = c
else -- hide it if it's not
c.hidden = true
end
end
end

128
teardrop.lua Normal file
View file

@ -0,0 +1,128 @@
----------------------------------------------------------------
-- Drop-down applications manager for the awesome window manager
----------------------------------------------------------------
-- Adrian C. <anrxc.sysphere.org>
-- Licensed under the WTFPL version 2
-- * http://sam.zoy.org/wtfpl/COPYING
----------------------------------------------------------------
-- To use this module add:
-- require("teardrop")
-- to the top of your rc.lua, and call it from a keybinding:
-- teardrop(prog, vert, horiz, width, height, sticky, screen)
--
-- Parameters:
-- prog - Program to run; "urxvt", "gmrun", "thunderbird"
-- vert - Vertical; "bottom", "center" or "top" (default)
-- horiz - Horizontal; "left", "right" or "center" (default)
-- width - Width in absolute pixels, or width percentage
-- when < 1 (0.9999 (99.9% of the screen) by default)
-- height - Height in absolute pixels, or height percentage
-- when < 1 (0.25 (25% of the screen) by default)
-- sticky - Visible on all tags, false by default
-- screen - Screen (optional), mouse.screen by default
----------------------------------------------------------------
-- Grab environment
local pairs = pairs
local awful = require("awful")
local setmetatable = setmetatable
local capi = {
mouse = mouse,
client = client,
screen = screen
}
-- Teardrop: Drop-down applications manager for the awesome window manager
module("teardrop")
local dropdown = {}
-- Create a new window for the drop-down application when it doesn't
-- exist, or toggle between hidden and visible states when it does
function toggle(prog, vert, horiz, width, height, sticky, screen)
local vert = vert or "top"
local horiz = horiz or "center"
local width = width or 0.9999
local height = height or 0.25
local sticky = sticky or false
local screen = screen or capi.mouse.screen
if not dropdown[prog] then
dropdown[prog] = {}
-- Add unmanage signal for teardrop programs
capi.client.add_signal("unmanage", function (c)
for scr, cl in pairs(dropdown[prog]) do
if cl == c then
dropdown[prog][scr] = nil
end
end
end)
end
if not dropdown[prog][screen] then
spawnw = function (c)
dropdown[prog][screen] = c
-- Teardrop clients are floaters
awful.client.floating.set(c, true)
-- Client geometry and placement
local screengeom = capi.screen[screen].workarea
if width < 1 then width = screengeom.width * width end
if height < 1 then height = screengeom.height * height end
if horiz == "left" then x = screengeom.x
elseif horiz == "right" then x = screengeom.width - width
else x = screengeom.x+(screengeom.width-width)/2 end
if vert == "bottom" then y = screengeom.height + screengeom.y - height
elseif vert == "center" then y = screengeom.y+(screengeom.height-height)/2
else y = screengeom.y - screengeom.y end
-- Client properties
c:geometry({ x = x, y = y, width = width, height = height })
c.ontop = true
c.above = true
c.skip_taskbar = true
if sticky then c.sticky = true end
if c.titlebar then awful.titlebar.remove(c) end
c:raise()
capi.client.focus = c
capi.client.remove_signal("manage", spawnw)
end
-- Add manage signal and spawn the program
capi.client.add_signal("manage", spawnw)
awful.util.spawn(prog, false)
else
-- Get a running client
c = dropdown[prog][screen]
-- Switch the client to the current workspace
if c:isvisible() == false then c.hidden = true;
awful.client.movetotag(awful.tag.selected(screen), c)
end
-- Focus and raise if hidden
if c.hidden then
-- Make sure it is centered
if vert == "center" then awful.placement.center_vertical(c) end
if horiz == "center" then awful.placement.center_horizontal(c) end
c.hidden = false
c:raise()
capi.client.focus = c
else -- Hide and detach tags if not
c.hidden = true
local ctags = c:tags()
for i, v in pairs(ctags) do
ctags[i] = nil
end
c:tags(ctags)
end
end
end
setmetatable(_M, { __call = function(_, ...) return toggle(...) end })

142
theme.lua Normal file
View file

@ -0,0 +1,142 @@
-------------------------------
-- "Zenburn" awesome theme --
-- By Adrian C. (anrxc) --
-------------------------------
-- {{{ Main
theme = {}
confdir = awful.util.getdir("config")
theme.wallpaper_cmd = { "/usr/bin/nitrogen --restore" }
--theme.wallpaper_cmd = { "awsetbg /usr/share/awesome/themes/zenburn/zenburn-background.png" }
-- }}}
-- {{{ Styles
theme.font = "fixed 6"
-- {{{ Colors
theme.fg_normal = "#DCDCCC"
theme.fg_focus = "#F0DFAF"
theme.fg_urgent = "#CC9393"
theme.bg_normal = "#3F3F3F"
theme.bg_focus = "#1E2320"
theme.bg_urgent = "#3F3F3F"
-- }}}
-- {{{ Borders
theme.border_width = "1"
theme.border_normal = "#3F3F3F"
theme.border_focus = "#6F6F6F"
theme.border_marked = "#CC9393"
-- }}}
-- {{{ Titlebars
theme.titlebar_bg_focus = "#5F5F5F"
theme.titlebar_bg_normal = "#3F3F3F"
-- theme.titlebar_[normal|focus]
-- }}}
-- {{{ Widgets
theme.fg_widget = "#AECF96"
theme.fg_center_widget = "#88A175"
theme.fg_end_widget = "#FF5656"
theme.fg_off_widget = "#494B4F"
theme.fg_netup_widget = "#7F9F7F"
theme.fg_netdn_widget = "#CC9393"
theme.bg_widget = "#3F3F3F"
theme.border_widget = "#3F3F3F"
-- }}}
-- {{{ Mouse finder
theme.mouse_finder_color = "#CC9393"
-- theme.mouse_finder_[timeout|animate_timeout|radius|factor]
-- }}}
-- {{{ Tooltips
-- theme.tooltip_[font|opacity|fg_color|bg_color|border_width|border_color]
-- }}}
-- {{{ Taglist and Tasklist
-- theme.[taglist|tasklist]_[bg|fg]_[focus|urgent]
-- }}}
-- {{{ Menu
-- theme.menu_[height|width]
-- theme.menu_[bg|fg]_[normal|focus]
-- theme.menu_[border_color|border_width]
-- }}}
-- }}}
-- {{{ Icons
--
-- {{{ Taglist icons
theme.taglist_squares_sel = confdir .. "/icons/taglist/squarefw.png"
theme.taglist_squares_unsel = confdir .. "/icons/taglist/squarew.png"
--theme.taglist_squares_resize = "false"
-- }}}
-- {{{ Misc icons
--theme.awesome_icon = confdir .. "/icons/awesome.png"
--theme.menu_submenu_icon = "/usr/share/awesome/themes/default/submenu.png"
--theme.tasklist_floating_icon = "/usr/share/awesome/themes/default/tasklist/floatingw.png"
-- }}}
-- {{{ Layout icons
theme.layout_tile = confdir .. "/icons/layouts/tilew.png"
theme.layout_tileleft = confdir .. "/icons/layouts/tileleftw.png"
theme.layout_tilebottom = confdir .. "/icons/layouts/tilebottomw.png"
theme.layout_tiletop = confdir .. "/icons/layouts/tiletopw.png"
theme.layout_fairv = confdir .. "/icons/layouts/fairvw.png"
theme.layout_fairh = confdir .. "/icons/layouts/fairhw.png"
theme.layout_spiral = confdir .. "/icons/layouts/spiralw.png"
theme.layout_dwindle = confdir .. "/icons/layouts/dwindlew.png"
theme.layout_max = confdir .. "/icons/layouts/maxw.png"
theme.layout_fullscreen = confdir .. "/icons/layouts/fullscreenw.png"
theme.layout_magnifier = confdir .. "/icons/layouts/magnifierw.png"
theme.layout_floating = confdir .. "/icons/layouts/floatingw.png"
-- }}}
-- {{{ Widget icons
theme.widget_cpu = confdir .. "/icons/cpu.png"
theme.widget_bat = confdir .. "/icons/bat.png"
theme.widget_mem = confdir .. "/icons/mem.png"
theme.widget_fs = confdir .. "/icons/disk.png"
theme.widget_net = confdir .. "/icons/down.png"
theme.widget_netup = confdir .. "/icons/up.png"
theme.widget_mail = confdir .. "/icons/mail.png"
theme.widget_vol = confdir .. "/icons/vol.png"
theme.widget_org = confdir .. "/icons/cal.png"
theme.widget_date = confdir .. "/icons/time.png"
theme.widget_crypto = confdir .. "/icons/crypto.png"
-- }}}
-- {{{ Titlebar icons
theme.titlebar_close_button_focus = confdir .. "/icons/titlebar/close_focus.png"
theme.titlebar_close_button_normal = confdir .. "/icons/titlebar/close_normal.png"
theme.titlebar_ontop_button_focus_active = confdir .. "/icons/titlebar/ontop_focus_active.png"
theme.titlebar_ontop_button_normal_active = confdir .. "/icons/titlebar/ontop_normal_active.png"
theme.titlebar_ontop_button_focus_inactive = confdir .. "/icons/titlebar/ontop_focus_inactive.png"
theme.titlebar_ontop_button_normal_inactive = confdir .. "/icons/titlebar/ontop_normal_inactive.png"
theme.titlebar_sticky_button_focus_active = confdir .. "/icons/titlebar/sticky_focus_active.png"
theme.titlebar_sticky_button_normal_active = confdir .. "/icons/titlebar/sticky_normal_active.png"
theme.titlebar_sticky_button_focus_inactive = confdir .. "/icons/titlebar/sticky_focus_inactive.png"
theme.titlebar_sticky_button_normal_inactive = confdir .. "/icons/titlebar/sticky_normal_inactive.png"
theme.titlebar_floating_button_focus_active = confdir .. "/icons/titlebar/floating_focus_active.png"
theme.titlebar_floating_button_normal_active = confdir .. "/icons/titlebar/floating_normal_active.png"
theme.titlebar_floating_button_focus_inactive = confdir .. "/icons/titlebar/floating_focus_inactive.png"
theme.titlebar_floating_button_normal_inactive = confdir .. "/icons/titlebar/floating_normal_inactive.png"
theme.titlebar_maximized_button_focus_active = confdir .. "/icons/titlebar/maximized_focus_active.png"
theme.titlebar_maximized_button_normal_active = confdir .. "/icons/titlebar/maximized_normal_active.png"
theme.titlebar_maximized_button_focus_inactive = confdir .. "/icons/titlebar/maximized_focus_inactive.png"
theme.titlebar_maximized_button_normal_inactive = confdir .. "/icons/titlebar/maximized_normal_inactive.png"
-- }}}
-- }}}
return theme

848
wicked.lua Normal file
View file

@ -0,0 +1,848 @@
---------------------------------------------------------------------------
-- Wicked widgets for the awesome window manager
---------------------------------------------------------------------------
-- Lucas de Vries <lucas@glacicle.com>
-- Licensed under the WTFPL
-- Version: v1.0pre-awe3.0rc4
---------------------------------------------------------------------------
-- Require libs
require("awful")
---- {{{ Grab environment
local ipairs = ipairs
local pairs = pairs
local print = print
local type = type
local tonumber = tonumber
local tostring = tostring
local math = math
local table = table
local awful = awful
local os = os
local io = io
local string = string
-- Grab C API
local capi =
{
awesome = awesome,
screen = screen,
client = client,
mouse = mouse,
button = button,
titlebar = titlebar,
widget = widget,
hooks = hooks,
keygrabber = keygrabber
}
-- }}}
-- Wicked: Widgets for the awesome window manager
module("wicked")
---- {{{ Initialise variables
local registered = {}
local widget_cache = {}
-- Initialise function tables
widgets = {}
helper = {}
local nets = {}
local cpu_total = {}
local cpu_active = {}
local cpu_usage = {}
-- }}}
---- {{{ Helper functions
----{{{ Max width
function helper.max_width(str, width)
l = str:len()
if l > width then
r = math.floor(width/2)
a = str:sub(1,r)
b = str:sub(l-r, l)
str = a .. "..." .. b
end
return str
end
----}}}
----{{{ Force a fixed width on a string with spaces
function helper.fixed_width(str, width)
l = str:len()
n = width-l
if n >= 0 then
for i = 1, n do
str = str.." "
end
else
str = str:sub(0, l+n)
end
return str
end
----}}}
---- {{{ Format a string with args
function helper.format(format, args)
-- TODO: Find a more efficient way to do this
-- Format a string
for var,val in pairs(args) do
format = string.gsub(format, '$'..var, val)
end
-- Return formatted string
return format
end
-- }}}
---- {{{ Padd a number to a minimum amount of digits
function helper.padd(number, padding)
s = tostring(number)
if padding == nil then
return s
end
for i=1,padding do
if math.floor(number/math.pow(10,(i-1))) == 0 then
s = "0"..s
end
end
if number == 0 then
s = s:sub(2)
end
return s
end
-- }}}
---- {{{ Convert amount of bytes to string
function helper.bytes_to_string(bytes, sec, padding)
if bytes == nil or tonumber(bytes) == nil then
return ''
end
bytes = tonumber(bytes)
signs = {}
signs[1] = ' b'
signs[2] = 'KiB'
signs[3] = 'MiB'
signs[4] = 'GiB'
signs[5] = 'TiB'
sign = 1
while bytes/1024 > 1 and signs[sign+1] ~= nil do
bytes = bytes/1024
sign = sign+1
end
bytes = bytes*10
bytes = math.floor(bytes)/10
if padding then
bytes = helper.padd(bytes*10, padding+1)
bytes = bytes:sub(1, bytes:len()-1).."."..bytes:sub(bytes:len())
end
if sec then
return tostring(bytes)..signs[sign]..'ps'
else
return tostring(bytes)..signs[sign]
end
end
-- }}}
---- {{{ Split by whitespace
function helper.splitbywhitespace(str)
values = {}
start = 1
splitstart, splitend = string.find(str, ' ', start)
while splitstart do
m = string.sub(str, start, splitstart-1)
if m:gsub(' ','') ~= '' then
table.insert(values, m)
end
start = splitend+1
splitstart, splitend = string.find(str, ' ', start)
end
m = string.sub(str, start)
if m:gsub(' ','') ~= '' then
table.insert(values, m)
end
return values
end
-- }}}
--{{{ Escape a string
function helper.escape(text)
if text then
text = text:gsub("&", "&amp;")
text = text:gsub("<", "&lt;")
text = text:gsub(">", "&gt;")
text = text:gsub("'", "&apos;")
text = text:gsub("\"", "&quot;")
end
return text
end
-- }}}
-- }}}
---- {{{ Widget types
---- {{{ MPD widget type
function widgets.mpd()
---- Get data from mpc
local nowplaying_file = io.popen('mpc')
local nowplaying = nowplaying_file:read()
-- Close the command
nowplaying_file:close()
-- Check that it's not nil
if nowplaying == nil then
return {''}
end
-- Escape
nowplaying = helper.escape(nowplaying)
-- Return it
return {nowplaying}
end
widget_cache[widgets.mpd] = {}
-- }}}
---- {{{ MOCP widget type
function widgets.mocp(format, max_width)
local playing = ''
---- Get data from mocp
local info = io.popen('mocp -i')
local state = info:read()
state = state.gsub(state, 'State: ', '')
if (state == "PLAY") then
local file = info:read()
file = file.gsub(file, 'File: ', '')
local title = info:read()
title = title.gsub(title, 'Title: ', '')
local artist = info:read()
artist = artist.gsub(artist, 'Artist: ', '')
local songtitle = info:read()
songtitle = songtitle.gsub(songtitle, 'SongTitle: ', '')
local album = info:read()
album = album.gsub(album, 'Album: ', '')
-- Try artist - (song)title
if (artist:len() > 0) then
playing = artist .. ' - ' .. (songtitle ~= '' and songtitle or title)
-- Else try title or songtitle
elseif (artist:len() == 0 and (title:len() > 0 or songtitle:len() > 0)) then
playing = (title ~= '' and title or songtitle)
-- Else use the filename
else
file = string.reverse(file)
i = string.find(file, '/')
if (i ~= nil) then
file = string.sub(file, 0, i-1)
end
playing = string.reverse(file)
end
else
playing = state
end
-- Close file
info:close()
-- Apply maximum width
if (max_width ~= nil) then
playing = helper.max_width(playing, max_width)
end
playing = helper.escape(playing)
-- Return it
return {playing}
end
widget_cache[widgets.mocp] = {}
-- }}}
---- {{{ CPU widget type
function widgets.cpu(format, padding)
-- Calculate CPU usage for all available CPUs / cores and return the
-- usage
-- Perform a new measurement
---- Get /proc/stat
local cpu_lines = {}
local cpu_usage_file = io.open('/proc/stat')
for line in cpu_usage_file:lines() do
if string.sub(line, 1, 3) == 'cpu' then
table.insert(cpu_lines, helper.splitbywhitespace(line))
end
end
cpu_usage_file:close()
---- Ensure tables are initialized correctly
while #cpu_total < #cpu_lines do
table.insert(cpu_total, 0)
end
while #cpu_active < #cpu_lines do
table.insert(cpu_active, 0)
end
while #cpu_usage < #cpu_lines do
table.insert(cpu_usage, 0)
end
---- Setup tables
total_new = {}
active_new = {}
diff_total = {}
diff_active = {}
for i,v in ipairs(cpu_lines) do
---- Calculate totals
total_new[i] = 0
for j = 2, #v do
total_new[i] = total_new[i] + v[j]
end
active_new[i] = v[2] + v[3] + v[4]
---- Calculate percentage
diff_total[i] = total_new[i] - cpu_total[i]
diff_active[i] = active_new[i] - cpu_active[i]
cpu_usage[i] = math.floor(diff_active[i] / diff_total[i] * 100)
---- Store totals
cpu_total[i] = total_new[i]
cpu_active[i] = active_new[i]
end
if padding ~= nil then
for k,v in pairs(cpu_usage) do
if type(padding) == "table" then
p = padding[k]
else
p = padding
end
cpu_usage[k] = helper.padd(cpu_usage[k], p)
end
end
return cpu_usage
end
widget_cache[widgets.cpu] = {}
-- }}}
---- {{{ Memory widget type
function widgets.mem(format, padding)
-- Return MEM usage values
local f = io.open('/proc/meminfo')
---- Get data
for line in f:lines() do
line = helper.splitbywhitespace(line)
if line[1] == 'MemTotal:' then
mem_total = math.floor(line[2]/1024)
elseif line[1] == 'MemFree:' then
free = math.floor(line[2]/1024)
elseif line[1] == 'Buffers:' then
buffers = math.floor(line[2]/1024)
elseif line[1] == 'Cached:' then
cached = math.floor(line[2]/1024)
end
end
f:close()
---- Calculate percentage
mem_free=free+buffers+cached
mem_inuse=mem_total-mem_free
mem_usepercent = math.floor(mem_inuse/mem_total*100)
if padding then
if type(padding) == "table" then
mem_usepercent = helper.padd(mem_usepercent, padding[1])
mem_inuse = helper.padd(mem_inuse, padding[2])
mem_total = helper.padd(mem_total, padding[3])
mem_free = helper.padd(mem_free, padding[4])
else
mem_usepercent = helper.padd(mem_usepercent, padding)
mem_inuse = helper.padd(mem_inuse, padding)
mem_total = helper.padd(mem_total, padding)
mem_free = helper.padd(mem_free, padding)
end
end
return {mem_usepercent, mem_inuse, mem_total, mem_free}
end
widget_cache[widgets.mem] = {}
-- }}}
---- {{{ Swap widget type
function widgets.swap(format, padding)
-- Return SWAP usage values
local f = io.open('/proc/meminfo')
---- Get data
for line in f:lines() do
line = helper.splitbywhitespace(line)
if line[1] == 'SwapTotal:' then
swap_total = math.floor(line[2]/1024)
elseif line[1] == 'SwapFree:' then
free = math.floor(line[2]/1024)
elseif line[1] == 'SwapCached:' then
cached = math.floor(line[2]/1024)
end
end
f:close()
---- Calculate percentage
swap_free=free+cached
swap_inuse=swap_total-swap_free
swap_usepercent = math.floor(swap_inuse/swap_total*100)
if padding then
if type(padding) == "table" then
swap_usepercent = helper.padd(swap_usepercent, padding[1])
swap_inuse = helper.padd(swap_inuse, padding[2])
swap_total = helper.padd(swap_total, padding[3])
swap_free = helper.padd(swap_free, padding[4])
else
swap_usepercent = helper.padd(swap_usepercent, padding)
swap_inuse = helper.padd(swap_inuse, padding)
swap_total = helper.padd(swap_total, padding)
swap_free = helper.padd(swap_free, padding)
end
end
return {swap_usepercent, swap_inuse, swap_total, swap_free}
end
widget_cache[widgets.swap] = {}
-- }}}
---- {{{ Date widget type
function widgets.date(format)
-- Get format
if format == nil then
return os.date()
else
return os.date(format)
end
end
-- }}}
---- {{{ Filesystem widget type
function widgets.fs(format, padding)
local f = io.popen('df -hP')
local args = {}
for line in f:lines() do
vars = helper.splitbywhitespace(line)
if vars[1] ~= 'Filesystem' and #vars == 6 then
vars[5] = vars[5]:gsub('%%','')
if padding then
if type(padding) == "table" then
vars[2] = helper.padd(vars[2], padding[1])
vars[3] = helper.padd(vars[3], padding[2])
vars[4] = helper.padd(vars[4], padding[3])
vars[5] = helper.padd(vars[5], padding[4])
else
vars[2] = helper.padd(vars[2], padding)
vars[3] = helper.padd(vars[3], padding)
vars[4] = helper.padd(vars[4], padding)
vars[5] = helper.padd(vars[5], padding)
end
end
args['{'..vars[6]..' size}'] = vars[2]
args['{'..vars[6]..' used}'] = vars[3]
args['{'..vars[6]..' avail}'] = vars[4]
args['{'..vars[6]..' usep}'] = vars[5]
end
end
f:close()
return args
end
-- }}}
---- {{{ Net widget type
function widgets.net(format, padding)
local f = io.open('/proc/net/dev')
args = {}
for line in f:lines() do
line = helper.splitbywhitespace(line)
local p = line[1]:find(':')
if p ~= nil then
name = line[1]:sub(0,p-1)
line[1] = line[1]:sub(p+1)
if tonumber(line[1]) == nil then
line[1] = line[2]
line[9] = line[10]
end
if padding then
args['{'..name..' rx}'] = helper.bytes_to_string(line[1], nil, padding)
args['{'..name..' tx}'] = helper.bytes_to_string(line[9], nil, padding)
else
args['{'..name..' rx}'] = helper.bytes_to_string(line[1])
args['{'..name..' tx}'] = helper.bytes_to_string(line[9])
end
args['{'..name..' rx_b}'] = math.floor(line[1]*10)/10
args['{'..name..' tx_b}'] = math.floor(line[9]*10)/10
args['{'..name..' rx_kb}'] = math.floor(line[1]/1024*10)/10
args['{'..name..' tx_kb}'] = math.floor(line[9]/1024*10)/10
args['{'..name..' rx_mb}'] = math.floor(line[1]/1024/1024*10)/10
args['{'..name..' tx_mb}'] = math.floor(line[9]/1024/1024*10)/10
args['{'..name..' rx_gb}'] = math.floor(line[1]/1024/1024/1024*10)/10
args['{'..name..' tx_gb}'] = math.floor(line[9]/1024/1024/1024*10)/10
if nets[name] == nil then
nets[name] = {}
args['{'..name..' down}'] = 'n/a'
args['{'..name..' up}'] = 'n/a'
args['{'..name..' down_b}'] = 0
args['{'..name..' up_b}'] = 0
args['{'..name..' down_kb}'] = 0
args['{'..name..' up_kb}'] = 0
args['{'..name..' down_mb}'] = 0
args['{'..name..' up_mb}'] = 0
args['{'..name..' down_gb}'] = 0
args['{'..name..' up_gb}'] = 0
nets[name].time = os.time()
else
interval = os.time()-nets[name].time
nets[name].time = os.time()
down = (line[1]-nets[name][1])/interval
up = (line[9]-nets[name][2])/interval
if padding then
args['{'..name..' down}'] = helper.bytes_to_string(down, true, padding)
args['{'..name..' up}'] = helper.bytes_to_string(up, true, padding)
else
args['{'..name..' down}'] = helper.bytes_to_string(down, true)
args['{'..name..' up}'] = helper.bytes_to_string(up, true)
end
args['{'..name..' down_b}'] = math.floor(down*10)/10
args['{'..name..' up_b}'] = math.floor(up*10)/10
args['{'..name..' down_kb}'] = math.floor(down/1024*10)/10
args['{'..name..' up_kb}'] = math.floor(up/1024*10)/10
args['{'..name..' down_mb}'] = math.floor(down/1024/1024*10)/10
args['{'..name..' up_mb}'] = math.floor(up/1024/1024*10)/10
args['{'..name..' down_gb}'] = math.floor(down/1024/1024/1024*10)/10
args['{'..name..' up_gb}'] = math.floor(up/1024/1024/1024*10)/10
end
nets[name][1] = line[1]
nets[name][2] = line[9]
end
end
f:close()
return args
end
widget_cache[widgets.net] = {}
-- }}}
---- {{{ Uptime widget type
function widgets.uptime(format, padding)
--Get uptime from /proc/uptime
local f = io.open("/proc/uptime")
uptime_line = f:read()
f:close()
args = {}
--/proc/uptime has the format "<up time> <idle time>"
if uptime_line:find(" ") ~= nil then
pend = uptime_line:find(" ",0,true)
uptime_line_part = uptime_line:sub(0,pend-1)
total_uptime = math.floor( tonumber(uptime_line_part) )
uptime_days = math.floor( total_uptime / (3600 * 24) )
uptime_hours = math.floor( ( total_uptime % (3600 * 24) ) / 3600 )
uptime_minutes = math.floor( ( ( total_uptime % (3600 * 24) ) % 3600 ) / 60 )
uptime_seconds = math.floor( ( ( total_uptime % (3600 * 24) ) % 3600) % 60 )
if padding then
if type(padding) == "table" then
total_uptime = helper.padd(total_uptime , padding[1])
uptime_days = helper.padd(uptime_days , padding[2])
uptime_hours = helper.padd(uptime_hours , padding[3])
uptime_minutes = helper.padd(uptime_minutes , padding[4])
uptime_seconds = helper.padd(uptime_seconds , padding[5])
else
total_uptime = helper.padd(total_uptime , padding)
uptime_days = helper.padd(uptime_days , padding)
uptime_hours = helper.padd(uptime_hours , padding)
uptime_minutes = helper.padd(uptime_minutes , padding)
uptime_seconds = helper.padd(uptime_seconds , padding)
end
end
end
return {total_uptime, uptime_days, uptime_hours, uptime_minutes, uptime_seconds}
end
widget_cache[widgets.uptime] = {}
-- }}}
-- For backwards compatibility: custom function
widgets["function"] = function ()
return {}
end
-- }}}
---- {{{ Main functions
---- {{{ Register widget
function register(widget, wtype, format, timer, field, padd)
local reg = {}
local widget = widget
-- Set properties
reg.type = wtype
reg.format = format
reg.timer = timer
reg.field = field
reg.padd = padd
reg.widget = widget
-- Update function
reg.update = function ()
update(widget, reg)
end
-- Default to timer=1
if reg.timer == nil then
reg.timer = 1
end
-- Allow using a string widget type
if type(reg.type) == "string" then
reg.type = widgets[reg.type]
end
-- Register reg object
regregister(reg)
-- Return reg object for reuse
return reg
end
-- }}}
-- {{{ Register from reg object
function regregister(reg)
if not reg.running then
-- Put widget in table
if registered[reg.widget] == nil then
registered[reg.widget] = {}
table.insert(registered[reg.widget], reg)
else
already = false
for w, i in pairs(registered) do
if w == reg.widget then
for k,v in pairs(i) do
if v == reg then
already = true
break
end
end
if already then
break
end
end
end
if not already then
table.insert(registered[reg.widget], reg)
end
end
-- Start timer
if reg.timer > 0 then
awful.hooks.timer.register(reg.timer, reg.update)
end
-- Initial update
reg.update()
-- Set running
reg.running = true
end
end
-- }}}
-- {{{ Unregister widget
function unregister(widget, keep, reg)
if reg == nil then
for w, i in pairs(registered) do
if w == widget then
for k,v in pairs(i) do
reg = unregister(w, keep, v)
end
end
end
return reg
end
if not keep then
for w, i in pairs(registered) do
if w == widget then
for k,v in pairs(i) do
if v == reg then
table.remove(registered[w], k)
end
end
end
end
end
awful.hooks.timer.unregister(reg.update)
reg.running = false
return reg
end
-- }}}
-- {{{ Suspend wicked, halt all widget updates
function suspend()
for w, i in pairs(registered) do
for k,v in pairs(i) do
unregister(w, true, v)
end
end
end
-- }}}
-- {{{ Activate wicked, restart all widget updates
function activate(widget)
for w, i in pairs(registered) do
if widget == nil or w == widget then
for k,v in pairs(i) do
regregister(v)
end
end
end
end
-- }}}
-- {{{ Enable caching for a widget type
function enable_caching(widget)
if widget_cache[widget] == nil then
widget_cache[widget] = {}
end
end
-- }}}
---- {{{ Update widget
function update(widget, reg, disablecache)
-- Check if there are any equal widgets
if reg == nil then
for w, i in pairs(registered) do
if w == widget then
for k,v in pairs(i) do
update(w, v, disablecache)
end
end
end
return
end
local t = os.time()
local data = {}
-- Check if we have output chached for this widget,
-- newer than last widget update.
if widget_cache[reg.type] ~= nil then
local c = widget_cache[reg.type]
if c.time == nil or c.time <= t-reg.timer or disablecache then
c.time = t
c.data = reg.type(reg.format, reg.padd)
end
data = c.data
else
data = reg.type(reg.format, reg.padd)
end
if type(data) == "table" then
if type(reg.format) == "string" then
data = helper.format(reg.format, data)
elseif type(reg.format) == "function" then
data = reg.format(widget, data)
end
end
if reg.field == nil then
widget.text = data
elseif widget.plot_data_add ~= nil then
widget:plot_data_add(reg.field, tonumber(data))
elseif widget.bar_data_add ~= nil then
widget:bar_data_add(reg.field, tonumber(data))
end
return data
end
-- }}}
-- }}}
-- vim: set filetype=lua fdm=marker tabstop=4 shiftwidth=4 nu:

141
zenburn.lua Normal file
View file

@ -0,0 +1,141 @@
-------------------------------
-- "Zenburn" awesome theme --
-- By Adrian C. (anrxc) --
-------------------------------
-- {{{ Main
theme = {}
theme.confdir = awful.util.getdir("config")
theme.wallpaper_cmd = { "/usr/bin/nitrogen --restore" }
--theme.wallpaper_cmd = { "awsetbg /usr/share/awesome/themes/zenburn/zenburn-background.png" }
-- }}}
-- {{{ Styles
theme.font = "Profont 8"
-- {{{ Colors
theme.fg_normal = "#DCDCCC"
theme.fg_focus = "#F0DFAF"
theme.fg_urgent = "#CC9393"
theme.bg_normal = "#3F3F3F"
theme.bg_focus = "#1E2320"
theme.bg_urgent = "#3F3F3F"
-- }}}
-- {{{ Borders
theme.border_width = "1"
theme.border_normal = "#3F3F3F"
theme.border_focus = "#6F6F6F"
theme.border_marked = "#CC9393"
-- }}}
-- {{{ Titlebars
theme.titlebar_bg_focus = "#3F3F3F"
theme.titlebar_bg_normal = "#3F3F3F"
-- theme.titlebar_[normal|focus]
-- }}}
-- {{{ Widgets
theme.fg_widget = "#AECF96"
theme.fg_center_widget = "#88A175"
theme.fg_end_widget = "#FF5656"
theme.fg_off_widget = "#494B4F"
theme.fg_netup_widget = "#7F9F7F"
theme.fg_netdn_widget = "#CC9393"
theme.bg_widget = "#3F3F3F"
theme.border_widget = "#3F3F3F"
-- }}}
-- {{{ Mouse finder
theme.mouse_finder_color = "#CC9393"
-- theme.mouse_finder_[timeout|animate_timeout|radius|factor]
-- }}}
-- {{{ Tooltips
-- theme.tooltip_[font|opacity|fg_color|bg_color|border_width|border_color]
-- }}}
-- {{{ Taglist and Tasklist
-- theme.[taglist|tasklist]_[bg|fg]_[focus|urgent]
-- }}}
-- {{{ Menu
-- theme.menu_[bg|fg]_[normal|focus]
-- theme.menu_[height|width|border_color|border_width]
-- }}}
-- }}}
-- {{{ Icons
--
-- {{{ Taglist icons
theme.taglist_squares_sel = theme.confdir .. "/icons/taglist/squarefz.png"
theme.taglist_squares_unsel = theme.confdir .. "/icons/taglist/squareza.png"
--theme.taglist_squares_resize = "false"
-- }}}
-- {{{ Misc icons
--theme.awesome_icon = theme.confdir .. "/icons/awesome.png"
--theme.menu_submenu_icon = "/usr/share/awesome/themes/default/submenu.png"
--theme.tasklist_floating_icon = "/usr/share/awesome/themes/default/tasklist/floatingw.png"
-- }}}
-- {{{ Layout icons
theme.layout_tile = theme.confdir .. "/icons/layouts/tile.png"
theme.layout_tileleft = theme.confdir .. "/icons/layouts/tileleft.png"
theme.layout_tilebottom = theme.confdir .. "/icons/layouts/tilebottom.png"
theme.layout_tiletop = theme.confdir .. "/icons/layouts/tiletop.png"
theme.layout_fairv = theme.confdir .. "/icons/layouts/fairv.png"
theme.layout_fairh = theme.confdir .. "/icons/layouts/fairh.png"
theme.layout_spiral = theme.confdir .. "/icons/layouts/spiral.png"
theme.layout_dwindle = theme.confdir .. "/icons/layouts/dwindle.png"
theme.layout_max = theme.confdir .. "/icons/layouts/max.png"
theme.layout_fullscreen = theme.confdir .. "/icons/layouts/fullscreen.png"
theme.layout_magnifier = theme.confdir .. "/icons/layouts/magnifier.png"
theme.layout_floating = theme.confdir .. "/icons/layouts/floating.png"
-- }}}
-- {{{ Widget icons
theme.widget_cpu = theme.confdir .. "/icons/cpu.png"
theme.widget_bat = theme.confdir .. "/icons/bat.png"
theme.widget_mem = theme.confdir .. "/icons/mem.png"
theme.widget_fs = theme.confdir .. "/icons/disk.png"
theme.widget_net = theme.confdir .. "/icons/down.png"
theme.widget_netup = theme.confdir .. "/icons/up.png"
theme.widget_mail = theme.confdir .. "/icons/mail.png"
theme.widget_vol = theme.confdir .. "/icons/vol.png"
theme.widget_org = theme.confdir .. "/icons/cal.png"
theme.widget_date = theme.confdir .. "/icons/time.png"
theme.widget_crypto = theme.confdir .. "/icons/crypto.png"
-- }}}
-- {{{ Titlebar icons
theme.titlebar_close_button_focus = theme.confdir .. "/icons/titlebar/close_focus.png"
theme.titlebar_close_button_normal = theme.confdir .. "/icons/titlebar/close_normal.png"
theme.titlebar_ontop_button_focus_active = theme.confdir .. "/icons/titlebar/ontop_focus_active.png"
theme.titlebar_ontop_button_normal_active = theme.confdir .. "/icons/titlebar/ontop_normal_active.png"
theme.titlebar_ontop_button_focus_inactive = theme.confdir .. "/icons/titlebar/ontop_focus_inactive.png"
theme.titlebar_ontop_button_normal_inactive = theme.confdir .. "/icons/titlebar/ontop_normal_inactive.png"
theme.titlebar_sticky_button_focus_active = theme.confdir .. "/icons/titlebar/sticky_focus_active.png"
theme.titlebar_sticky_button_normal_active = theme.confdir .. "/icons/titlebar/sticky_normal_active.png"
theme.titlebar_sticky_button_focus_inactive = theme.confdir .. "/icons/titlebar/sticky_focus_inactive.png"
theme.titlebar_sticky_button_normal_inactive = theme.confdir .. "/icons/titlebar/sticky_normal_inactive.png"
theme.titlebar_floating_button_focus_active = theme.confdir .. "/icons/titlebar/floating_focus_active.png"
theme.titlebar_floating_button_normal_active = theme.confdir .. "/icons/titlebar/floating_normal_active.png"
theme.titlebar_floating_button_focus_inactive = theme.confdir .. "/icons/titlebar/floating_focus_inactive.png"
theme.titlebar_floating_button_normal_inactive = theme.confdir .. "/icons/titlebar/floating_normal_inactive.png"
theme.titlebar_maximized_button_focus_active = theme.confdir .. "/icons/titlebar/maximized_focus_active.png"
theme.titlebar_maximized_button_normal_active = theme.confdir .. "/icons/titlebar/maximized_normal_active.png"
theme.titlebar_maximized_button_focus_inactive = theme.confdir .. "/icons/titlebar/maximized_focus_inactive.png"
theme.titlebar_maximized_button_normal_inactive = theme.confdir .. "/icons/titlebar/maximized_normal_inactive.png"
-- }}}
-- }}}
return theme