|
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 |