| 7 |      1 | require("naughty")
 | 
|  |      2 | require("awful")
 | 
|  |      3 | require("debug")
 | 
|  |      4 | require("vicious")
 | 
|  |      5 | require("wicked")
 | 
|  |      6 | require("beautiful")
 | 
|  |      7 | 
 | 
|  |      8 | local ipairs = ipairs
 | 
|  |      9 | local pairs = pairs
 | 
|  |     10 | local naughty = naughty
 | 
|  |     11 | local awful = awful
 | 
|  |     12 | local debug = debug
 | 
|  |     13 | local vicious = vicious
 | 
|  |     14 | local wicked = wicked
 | 
|  |     15 | local beautiful = beautiful
 | 
|  |     16 | 
 | 
|  |     17 | local capi = {
 | 
|  |     18 |    keygrabber = keygrabber,
 | 
|  |     19 |    client = client,
 | 
|  |     20 |    string = string,
 | 
|  |     21 |    widget = widget,
 | 
|  |     22 | }
 | 
|  |     23 | 
 | 
|  |     24 | module("my")
 | 
|  |     25 | 
 | 
|  |     26 | local in_error = false
 | 
|  |     27 | function notify_error(err)
 | 
|  |     28 |    -- Make sure we don't go into an endless error loop
 | 
|  |     29 |    if in_error then return end
 | 
|  |     30 |    in_error = true
 | 
|  |     31 | 
 | 
|  |     32 |    naughty.notify({ preset = naughty.config.presets.critical,
 | 
|  |     33 |                     title = "Oops, an error happened!",
 | 
|  |     34 |                     text = err })
 | 
|  |     35 |    in_error = false
 | 
|  |     36 | end
 | 
|  |     37 | 
 | 
|  |     38 | function mkspawn(p)
 | 
|  |     39 |    return function () awful.util.spawn(p) end
 | 
|  |     40 | end
 | 
|  |     41 | 
 | 
|  |     42 | function setxkbmap(kb)
 | 
|  |     43 |    XKBDIR="$HOME/.xkb"
 | 
|  |     44 |    -- Strange bug on xkbcomp: pushing directly the output to the display
 | 
|  |     45 |    -- lead to an error; We need to convert it first to .xkb and then feed
 | 
|  |     46 |    -- xkbcomp again for setting the x display
 | 
|  |     47 |    p = 'setxkbmap "' .. kb .. " -print | xkbcomp -xkb -a -I" .. XKBDIR .. " - - | kxbcomp - $DISPLAY"
 | 
|  |     48 |    awful.util.spawn_with_shell(p)
 | 
|  |     49 | end
 | 
|  |     50 | 
 | 
|  |     51 | function kill_all(rule)
 | 
|  |     52 |    for c in awful.client.iterate(rule) do
 | 
|  |     53 |       c:kill()
 | 
|  |     54 |    end
 | 
|  |     55 | end
 | 
|  |     56 | 
 | 
|  |     57 | function quit()
 | 
|  |     58 |    kill_all(awful.rules.any)
 | 
|  |     59 |    awesome.quit()
 | 
|  |     60 | end
 | 
|  |     61 | 
 | 
|  |     62 | function show_clients()
 | 
|  |     63 |    if instance then
 | 
|  |     64 |       instance:hide()
 | 
|  |     65 |       instance = nil
 | 
|  |     66 |    else
 | 
|  |     67 |       instance = awful.menu.clients({width=250})
 | 
|  |     68 |    end
 | 
|  |     69 | end
 | 
|  |     70 | 
 | 
|  |     71 | local function widgets_cpu()
 | 
|  |     72 |    local w = awful.widget.graph()
 | 
|  |     73 |    -- Graph properties
 | 
|  |     74 |    w:set_width(30)
 | 
|  |     75 |    w:set_background_color("#729fcf")
 | 
|  |     76 |    w:set_gradient_colors({ "#729fcf", "LightBlue", "white" })
 | 
|  |     77 | -- Register widget
 | 
|  |     78 |    vicious.register(w, vicious.widgets.cpu, "$1", 1)
 | 
|  |     79 |    return w
 | 
|  |     80 | end
 | 
|  |     81 | 
 | 
|  |     82 | local function widgets_mdp()
 | 
|  |     83 |    -- Initialize widget
 | 
|  |     84 |    local w = capi.widget({ type = "textbox" })
 | 
|  |     85 |    -- Register widget
 | 
|  |     86 |    vicious.register(w, vicious.widgets.mpd,
 | 
|  |     87 |                     function (widget, args)
 | 
|  |     88 |                        if args["{state}"] == "Stop" then 
 | 
|  |     89 |                           return " - "
 | 
|  |     90 |                        else 
 | 
|  |     91 |                           return args["{Artist}"]..' - '.. args["{Title}"]
 | 
|  |     92 |                        end
 | 
|  |     93 |                     end, 10)
 | 
|  |     94 |    return w
 | 
|  |     95 | end
 | 
|  |     96 | 
 | 
|  |     97 | local function widgets_mem(monitor)
 | 
|  |     98 | -- Initialize widget
 | 
|  |     99 |    local w = awful.widget.progressbar()
 | 
|  |    100 | -- Progressbar properties
 | 
|  |    101 |    w:set_width(10)
 | 
|  |    102 |    w:set_vertical(true)
 | 
|  |    103 |    w:set_background_color("#729fcf")
 | 
|  |    104 |    w:set_gradient_colors({ "#729fcf", "LightBlue", "white" })
 | 
|  |    105 | -- Register widget
 | 
|  |    106 |    vicious.register(w, vicious.widgets.mem, "$1", 5)
 | 
|  |    107 |    return w
 | 
|  |    108 | end
 | 
|  |    109 | 
 | 
|  |    110 | local function widgets_net(device)
 | 
|  |    111 |    local w = capi.widget({ type = "textbox"})
 | 
|  |    112 |    -- w:set_vertical(true)
 | 
|  |    113 |    w.width = 150
 | 
|  |    114 |    w.align = 'center'
 | 
|  |    115 |    vicious.register(w, wicked.widgets.net,
 | 
|  |    116 |                     '${' .. device .. ' up} / ${' .. device .. ' down}',
 | 
|  |    117 |                    1)
 | 
|  |    118 |    return w
 | 
|  |    119 | end
 | 
|  |    120 | 
 | 
|  |    121 | local function widgets_mode()
 | 
|  |    122 |    local w = capi.widget({ type = "textbox"})
 | 
|  |    123 |    widgets.mode_widget = w
 | 
|  |    124 |    return w
 | 
|  |    125 | end
 | 
|  |    126 | 
 | 
|  |    127 | local function widgets_keyboard()
 | 
|  |    128 |    local w = capi.widget({ type = "textbox"})
 | 
|  |    129 |    widgets.keyboard_widget = w
 | 
|  |    130 |    return w
 | 
|  |    131 | end
 | 
|  |    132 | 
 | 
|  |    133 | local function widgets_decorated(w, onclick)
 | 
|  |    134 |    local wg = w
 | 
|  |    135 |    if w.widget then
 | 
|  |    136 |       wg = w.widget
 | 
|  |    137 |    end
 | 
|  |    138 |    wg:buttons(awful.util.table.join(
 | 
|  |    139 |                 awful.button({}, 1, onclick)))
 | 
|  |    140 |    return w
 | 
|  |    141 | end
 | 
|  |    142 | 
 | 
|  |    143 | widgets = {
 | 
|  |    144 |    cpu = widgets_cpu,
 | 
|  |    145 |    mem = widgets_mem,
 | 
|  |    146 |    net = widgets_net,
 | 
|  |    147 |    mdp = widgets_mdp,
 | 
|  |    148 |    mode = widgets_mode,
 | 
|  |    149 |    keyboard = widgets_keyboard,
 | 
|  |    150 |    decorated = widgets_decorated,
 | 
|  |    151 | }
 | 
|  |    152 | 
 | 
|  |    153 | function make_key(k, n, f)
 | 
|  |    154 |    return { key = k, name = n, func = f}
 | 
|  |    155 | end
 | 
|  |    156 | 
 | 
|  |    157 | function show_kt(keytable, title)
 | 
|  |    158 |    -- todo: replace with a menu ?
 | 
|  |    159 |    text = ""
 | 
|  |    160 |    for _, k in ipairs(keytable) do
 | 
|  |    161 |       text = text .. "\'" .. k.key .. "\'\t" .. k.name .. "\n"
 | 
|  |    162 |    end
 | 
|  |    163 |    naughty.notify({text = text, 
 | 
|  |    164 |                    title = title, 
 | 
|  |    165 |                    position = "top_left",
 | 
|  |    166 |    })
 | 
|  |    167 | end
 | 
|  |    168 | 
 | 
|  |    169 | local keynames = {
 | 
|  |    170 |    [" "] = "space",
 | 
|  |    171 |    ["\t"] = "tab",
 | 
|  |    172 | }
 | 
|  |    173 | 
 | 
|  |    174 | local function translate_key(mod, key)
 | 
|  |    175 |    local skey = ""
 | 
|  |    176 |    for m,v in pairs(mod) do
 | 
|  |    177 |       if v then 
 | 
|  |    178 |          skey = skey .. v .. "+"
 | 
|  |    179 |       end
 | 
|  |    180 |    end
 | 
|  |    181 |    skey = skey .. (keynames[key] or key)
 | 
|  |    182 |    return skey
 | 
|  |    183 | end
 | 
|  |    184 | 
 | 
|  |    185 | local function kt_handler(keytable, mod, key, event)
 | 
|  |    186 |    if event == "release" then 
 | 
|  |    187 |       return true 
 | 
|  |    188 |    end
 | 
|  |    189 |    local theme = beautiful.get()
 | 
|  |    190 |    widgets.mode_widget.bg = theme.bg_focus
 | 
|  |    191 |    if key == "Escape" then   
 | 
|  |    192 |       return false
 | 
|  |    193 |    end
 | 
|  |    194 |    local skey = capi.string.lower(translate_key(mod, key))
 | 
|  |    195 |    if skey == "control+h" or skey == "shift+?" then
 | 
|  |    196 |       show_kt(keytable, "Current binding")
 | 
|  |    197 |       return true
 | 
|  |    198 |    end
 | 
|  |    199 |    for _,k in ipairs(keytable) do
 | 
|  |    200 |       if skey == capi.string.lower(k.key) then
 | 
|  |    201 |          return k.func(c)
 | 
|  |    202 |       end
 | 
|  |    203 |    end
 | 
|  |    204 |    -- notify_error("Nothing for " .. skey)
 | 
|  |    205 |    widgets.mode_widget.bg = theme.bg_urgent
 | 
|  |    206 |    return true
 | 
|  |    207 | end
 | 
|  |    208 | 
 | 
|  |    209 | local function stop_kt()
 | 
|  |    210 |    capi.keygrabber.stop()
 | 
|  |    211 |    widgets.mode_widget.visible = false
 | 
|  |    212 | end
 | 
|  |    213 | 
 | 
|  |    214 | function mkinteractive(f)
 | 
|  |    215 |   return function (c)
 | 
|  |    216 |      stop_kt()
 | 
|  |    217 |      return f(c)
 | 
|  |    218 |   end
 | 
|  |    219 | end
 | 
|  |    220 | 
 | 
|  |    221 | 
 | 
|  |    222 | -- local is_in_run_kt = false
 | 
|  |    223 | function run_kt(c, keytable, title)
 | 
|  |    224 |    widgets.mode_widget.text = "Mode: " .. title
 | 
|  |    225 |    widgets.mode_widget.visible = true
 | 
|  |    226 |    widgets.mode_widget.bg = "LightBlue"
 | 
|  |    227 |    widgets.mode_widget:buttons(
 | 
|  |    228 |       awful.util.table.join(
 | 
|  |    229 |          awful.button({}, 1, function () show_kt(keytable, "Binding") end),
 | 
|  |    230 |          awful.button({}, 3, stop_kt)))
 | 
|  |    231 |    capi.keygrabber.run(function (mod, key, event)
 | 
|  |    232 |          if not kt_handler(keytable, mod, key, event) then
 | 
|  |    233 |             stop_kt()
 | 
|  |    234 |             return false
 | 
|  |    235 |          end
 | 
|  |    236 |          return true
 | 
|  |    237 |    end)
 | 
|  |    238 | end
 | 
|  |    239 | 
 | 
|  |    240 | function make_kt(keytable, title)
 | 
|  |    241 |    return function (c) 
 | 
|  |    242 |       -- if is_in_run_kt then
 | 
|  |    243 |       --    -- notify_error("Already in run_kt:\n" .. debug.traceback())
 | 
|  |    244 |       --    is_in_run_kt = false -- reset
 | 
|  |    245 |       --    return false
 | 
|  |    246 |       -- end
 | 
|  |    247 |       return run_kt(c, keytable, title)
 | 
|  |    248 |    end
 | 
|  |    249 | end
 | 
|  |    250 | 
 | 
|  |    251 | function make_focus_bydirection(direction)
 | 
|  |    252 |    return function ()
 | 
|  |    253 |       awful.client.focus.bydirection(direction)
 | 
|  |    254 |       if capi.client.focus then capi.client.focus:raise() end
 | 
|  |    255 |       return true
 | 
|  |    256 |    end
 | 
|  |    257 | end
 | 
|  |    258 | 
 | 
|  |    259 | function make_globalkeys(modifiers, keytable)
 | 
|  |    260 |    local t = {}
 | 
|  |    261 |    for _,k in ipairs(keytable) do
 | 
|  |    262 |       t = awful.util.table.join(t, awful.key(modifiers, k.key, k.func))
 | 
|  |    263 |    end
 | 
|  |    264 |    return t
 | 
|  |    265 | end
 | 
|  |    266 | 
 |