author | Fabien Ninoles <fabien@tzone.org> |
Sun, 14 Jun 2015 22:18:07 -0400 | |
changeset 11 | 7226709dc4c4 |
parent 9 | 56e80afa3e1c |
child 12 | ffc02bf394cb |
permissions | -rw-r--r-- |
11 | 1 |
local naughty = require("naughty") |
2 |
local awful = require("awful") |
|
3 |
local debug = require("debug") |
|
4 |
local vicious = require("vicious") |
|
5 |
local wicked = require("wicked") |
|
6 |
local beautiful = require("beautiful") |
|
7 |
local timer = require("timer") |
|
8 |
local wibox = require("wibox") |
|
7 | 9 |
|
10 |
local ipairs = ipairs |
|
11 |
local pairs = pairs |
|
12 |
||
13 |
local capi = { |
|
14 |
keygrabber = keygrabber, |
|
15 |
client = client, |
|
16 |
string = string, |
|
17 |
widget = widget, |
|
18 |
} |
|
19 |
||
20 |
module("my") |
|
21 |
||
11 | 22 |
local function get_gradient_colors(c1, c2, c3) |
23 |
return { type = "linear", from = { 0, 0 }, to = { 0, 20 }, stops = { { 0, c1 }, { 0.5, c2 }, { 1, c3 } }} |
|
24 |
end |
|
25 |
||
7 | 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") |
|
11 | 76 |
w:set_color(get_gradient_colors("#729fcf", "LightBlue", "white")) |
7 | 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 |
|
11 | 84 |
local w = wibox.widget.textbox() |
7 | 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") |
|
11 | 104 |
w:set_color(get_gradient_colors("#729fcf", "LightBlue", "white")) |
7 | 105 |
-- Register widget |
106 |
vicious.register(w, vicious.widgets.mem, "$1", 5) |
|
107 |
return w |
|
108 |
end |
|
109 |
||
110 |
local function widgets_net(device) |
|
11 | 111 |
local w = wibox.widget.textbox() |
7 | 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() |
|
11 | 122 |
local w = wibox.widget.textbox() |
7 | 123 |
widgets.mode_widget = w |
124 |
return w |
|
125 |
end |
|
126 |
||
127 |
local function widgets_keyboard() |
|
11 | 128 |
local w = wibox.widget.textbox() |
7 | 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 |
||
8 | 174 |
local ignored_mods = { |
175 |
["Mod2"] = true, |
|
176 |
} |
|
177 |
||
7 | 178 |
local function translate_key(mod, key) |
179 |
local skey = "" |
|
180 |
for m,v in pairs(mod) do |
|
8 | 181 |
if not ignored_mods[v] then |
7 | 182 |
skey = skey .. v .. "+" |
183 |
end |
|
184 |
end |
|
185 |
skey = skey .. (keynames[key] or key) |
|
186 |
return skey |
|
187 |
end |
|
188 |
||
189 |
local function kt_handler(keytable, mod, key, event) |
|
190 |
if event == "release" then |
|
191 |
return true |
|
192 |
end |
|
193 |
local theme = beautiful.get() |
|
194 |
widgets.mode_widget.bg = theme.bg_focus |
|
195 |
if key == "Escape" then |
|
196 |
return false |
|
197 |
end |
|
198 |
local skey = capi.string.lower(translate_key(mod, key)) |
|
199 |
if skey == "control+h" or skey == "shift+?" then |
|
200 |
show_kt(keytable, "Current binding") |
|
201 |
return true |
|
202 |
end |
|
203 |
for _,k in ipairs(keytable) do |
|
204 |
if skey == capi.string.lower(k.key) then |
|
205 |
return k.func(c) |
|
206 |
end |
|
207 |
end |
|
208 |
-- notify_error("Nothing for " .. skey) |
|
209 |
widgets.mode_widget.bg = theme.bg_urgent |
|
210 |
return true |
|
211 |
end |
|
212 |
||
213 |
local function stop_kt() |
|
214 |
capi.keygrabber.stop() |
|
215 |
widgets.mode_widget.visible = false |
|
216 |
end |
|
217 |
||
218 |
function mkinteractive(f) |
|
219 |
return function (c) |
|
220 |
stop_kt() |
|
221 |
return f(c) |
|
222 |
end |
|
223 |
end |
|
224 |
||
225 |
||
226 |
-- local is_in_run_kt = false |
|
227 |
function run_kt(c, keytable, title) |
|
228 |
widgets.mode_widget.text = "Mode: " .. title |
|
229 |
widgets.mode_widget.visible = true |
|
230 |
widgets.mode_widget.bg = "LightBlue" |
|
231 |
widgets.mode_widget:buttons( |
|
232 |
awful.util.table.join( |
|
233 |
awful.button({}, 1, function () show_kt(keytable, "Binding") end), |
|
234 |
awful.button({}, 3, stop_kt))) |
|
235 |
capi.keygrabber.run(function (mod, key, event) |
|
236 |
if not kt_handler(keytable, mod, key, event) then |
|
237 |
stop_kt() |
|
238 |
return false |
|
239 |
end |
|
240 |
return true |
|
241 |
end) |
|
242 |
end |
|
243 |
||
244 |
function make_kt(keytable, title) |
|
245 |
return function (c) |
|
246 |
-- if is_in_run_kt then |
|
247 |
-- -- notify_error("Already in run_kt:\n" .. debug.traceback()) |
|
248 |
-- is_in_run_kt = false -- reset |
|
249 |
-- return false |
|
250 |
-- end |
|
251 |
return run_kt(c, keytable, title) |
|
252 |
end |
|
253 |
end |
|
254 |
||
255 |
function make_focus_bydirection(direction) |
|
256 |
return function () |
|
257 |
awful.client.focus.bydirection(direction) |
|
258 |
if capi.client.focus then capi.client.focus:raise() end |
|
259 |
return true |
|
260 |
end |
|
261 |
end |
|
262 |
||
263 |
function make_globalkeys(modifiers, keytable) |
|
264 |
local t = {} |
|
265 |
for _,k in ipairs(keytable) do |
|
266 |
t = awful.util.table.join(t, awful.key(modifiers, k.key, k.func)) |
|
267 |
end |
|
268 |
return t |
|
269 |
end |
|
270 |
||
8 | 271 |
-- Install a sloppy-like focus with a timeout. |
272 |
||
273 |
function sloppy_toggle() |
|
274 |
sloppy = not sloppy |
|
275 |
end |
|
276 |
||
277 |
function sloppy_mouse_enter(c) |
|
278 |
if sloppy and |
|
279 |
c ~= sloppy_last_client and |
|
280 |
awful.client.focus.filter(c) and |
|
281 |
awful.layout.get(c.screen) ~= awful.layout.suit.magnifier |
|
282 |
then |
|
9
56e80afa3e1c
Only start sloppy timer on a mouse_enter.
Fabien Ninoles <fabien@tzone.org>
parents:
8
diff
changeset
|
283 |
if sloppy_timer.started |
56e80afa3e1c
Only start sloppy timer on a mouse_enter.
Fabien Ninoles <fabien@tzone.org>
parents:
8
diff
changeset
|
284 |
then |
56e80afa3e1c
Only start sloppy timer on a mouse_enter.
Fabien Ninoles <fabien@tzone.org>
parents:
8
diff
changeset
|
285 |
sloppy_timer:again() |
56e80afa3e1c
Only start sloppy timer on a mouse_enter.
Fabien Ninoles <fabien@tzone.org>
parents:
8
diff
changeset
|
286 |
else |
56e80afa3e1c
Only start sloppy timer on a mouse_enter.
Fabien Ninoles <fabien@tzone.org>
parents:
8
diff
changeset
|
287 |
sloppy_timer:start() |
56e80afa3e1c
Only start sloppy timer on a mouse_enter.
Fabien Ninoles <fabien@tzone.org>
parents:
8
diff
changeset
|
288 |
end |
8 | 289 |
sloppy_last_client = c |
290 |
end |
|
291 |
end |
|
292 |
||
293 |
function sloppy_on_timeout() |
|
294 |
if sloppy |
|
295 |
then |
|
296 |
local c = awful.mouse.client_under_pointer() |
|
297 |
if c and |
|
298 |
c == sloppy_last_client |
|
299 |
then |
|
300 |
capi.client.focus = c |
|
9
56e80afa3e1c
Only start sloppy timer on a mouse_enter.
Fabien Ninoles <fabien@tzone.org>
parents:
8
diff
changeset
|
301 |
sloppy_timer:stop() |
8 | 302 |
end |
303 |
end |
|
304 |
end |
|
305 |
||
306 |
sloppy = true |
|
307 |
sloppy_last_client = nil |
|
308 |
sloppy_timer = nil |
|
309 |
||
310 |
function sloppy_install(delay) |
|
311 |
sloppy_timer = timer({ timeout = delay }) |
|
11 | 312 |
sloppy_timer:connect_signal("timeout", sloppy_on_timeout) |
8 | 313 |
sloppy_timer:start() |
11 | 314 |
capi.client.connect_signal("manage", function (c) |
315 |
c:connect_signal("mouse::enter", sloppy_mouse_enter) |
|
8 | 316 |
end) |
11 | 317 |
capi.client.connect_signal("focus", function () sloppy_timer:stop() end) |
8 | 318 |
end |