local os = require("os")
local io = require("io")
local debug = require("debug")
local awesome = require("awesome")
local naughty = require("naughty")
local awful = require("awful")
local vicious = require("vicious")
local wicked = require("wicked")
local beautiful = require("beautiful")
local timer = require("timer")
local wibox = require("wibox")
local ipairs = ipairs
local pairs = pairs
local capi = {
keygrabber = require("keygrabber"),
client = require("client"),
string = require("string"),
}
module("my")
--- Stolen from shifty: Shows a popup and logs to a file
-- @param message The text message.
-- @param log_level 1 = INFO, 2 = WARN, 3 = ERROR, if nothting is provided 1 is used.
function log(message, log_level)
if log_level == nil then
log_level = 1
end
local log_table = {
{ level = "INFO", bg_colour = "#18F92C", fg_colour = "#0E0E0E" },
{ level = "WARN", bg_colour = "#9E731F", fg_colour = "#0E0E0E" },
{ level = "ERROR", bg_colour = "#FF0015", fg_colour = "#000000" }
}
-- %c eg: Wed Jan 30 14:25:13 2013
local time = os.date("%c")
message = time .. " - " .. log_table[log_level].level .. " - " .. message .. "\n" .. debug.traceback()
local home = os.getenv("HOME")
local log_file = io.open(home .. "/.awesome.log", "a+")
log_file:write(message .."\n")
log_file:close()
naughty.notify({ preset = naughty.config.presets.critical, text = message, bg = log_table[log_level].bg_colour, fg = log_table[log_level].fg_colour})
end
local in_error = false
function mk_notify_error_dialog(level)
return function(msg)
-- Make sure we don't go into an endless error loop
if in_error then return end
in_error = true
log(msg, level)
in_error = false
end
end
notify_error = mk_notify_error_dialog(3)
local function get_gradient_colors(c1, c2, c3)
return { type = "linear", from = { 0, 0 }, to = { 0, 20 }, stops = { { 0, c1 }, { 0.5, c2 }, { 1, c3 } }}
end
function mkspawn(p)
return function () awful.util.spawn(p) end
end
function setxkbmap(kb)
XKBDIR="$HOME/.xkb"
-- Strange bug on xkbcomp: pushing directly the output to the display
-- lead to an error; We need to convert it first to .xkb and then feed
-- xkbcomp again for setting the x display
p = 'setxkbmap "' .. kb .. " -print | xkbcomp -xkb -a -I" .. XKBDIR .. " - - | kxbcomp - $DISPLAY"
awful.util.spawn_with_shell(p)
end
function kill_all(rule)
for c in awful.client.iterate(rule) do
c:kill()
end
end
function quit()
kill_all(function (c) return true end)
awesome.quit()
end
function show_clients()
if instance then
instance:hide()
instance = nil
else
instance = awful.menu.clients({width=250})
end
end
local function widgets_cpu()
local w = awful.widget.graph()
-- Graph properties
w:set_width(30)
w:set_background_color("#729fcf")
w:set_color(get_gradient_colors("#729fcf", "LightBlue", "white"))
-- Register widget
vicious.register(w, vicious.widgets.cpu, "$1", 1)
return w
end
local function widgets_mdp()
-- Initialize widget
local w = wibox.widget.textbox()
-- Register widget
vicious.register(w, vicious.widgets.mpd,
function (widget, args)
if args["{state}"] == "Stop" then
return " - "
else
return args["{Artist}"]..' - '.. args["{Title}"]
end
end, 10)
return w
end
local function widgets_mem(monitor)
-- Initialize widget
local w = awful.widget.progressbar()
-- Progressbar properties
w:set_width(10)
w:set_vertical(true)
w:set_background_color("#729fcf")
w:set_color(get_gradient_colors("#729fcf", "LightBlue", "white"))
-- Register widget
vicious.register(w, vicious.widgets.mem, "$1", 5)
return w
end
local function widgets_net(device)
local w = wibox.widget.textbox()
-- w:set_vertical(true)
w.width = 150
w.align = 'center'
vicious.register(w, wicked.widgets.net,
'${' .. device .. ' up} / ${' .. device .. ' down}',
1)
return w
end
local function widgets_mode()
local bg = wibox.widget.background()
local w = wibox.widget.textbox()
bg:set_widget(w)
widgets.mode_widget = w
widgets.mode_widget_bg = bg
return bg
end
local function widgets_keyboard()
local w = wibox.widget.textbox()
widgets.keyboard_widget = w
return w
end
local function widgets_decorated(w, onclick)
local wg = w
if w.widget then
wg = w.widget
end
wg:buttons(awful.util.table.join(
awful.button({}, 1, onclick)))
return w
end
widgets = {
cpu = widgets_cpu,
mem = widgets_mem,
net = widgets_net,
mdp = widgets_mdp,
mode = widgets_mode,
keyboard = widgets_keyboard,
decorated = widgets_decorated,
}
function make_key(k, n, f)
return { key = k, name = n, func = f}
end
function show_kt(keytable, title)
-- todo: replace with a menu ?
text = ""
for _, k in ipairs(keytable) do
text = text .. "\'" .. k.key .. "\'\t" .. k.name .. "\n"
end
naughty.notify({text = text,
title = title,
position = "top_left",
})
end
local keynames = {
[" "] = "space",
["\t"] = "tab",
}
local ignored_mods = {
["Mod2"] = true,
}
local function translate_key(mod, key)
local skey = ""
for m,v in pairs(mod) do
if not ignored_mods[v] then
skey = skey .. v .. "+"
end
end
skey = skey .. (keynames[key] or key)
return skey
end
local function kt_handler(keytable, mod, key, event)
if event == "release" then
return true
end
local theme = beautiful.get()
widgets.mode_widget_bg:set_bg(theme.bg_focus)
if key == "Escape" then
return false
end
local skey = capi.string.lower(translate_key(mod, key))
if skey == "control+h" or skey == "shift+?" then
show_kt(keytable, "Current binding")
return true
end
for _,k in ipairs(keytable) do
if skey == capi.string.lower(k.key) then
return k.func(c)
end
end
-- notify_error("Nothing for " .. skey)
widgets.mode_widget_bg:set_bg(theme.bg_urgent)
return true
end
local function stop_kt()
capi.keygrabber.stop()
widgets.mode_widget:set_text("")
end
function mkinteractive(f)
return function (c)
stop_kt()
return f(c)
end
end
-- local is_in_run_kt = false
function run_kt(c, keytable, title)
widgets.mode_widget:set_text("Mode: " .. title)
-- widgets.mode_widget:show()
widgets.mode_widget_bg:set_bg("LightBlue")
widgets.mode_widget:buttons(
awful.util.table.join(
awful.button({}, 1, function () show_kt(keytable, "Binding") end),
awful.button({}, 3, stop_kt)))
capi.keygrabber.run(function (mod, key, event)
if not kt_handler(keytable, mod, key, event) then
stop_kt()
return false
end
return true
end)
end
function make_kt(keytable, title)
return function (c)
-- if is_in_run_kt then
-- -- notify_error("Already in run_kt:\n" .. debug.traceback())
-- is_in_run_kt = false -- reset
-- return false
-- end
return run_kt(c, keytable, title)
end
end
function make_focus_bydirection(direction)
return function ()
awful.client.focus.bydirection(direction)
if capi.client.focus then capi.client.focus:raise() end
return true
end
end
function make_globalkeys(modifiers, keytable)
local t = {}
for _,k in ipairs(keytable) do
t = awful.util.table.join(t, awful.key(modifiers, k.key, k.func))
end
return t
end
-- Install a sloppy-like focus with a timeout.
function sloppy_toggle()
sloppy = not sloppy
end
function sloppy_mouse_enter(c)
if sloppy and
c ~= sloppy_last_client and
awful.client.focus.filter(c) and
awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
then
if sloppy_timer.started
then
sloppy_timer:again()
else
sloppy_timer:start()
end
sloppy_last_client = c
end
end
function sloppy_on_timeout()
if sloppy
then
local c = awful.mouse.client_under_pointer()
if c and
c == sloppy_last_client
then
capi.client.focus = c
sloppy_timer:stop()
end
end
end
sloppy = true
sloppy_last_client = nil
sloppy_timer = nil
function sloppy_install(delay)
sloppy_timer = timer({ timeout = delay })
sloppy_timer:connect_signal("timeout", sloppy_on_timeout)
sloppy_timer:start()
capi.client.connect_signal("manage", function (c)
c:connect_signal("mouse::enter", sloppy_mouse_enter)
end)
capi.client.connect_signal("focus", function ()
if sloppy_timer.started then
sloppy_timer:stop()
end
end)
end