· 7 years ago · Nov 09, 2018, 03:24 PM
1local awful = require("awful")
2local config_path = awful.util.getdir("config")
3package.path = config_path .. "/?.lua;" .. package.path
4package.path = config_path .. "/?/init.lua;" .. package.path
5package.path = config_path .. "/modules/?.lua;" .. package.path
6package.path = config_path .. "/modules/?/init.lua;" .. package.path
7
8local math = require("math")
9local gears = require("gears")
10awful.client = require("awful.client")
11awful.screen = require("awful.screen")
12awful.mouse = require("awful.mouse")
13awful.rules = require("awful.rules")
14awful.menu = require("awful.menu")
15awful.ewmh = require("awful.ewmh")
16require("awful.autofocus")
17require("awful.dbus")
18require("awful.remote")
19local wibox = require("wibox")
20local beautiful = require("beautiful")
21local naughty = require("naughty")
22local menubar = require("menubar")
23local hotkeys_popup = require("awful.hotkeys_popup").widget
24local xrandr = require("xrandr")
25local foggy = require("foggy")
26
27-- vicious widgets
28local vicious = require("vicious")
29
30-- bashets config: https://gitorious.org/bashets/pages/Brief_Introduction
31local bashets = require("bashets")
32
33-- utilities
34local util = require("util")
35
36-- universal arguments
37local uniarg = require("uniarg")
38
39local capi = {
40 tag = tag,
41 screen = screen,
42 client = client,
43 timer = timer,
44}
45
46local timer = require("gears.timer")
47
48-- do not use letters, which shadow access key to menu entry
49awful.menu.menu_keys.down = { "Down", ".", ">", "'", "\"", }
50awful.menu.menu_keys.up = { "Up", ",", "<", ";", ":", }
51awful.menu.menu_keys.enter = { "Right", "]", "}", "=", "+", }
52awful.menu.menu_keys.back = { "Left", "[", "{", "-", "_", }
53awful.menu.menu_keys.exec = { "Return", "Space", }
54awful.menu.menu_keys.close = { "Escape", "BackSpace", }
55
56-- customization
57customization = {}
58customization.config = {}
59customization.orig = {}
60customization.func = {}
61customization.default = {}
62customization.option = {}
63customization.timer = {}
64customization.widgets = {}
65
66customization.config.version = "4.0.13"
67customization.config.help_url = "https://github.com/pw4ever/awesome-wm-config/tree/" .. customization.config.version
68
69customization.default.property = {
70 layout = awful.layout.suit.floating,
71 mwfact = 0.5,
72 nmaster = 1,
73 ncol = 1,
74 min_opacity = 0.4,
75 max_opacity = 1,
76 default_naughty_opacity = 1,
77 low_naughty_opacity = 0.90,
78 normal_naughty_opacity = 0.95,
79 critical_naughty_opacity = 1,
80 minimal_client_width = 50,
81 minimal_client_height = 50,
82}
83
84customization.default.compmgr = 'xcompmgr'
85customization.default.compmgr_args = '-f -c -s'
86customization.default.wallpaper_change_interval = 15
87
88customization.option.wallpaper_change_p = true
89customization.option.tag_persistent_p = true
90customization.option.low_battery_notification_p = true
91
92naughty.config.presets.low.opacity = customization.default.property.low_naughty_opacity
93naughty.config.presets.normal.opacity = customization.default.property.normal_naughty_opacity
94naughty.config.presets.critical.opacity = customization.default.property.critical_naughty_opacity
95
96do
97 local config_path = awful.util.getdir("config")
98 bashets.set_script_path(config_path .. "/modules/bashets/")
99end
100
101-- {{{ Error handling
102-- Check if awesome encountered an error during startup and fell back to
103-- another config (This code will only ever execute for the fallback config)
104if awesome.startup_errors then
105 naughty.notify({ preset = naughty.config.presets.critical,
106 title = "Oops, there were errors during startup!",
107 text = awesome.startup_errors })
108end
109
110-- Handle runtime errors after startup
111do
112 local in_error = false
113 awesome.connect_signal("debug::error", function (err)
114 -- Make sure we don't go into an endless error loop
115 if in_error then return end
116 in_error = true
117
118 naughty.notify({ preset = naughty.config.presets.critical,
119 title = "Oops, an error happened!",
120 text = err })
121 in_error = false
122 end)
123end
124-- }}}
125
126-- {{{
127-- HACK! prevent Awesome start autostart items multiple times in a session
128-- cause: in-place restart by awesome.restart, xrandr change
129-- idea:
130-- * create a file awesome-autostart-once when first time "dex" autostart items (at the end of this file)
131-- * only "rm" this file when awesome.quit
132
133local cachedir = awful.util.getdir("cache")
134local awesome_tags_fname = cachedir .. "/awesome-tags"
135local awesome_autostart_once_fname = cachedir .. "/awesome-autostart-once-" .. os.getenv("XDG_SESSION_ID")
136local awesome_client_tags_fname = cachedir .. "/awesome-client-tags-" .. os.getenv("XDG_SESSION_ID")
137
138do
139
140 awesome.connect_signal("exit", function (restart)
141 local scrcount = screen.count()
142 -- save number of screens, used for check proper tag recording
143 do
144 local f = io.open(awesome_tags_fname .. ".0", "w+")
145 if f then
146 f:write(string.format("%d", scrcount) .. "\n")
147 f:close()
148 end
149 end
150 -- save current tags
151 for s = 1, scrcount do
152 local f = io.open(awesome_tags_fname .. "." .. s, "w+")
153 if f then
154 local tags = awful.tag.gettags(s)
155 for _, tag in ipairs(tags) do
156 f:write(tag.name .. "\n")
157 end
158 f:close()
159 end
160 f = io.open(awesome_tags_fname .. "-selected." .. s, "w+")
161 if f then
162 f:write(awful.tag.getidx() .. "\n")
163 f:close()
164 end
165 end
166 customization.func.client_opaque_off(nil) -- prevent compmgr glitches
167 if not restart then
168 awful.util.spawn_with_shell("rm -rf " .. awesome_autostart_once_fname)
169 awful.util.spawn_with_shell("rm -rf " .. awesome_client_tags_fname)
170 if not customization.option.tag_persistent_p then
171 awful.util.spawn_with_shell("rm -rf " .. awesome_tags_fname .. '*')
172 end
173 bashets.stop()
174 else -- if restart, save client tags
175 -- save tags for each client
176 awful.util.mkdir(awesome_client_tags_fname)
177 -- !! avoid awful.util.spawn_with_shell("mkdir -p " .. awesome_client_tags_fname)
178 -- race condition (whether awesome_client_tags_fname is created) due to asynchrony of "spawn_with_shell"
179 for _, c in ipairs(client.get()) do
180 local client_id = c.pid .. '-' .. c.window
181 local f = io.open(awesome_client_tags_fname .. '/' .. client_id, 'w+')
182 if f then
183 for _, t in ipairs(c:tags()) do
184 f:write(t.name .. "\n")
185 end
186 f:close()
187 end
188 end
189
190 end
191 end)
192
193 customization.orig.quit = awesome.quit
194 awesome.quit = function ()
195 local scr = awful.screen.focused()
196 awful.prompt.run({prompt = "Quit (type 'yes' to confirm)? "},
197 customization.widgets.promptbox[scr].widget,
198 function (t)
199 if string.lower(t) == 'yes' then
200 customization.orig.quit()
201 end
202 end,
203 function (t, p, n)
204 return awful.completion.generic(t, p, n, {'no', 'NO', 'yes', 'YES'})
205 end)
206 end
207end
208
209do
210
211 customization.orig.restart = awesome.restart
212 awesome.restart = function ()
213 local scr = awful.screen.focused()
214 awful.prompt.run({prompt = "Restart (type 'yes' to confirm)? "},
215 customization.widgets.promptbox[scr].widget,
216 function (t)
217 if string.lower(t) == 'yes' then
218 customization.orig.restart()
219 end
220 end,
221 function (t, p, n)
222 return awful.completion.generic(t, p, n, {'no', 'NO', 'yes', 'YES'})
223 end)
224 end
225end
226
227-- }}}
228
229-- {{{ Variable definitions
230-- Themes define colours, icons, and wallpapers
231---[[
232
233do
234 local config_path = awful.util.getdir("config")
235 local function init_theme(theme_name)
236 local theme_path = config_path .. "/themes/" .. theme_name .. "/theme.lua"
237 beautiful.init(theme_path)
238 end
239
240 init_theme("zenburn")
241
242 awful.util.spawn_with_shell("hsetroot -solid '#000000'")
243
244 -- randomly select a background picture
245 --{{
246 function customization.func.change_wallpaper()
247 if customization.option.wallpaper_change_p then
248 awful.util.spawn_with_shell("cd " .. config_path .. "/wallpaper/; ./my-wallpaper-pick.sh")
249 end
250 end
251
252 customization.timer.change_wallpaper= timer({timeout = customization.default.wallpaper_change_interval})
253
254 customization.timer.change_wallpaper:connect_signal("timeout", customization.func.change_wallpaper)
255
256 customization.timer.change_wallpaper:connect_signal("property::timeout",
257 function ()
258 customization.timer.change_wallpaper:stop()
259 customization.timer.change_wallpaper:start()
260 end
261 )
262
263 customization.timer.change_wallpaper:start()
264 -- first trigger
265 customization.func.change_wallpaper()
266 --}}
267end
268--]]
269
270-- This is used later as the default terminal and editor to run.
271
272--{{
273local tools = {
274 terminal = "sakura",
275 system = {
276 filemanager = "pcmanfm",
277 taskmanager = "lxtask",
278 },
279 browser = {
280 },
281 editor = {
282 },
283}
284
285tools.browser.primary = os.getenv("BROWSER") or "firefox"
286tools.browser.secondary = ({chromium="firefox", firefox="chromium"})[tools.browser.primary]
287
288-- alternative: override
289--tools.browser.primary = "google-chrome-stable"
290--tools.browser.secondary = "firefox"
291
292tools.editor.primary = os.getenv("EDITOR") or "gvim"
293tools.editor.secondary = ({emacs="gvim", gvim="emacs"})[tools.editor.primary]
294
295-- alternative: override
296--tools.editor.primary = "gvim"
297--tools.editor.secondary = "emacs"
298
299local myapp = nil
300do
301 local function build(arg)
302 local current = {}
303 local keys = {} -- keep the keys sorted
304 for k, v in pairs(arg) do table.insert(keys, k) end
305 table.sort(keys)
306
307 for _, k in ipairs(keys) do
308 v = arg[k]
309 if type(v) == 'table' then
310 table.insert(current, {k, build(v)})
311 else
312 table.insert(current, {v, v})
313 end
314 end
315 return current
316 end
317 myapp = build(tools)
318end
319--}}
320
321-- Default modkey.
322-- Usually, Mod4 is the key with a logo between Control and Alt.
323-- If you do not like this or do not have such a key,
324-- I suggest you to remap Mod4 to another key using xmodmap or other tools.
325-- However, you can use another modifier like Mod1, but it may interact with others.
326modkey = "Mod4"
327
328-- Table of layouts to cover with awful.layout.inc, order matters.
329local layouts =
330{
331 awful.layout.suit.floating,
332 awful.layout.suit.tile,
333 awful.layout.suit.fair,
334 awful.layout.suit.max.fullscreen,
335 awful.layout.suit.magnifier,
336}
337--[[
338local layouts =
339{
340awful.layout.suit.floating,
341awful.layout.suit.tile,
342awful.layout.suit.tile.left,
343awful.layout.suit.tile.bottom,
344awful.layout.suit.tile.top,
345awful.layout.suit.fair,
346awful.layout.suit.fair.horizontal,
347awful.layout.suit.spiral,
348awful.layout.suit.spiral.dwindle,
349awful.layout.suit.max,
350awful.layout.suit.max.fullscreen,
351awful.layout.suit.magnifier
352}
353--]]
354-- }}}
355
356--[[
357-- {{{ Wallpaper
358if beautiful.wallpaper then
359for s = 1, screen.count() do
360gears.wallpaper.maximized(beautiful.wallpaper, s, true)
361end
362end
363-- }}}
364--]]
365
366-- {{{ Customized functions
367
368customization.func.system_lock = function ()
369 awful.util.spawn("xscreensaver-command -l")
370end
371
372customization.func.system_suspend = function ()
373 awful.util.spawn("systemctl suspend")
374end
375
376customization.func.system_hibernate = function ()
377 local scr = awful.screen.focused()
378 awful.prompt.run({prompt = "Hibernate (type 'yes' to confirm)? "},
379 customization.widgets.promptbox[scr].widget,
380 function (t)
381 if string.lower(t) == 'yes' then
382 awful.util.spawn("systemctl hibernate")
383 end
384 end,
385 function (t, p, n)
386 return awful.completion.generic(t, p, n, {'no', 'NO', 'yes', 'YES'})
387 end)
388end
389
390customization.func.system_hybrid_sleep = function ()
391 local scr = awful.screen.focused()
392 awful.prompt.run({prompt = "Hybrid Sleep (type 'yes' to confirm)? "},
393 customization.widgets.promptbox[scr].widget,
394 function (t)
395 if string.lower(t) == 'yes' then
396 awful.util.spawn("systemctl hybrid-sleep")
397 end
398 end,
399 function (t, p, n)
400 return awful.completion.generic(t, p, n, {'no', 'NO', 'yes', 'YES'})
401 end)
402end
403
404customization.func.system_reboot = function ()
405 local scr = awful.screen.focused()
406 awful.prompt.run({prompt = "Reboot (type 'yes' to confirm)? "},
407 customization.widgets.promptbox[scr].widget,
408 function (t)
409 if string.lower(t) == 'yes' then
410 awesome.emit_signal("exit", nil)
411 awful.util.spawn("systemctl reboot")
412 end
413 end,
414 function (t, p, n)
415 return awful.completion.generic(t, p, n, {'no', 'NO', 'yes', 'YES'})
416 end)
417end
418
419customization.func.system_power_off = function ()
420 local scr = awful.screen.focused()
421 awful.prompt.run({prompt = "Power Off (type 'yes' to confirm)? "},
422 customization.widgets.promptbox[scr].widget,
423 function (t)
424 if string.lower(t) == 'yes' then
425 awesome.emit_signal("exit", nil)
426 awful.util.spawn("systemctl poweroff")
427 end
428 end,
429 function (t, p, n)
430 return awful.completion.generic(t, p, n, {'no', 'NO', 'yes', 'YES'})
431 end)
432end
433
434customization.func.app_finder = function ()
435 awful.util.spawn("xfce4-appfinder")
436end
437
438-- {{ client actions
439
440customization.func.client_focus_next = function ()
441 awful.client.focus.byidx(1)
442 if client.focus then client.focus:raise() end
443end
444
445customization.func.client_focus_prev = function ()
446 awful.client.focus.byidx(-1)
447 if client.focus then client.focus:raise() end
448end
449
450customization.func.client_focus_urgent = awful.client.urgent.jumpto
451
452customization.func.client_swap_next = function () awful.client.swap.byidx( 1) end
453
454customization.func.client_swap_prev = function () awful.client.swap.byidx( -1) end
455
456customization.func.client_move_next = function () util.client.rel_send(1) end
457
458customization.func.client_move_prev = function () util.client.rel_send(-1) end
459
460customization.func.client_move_to_tag = function ()
461 local keywords = {}
462 local scr = awful.screen.focused()
463 for _, t in ipairs(awful.tag.gettags(scr)) do -- only the current screen
464 table.insert(keywords, t.name)
465 end
466 awful.prompt.run({prompt = "Move client to tag: "},
467 customization.widgets.promptbox[scr].widget,
468 function (t)
469 local tag = util.tag.name2tag(t)
470 if tag then
471 awful.client.movetotag(tag)
472 end
473 end,
474 function (t, p, n)
475 return awful.completion.generic(t, p, n, keywords)
476 end,
477 nil)
478end
479
480customization.func.client_toggle_tag = function (c)
481 local keywords = {}
482 local scr = awful.screen.focused()
483 for _, t in ipairs(awful.tag.gettags(scr)) do -- only the current screen
484 table.insert(keywords, t.name)
485 end
486 local c = c or client.focus
487 awful.prompt.run({prompt = "Toggle tag for " .. c.name .. ": "},
488 customization.widgets.promptbox[scr].widget,
489 function (t)
490 local tag = util.tag.name2tag(t)
491 if tag then
492 awful.client.toggletag(tag)
493 end
494 end,
495 function (t, p, n)
496 return awful.completion.generic(t, p, n, keywords)
497 end,
498 nil)
499end
500
501customization.func.client_toggle_titlebar = function ()
502 awful.titlebar.toggle(client.focus)
503end
504
505customization.func.client_raise = function (c)
506 c:raise()
507end
508
509customization.func.client_fullscreen = function (c)
510 c.fullscreen = not c.fullscreen
511end
512
513customization.func.client_maximize_horizontal = function (c)
514 c.maximized_horizontal = not c.maximized_horizontal
515end
516
517customization.func.client_maximize_vertical = function (c)
518 c.maximized_vertical = not c.maximized_vertical
519end
520
521customization.func.client_maximize = function (c)
522 c.maximized = not c.maximized
523end
524
525customization.func.client_minimize = function (c)
526 c.minimized = not c.minimized
527end
528
529do
530
531 -- closures for client_status
532 -- client_status[client] = {sidelined = <boolean>, geometry= <client geometry>}
533 local client_status = {}
534
535 customization.func.client_sideline_left = function (c)
536 local scr = screen[awful.screen.focused()]
537 local workarea = scr.workarea
538 if client_status[c] == nil then
539 client_status[c] = {sidelined=false, geometry=nil}
540 end
541 if client_status[c].sidelined then
542 if client_status[c].geometry then
543 c:geometry(client_status[c].geometry)
544 end
545 else
546 client_status[c].geometry = c:geometry()
547 workarea.width = math.floor(workarea.width/2)
548 c:geometry(workarea)
549 end
550 client_status[c].sidelined = not client_status[c].sidelined
551 end
552
553 customization.func.client_sideline_right = function (c)
554 local scr = screen[awful.screen.focused()]
555 local workarea = scr.workarea
556 if client_status[c] == nil then
557 client_status[c] = {sidelined=false, geometry=nil}
558 end
559 if client_status[c].sidelined then
560 if client_status[c].geometry then
561 c:geometry(client_status[c].geometry)
562 end
563 else
564 client_status[c].geometry = c:geometry()
565 workarea.x = workarea.x + math.floor(workarea.width/2)
566 workarea.width = math.floor(workarea.width/2)
567 c:geometry(workarea)
568 end
569 client_status[c].sidelined = not client_status[c].sidelined
570 end
571
572 customization.func.client_sideline_top = function (c)
573 local scr = screen[awful.screen.focused()]
574 local workarea = scr.workarea
575 if client_status[c] == nil then
576 client_status[c] = {sidelined=false, geometry=nil}
577 end
578 if client_status[c].sidelined then
579 if client_status[c].geometry then
580 c:geometry(client_status[c].geometry)
581 end
582 else
583 client_status[c].geometry = c:geometry()
584 workarea.height = math.floor(workarea.height/2)
585 c:geometry(workarea)
586 end
587 client_status[c].sidelined = not client_status[c].sidelined
588 end
589
590 customization.func.client_sideline_bottom = function (c)
591 local scr = screen[awful.screen.focused()]
592 local workarea = scr.workarea
593 if client_status[c] == nil then
594 client_status[c] = {sidelined=false, geometry=nil}
595 end
596 if client_status[c].sidelined then
597 if client_status[c].geometry then
598 c:geometry(client_status[c].geometry)
599 end
600 else
601 client_status[c].geometry = c:geometry()
602 workarea.y = workarea.y + math.floor(workarea.height/2)
603 workarea.height = math.floor(workarea.height/2)
604 c:geometry(workarea)
605 end
606 client_status[c].sidelined = not client_status[c].sidelined
607 end
608
609 customization.func.client_sideline_extend_left = function (c, by)
610 local cg = c:geometry()
611 if by then
612 cg.x = cg.x - by
613 cg.width = cg.width + by
614 else -- use heuristics
615 local delta = math.floor(cg.x/7)
616 if delta ~= 0 then
617 cg.x = cg.x - delta
618 cg.width = cg.width + delta
619 end
620 end
621 c:geometry(cg)
622 end
623
624 customization.func.client_sideline_extend_right = function (c, by)
625 local cg = c:geometry()
626 if by then
627 cg.width = cg.width + by
628 else
629 local workarea = screen[awful.screen.focused()].workarea
630 local rmargin = math.max( (workarea.x + workarea.width - cg.x - cg.width), 0)
631 local delta = math.floor(rmargin/7)
632 if delta ~= 0 then
633 cg.width = cg.width + delta
634 end
635 end
636 c:geometry(cg)
637 end
638
639 customization.func.client_sideline_extend_top = function (c, by)
640 local cg = c:geometry()
641 if by then
642 cg.y = cg.y - by
643 cg.height = cg.height + by
644 else
645 local delta = math.floor(cg.y/7)
646 if delta ~= 0 then
647 cg.y = cg.y - delta
648 cg.height = cg.height + delta
649 end
650 end
651 c:geometry(cg)
652 end
653
654 customization.func.client_sideline_extend_bottom = function (c, by)
655 local cg = c:geometry()
656 if by then
657 cg.height = cg.height + by
658 else
659 local workarea = screen[awful.screen.focused()].workarea
660 local bmargin = math.max( (workarea.y + workarea.height - cg.y - cg.height), 0)
661 local delta = math.floor(bmargin/7)
662 if delta ~= 0 then
663 cg.height = cg.height + delta
664 end
665 end
666 c:geometry(cg)
667 end
668
669 customization.func.client_sideline_shrink_left = function (c, by)
670 local cg = c:geometry()
671 local min = customization.default.property.minimal_client_width
672 if by then
673 cg.width = math.max(cg.width - by, min)
674 else
675 local delta = math.floor(cg.width/11)
676 if delta ~= 0 and cg.width > min then
677 cg.width = cg.width - delta
678 end
679 end
680 c:geometry(cg)
681 end
682
683 customization.func.client_sideline_shrink_right = function (c, by)
684 local cg = c:geometry()
685 local min = customization.default.property.minimal_client_width
686 if by then
687 local t = cg.x + cg.width
688 cg.width = math.max(cg.width - by, min)
689 cg.x = t - cg.width
690 else
691 local delta = math.floor(cg.width/11)
692 if delta ~= 0 and cg.width > min then
693 cg.x = cg.x + delta
694 cg.width = cg.width - delta
695 end
696 end
697 c:geometry(cg)
698 end
699
700 customization.func.client_sideline_shrink_top = function (c, by)
701 local cg = c:geometry()
702 local min = customization.default.property.minimal_client_height
703 if by then
704 cg.height = math.max(cg.height - by, min)
705 else
706 local delta = math.floor(cg.height/11)
707 if delta ~= 0 and cg.height > min then
708 cg.height = cg.height - delta
709 end
710 end
711 c:geometry(cg)
712 end
713
714 customization.func.client_sideline_shrink_bottom = function (c, by)
715 local cg = c:geometry()
716 local min = customization.default.property.minimal_client_height
717 if by then
718 local t = cg.y + cg.width
719 cg.height = math.max(cg.height - by, min)
720 cg.y = t - cg.height
721 else
722 local delta = math.floor(cg.height/11)
723 if delta ~= 0 and cg.height > min then
724 cg.y = cg.y + delta
725 cg.height = cg.height - delta
726 end
727 end
728 c:geometry(cg)
729 end
730
731end
732
733customization.func.client_opaque_less = function (c)
734 local opacity = c.opacity - 0.1
735 if opacity and opacity >= customization.default.property.min_opacity then
736 c.opacity = opacity
737 end
738end
739
740customization.func.client_opaque_more = function (c)
741 local opacity = c.opacity + 0.1
742 if opacity and opacity <= customization.default.property.max_opacity then
743 c.opacity = opacity
744 end
745end
746
747customization.func.client_opaque_off = function (c)
748 awful.util.spawn_with_shell("pkill " .. customization.default.compmgr)
749end
750
751customization.func.client_opaque_on = function (c)
752 awful.util.spawn_with_shell(customization.default.compmgr.. " " .. customization.default.compmgr_args)
753end
754
755customization.func.client_swap_with_master = function (c)
756 c:swap(awful.client.getmaster())
757end
758
759customization.func.client_toggle_top = function (c)
760 c.ontop = not c.ontop
761end
762
763customization.func.client_toggle_sticky = function (c)
764 c.sticky = not c.sticky
765end
766
767customization.func.client_kill = function (c)
768 c:kill()
769end
770
771do
772 local instance = nil
773 customization.func.client_action_menu = function (c)
774 local clear_instance = function ()
775 if instance then
776 instance:hide()
777 instance = nil
778 end
779 end
780 if instance and instance.wibox.visible then
781 clear_instance()
782 return
783 end
784 c = c or client.focus
785 instance = awful.menu({
786 theme = {
787 width = 200,
788 },
789 items = {
790 {
791 "&cancel", function ()
792 clear_instance()
793 end
794 },
795 {
796 "=== task action menu ===", function ()
797 clear_instance()
798 end
799 },
800 {
801 "--- status ---", function ()
802 clear_instance()
803 end
804 },
805 {
806 "&raise", function ()
807 clear_instance()
808 customization.func.client_raise(c)
809 end
810 },
811 {
812 "&top", function ()
813 clear_instance()
814 customization.func.client_toggle_top(c)
815 end
816 },
817 {
818 "&sticky", function ()
819 clear_instance()
820 customization.func.client_toggle_sticky(c)
821 end
822 },
823 {
824 "&kill", function ()
825 clear_instance()
826 customization.func.client_kill(c)
827 end
828 },
829 {
830 "toggle title&bar", function ()
831 clear_instance()
832 customization.func.client_toggle_titlebar(c)
833 end
834 },
835 {
836 "--- focus ---", function ()
837 clear_instance()
838 end
839 },
840 {
841 "&next client", function ()
842 clear_instance()
843 customization.func.client_focus_next(c)
844 end
845 },
846 {
847 "&prev client", function ()
848 clear_instance()
849 customization.func.client_focus_prev(c)
850 end
851 },
852 {
853 "&urgent", function ()
854 clear_instance()
855 customization.func.client_focus_urgent(c)
856 end
857 },
858 {
859 "--- tag ---", function ()
860 clear_instance()
861 end
862 },
863 {
864 "move to next tag", function ()
865 clear_instance()
866 customization.func.client_move_next(c)
867 end
868 },
869 {
870 "move to previous tag", function ()
871 clear_instance()
872 customization.func.client_move_prev(c)
873 end
874 },
875 {
876 "move to ta&g", function ()
877 clear_instance()
878 customization.func.client_move_to_tag(c)
879 end
880 },
881 {
882 "togg&le tag", function ()
883 clear_instance()
884 customization.func.client_toggle_tag(c)
885 end
886 },
887 {
888 "--- geometry ---", function ()
889 clear_instance()
890 end
891 },
892 {
893 "&fullscreen", function ()
894 clear_instance()
895 customization.func.client_fullscreen(c)
896 end
897 },
898 {
899 "m&aximize", function ()
900 clear_instance()
901 customization.func.client_maximize(c)
902 end
903 },
904 {
905 "maximize h&orizontal", function ()
906 clear_instance()
907 customization.func.client_maximize_horizontal(c)
908 end
909 },
910 {
911 "maximize &vertical", function ()
912 clear_instance()
913 customization.func.client_maximize_vertical(c)
914 end
915 },
916 {
917 "m&inimize", function ()
918 clear_instance()
919 customization.func.client_minimize(c)
920 end
921 },
922 {
923 "move to left", function ()
924 clear_instance()
925 customization.func.client_sideline_left(c)
926 end
927 },
928 {
929 "move to right", function ()
930 clear_instance()
931 customization.func.client_sideline_right(c)
932 end
933 },
934 {
935 "move to top", function ()
936 clear_instance()
937 customization.func.client_sideline_top(c)
938 end
939 },
940 {
941 "move to bottom", function ()
942 clear_instance()
943 customization.func.client_sideline_bottom(c)
944 end
945 },
946 {
947 "extend left", function ()
948 clear_instance()
949 customization.func.client_sideline_extend_left(c)
950 end
951 },
952 {
953 "extend right", function ()
954 clear_instance()
955 customization.func.client_sideline_extend_right(c)
956 end
957 },
958 {
959 "extend top", function ()
960 clear_instance()
961 customization.func.client_sideline_extend_top(c)
962 end
963 },
964 {
965 "extend bottom", function ()
966 clear_instance()
967 customization.func.client_sideline_extend_bottom(c)
968 end
969 },
970 {
971 "shrink left", function ()
972 clear_instance()
973 customization.func.client_sideline_shrink_left(c)
974 end
975 },
976 {
977 "shrink right", function ()
978 clear_instance()
979 customization.func.client_sideline_shrink_right(c)
980 end
981 },
982 {
983 "shrink top", function ()
984 clear_instance()
985 customization.func.client_sideline_shrink_top(c)
986 end
987 },
988 {
989 "shrink bottom", function ()
990 clear_instance()
991 customization.func.client_sideline_shrink_bottom(c)
992 end
993 },
994 {
995 "--- opacity ---", function ()
996 clear_instance()
997 end
998 },
999 {
1000 "&less opaque", function ()
1001 clear_instance()
1002 customization.func.client_opaque_less(c)
1003 end
1004 },
1005 {
1006 "&more opaque", function ()
1007 clear_instance()
1008 customization.func.client_opaque_more(c)
1009 end
1010 },
1011 {
1012 "opacity off", function ()
1013 clear_instance()
1014 customization.func.client_opaque_off(c)
1015 end
1016 },
1017 {
1018 "opacity on", function ()
1019 clear_instance()
1020 customization.func.client_opaque_on(c)
1021 end
1022 },
1023 {
1024 "--- ordering ---", function ()
1025 clear_instance()
1026 end
1027 },
1028 {
1029 "swap with master", function ()
1030 clear_instance()
1031 customization.func.client_swap_with_master(c)
1032 end
1033 },
1034 {
1035 "swap with next", function ()
1036 clear_instance()
1037 customization.func.client_swap_next(c)
1038 end
1039 },
1040 {
1041 "swap with prev", function ()
1042 clear_instance()
1043 customization.func.client_swap_prev(c)
1044 end
1045 },
1046 }
1047 })
1048 instance:toggle({keygrabber=true})
1049 end
1050end
1051
1052-- }}
1053
1054-- {{ tag actions
1055
1056customization.func.tag_add_after = function ()
1057 local focused = awful.screen.focused()
1058 local scr = focused
1059 local sel_idx = focused.selected_tag and focused.selected_tag.index or 0
1060 local t = util.tag.add(nil,
1061 {
1062 screen = scr,
1063 index = sel_idx and sel_idx+1 or 1,
1064 layout = customization.default.property.layout,
1065 mwfact = customization.default.property.mwfact,
1066 nmaster = customization.default.property.nmaster,
1067 ncol = customization.default.property.ncol,
1068 })
1069end
1070
1071customization.func.tag_add_before = function ()
1072 local focused = awful.screen.focused()
1073 local scr = focused.index
1074 local sel_idx = focused.selected_tag and focused.selected_tag.index or 1
1075 local t = util.tag.add(nil,
1076 {
1077 screen = scr,
1078 index = sel_idx and sel_idx or 1,
1079 layout = customization.default.property.layout,
1080 mwfact = customization.default.property.mwfact,
1081 nmaster = customization.default.property.nmaster,
1082 ncol = customization.default.property.ncol,
1083 })
1084end
1085
1086customization.func.tag_delete = function ()
1087 local sel = awful.screen.focused().selected_tag
1088 if sel then sel:delete() end
1089end
1090
1091customization.func.tag_rename = function ()
1092 local focused = awful.screen.focused()
1093 local sel = focused.selected_tag
1094 util.tag.rename(sel)
1095end
1096
1097customization.func.tag_view_prev = awful.tag.viewprev
1098
1099customization.func.tag_view_next = awful.tag.viewnext
1100
1101customization.func.tag_last = awful.tag.history.restore
1102
1103customization.func.tag_goto = function ()
1104 local keywords = {}
1105 local scr = awful.screen.focused()
1106 for _, t in ipairs(awful.tag.gettags(scr)) do -- only the current screen
1107 table.insert(keywords, t.name)
1108 end
1109 awful.prompt.run({prompt = "Goto tag: "},
1110 customization.widgets.promptbox[scr].widget,
1111 function (t)
1112 local tag = util.tag.name2tag(t)
1113 if tag then
1114 awful.tag.viewonly(tag)
1115 end
1116 end,
1117 function (t, p, n)
1118 return awful.completion.generic(t, p, n, keywords)
1119 end)
1120end
1121
1122customization.func.client_move_screen_by_direction = function (dir)
1123 -- dir: enum{ "up", "down", "left", "right" }
1124 local cur = capi.client.focus
1125 if cur then -- if has a focused client
1126 local scr = cur.screen
1127 if scr then
1128 local next_scr = scr:get_next_in_direction(dir)
1129 if next_scr then
1130 cur.screen = next_scr
1131 end
1132 end
1133 end
1134end
1135
1136customization.func.client_move_screen_relatively = function (index_offset)
1137 -- index_offset: Index offset
1138 local cur = capi.client.focus
1139 if cur then -- if has a focused client
1140 local sc = capi.screen.count()
1141 local s = cur.screen
1142 if s and sc > 1 then -- current client is on a screen, and there is >1 screens
1143 index_offset = math.fmod(index_offset, sc)
1144 if index_offset < 0 then
1145 index_offset = index_offset + sc
1146 end
1147 -- nsi: New screen index (screen index from 1 to sc)
1148 local nsi = math.fmod(s.index - 1 + index_offset, sc) + 1
1149 -- ns: New screen
1150 local ns = capi.screen[nsi]
1151 if ns then
1152 cur.screen = ns
1153 end
1154 end
1155 end
1156end
1157
1158customization.func.tag_move_forward = function ()
1159 util.tag.rel_move(awful.tag.selected(), 1)
1160end
1161
1162customization.func.tag_move_backward = function ()
1163 util.tag.rel_move(awful.tag.selected(), -1)
1164end
1165
1166customization.func.tag_move_screen = function (scrdelta)
1167 local seltag = awful.tag.selected()
1168 local scrcount = capi.screen.count()
1169 if seltag then
1170 local s = awful.tag.getscreen(seltag) + scrdelta
1171 if s > scrcount then s = 1 elseif s < 1 then s = scrcount end
1172 awful.tag.setscreen(seltag, s)
1173 awful.tag.viewonly(seltag)
1174 awful.screen.focus(s)
1175 end
1176end
1177
1178customization.func.tag_move_screen_prev = function ()
1179 customization.func.tag_move_screen(-1)
1180end
1181
1182customization.func.tag_move_screen_next = function ()
1183 customization.func.tag_move_screen(1)
1184end
1185
1186do
1187 local instance = nil
1188 customization.func.tag_action_menu = function (t)
1189 local clear_instance = function ()
1190 if instance then
1191 instance:hide()
1192 instance = nil
1193 end
1194 end
1195 if instance and instance.wibox.visible then
1196 clear_instance()
1197 return
1198 end
1199 t = t or awful.tag.selected()
1200 if t then
1201 instance = awful.menu({
1202 theme = {
1203 width = 200,
1204 },
1205 items = {
1206 {
1207 "&cancel", function ()
1208 clear_instance()
1209 end
1210 },
1211 {
1212 "=== tag action menu ===", function ()
1213 clear_instance()
1214 end
1215 },
1216 {
1217 "--- dynamic tagging ---", function ()
1218 clear_instance()
1219 end
1220 },
1221 {
1222 "add tag &after current one", function ()
1223 clear_instance()
1224 customization.func.tag_add_after(t)
1225 end
1226 },
1227 {
1228 "add tag &before current one", function ()
1229 clear_instance()
1230 customization.func.tag_add_before(t)
1231 end
1232 },
1233 {
1234 "&delete current tag if empty", function ()
1235 clear_instance()
1236 customization.func.tag_delete(t)
1237 end
1238 },
1239 {
1240 "&rename current tag", function ()
1241 clear_instance()
1242 customization.func.tag_rename(t)
1243 end
1244 },
1245 {
1246 "--- focus ---", function ()
1247 clear_instance()
1248 end
1249 },
1250 {
1251 "&goto tag", function ()
1252 clear_instance()
1253 customization.func.tag_goto(t)
1254 end
1255 },
1256 {
1257 "view &previous tag", function ()
1258 clear_instance()
1259 customization.func.tag_view_prev(t)
1260 end
1261 },
1262 {
1263 "view &next tag", function ()
1264 clear_instance()
1265 customization.func.tag_view_next(t)
1266 end
1267 },
1268 {
1269 "view &last tag", function ()
1270 clear_instance()
1271 customization.func.tag_last(t)
1272 end
1273 },
1274 {
1275 "--- ordering ---", function ()
1276 clear_instance()
1277 end
1278 },
1279 {
1280 "move tag &forward", function ()
1281 clear_instance()
1282 customization.func.tag_move_forward()
1283 end
1284 },
1285 {
1286 "move tag &backward", function ()
1287 clear_instance()
1288 customization.func.tag_move_backward()
1289 end
1290 },
1291 {
1292 "--- screen ---", function ()
1293 clear_instance()
1294 end
1295 },
1296 {
1297 "move tag to pre&vious window", function ()
1298 clear_instance()
1299 customization.func.tag_move_screen_prev()
1300 end
1301 },
1302 {
1303 "move tag to ne&xt window", function ()
1304 clear_instance()
1305 customization.func.tag_move_screen_next()
1306 end
1307 },
1308 }
1309 })
1310 instance:toggle({keygrabber=true})
1311 end
1312 end
1313end
1314
1315-- }}
1316
1317-- {{ clients on tags
1318
1319do
1320 local instance = nil
1321 customization.func.clients_on_tag = function ()
1322 local clear_instance = function ()
1323 if instance then
1324 instance:hide()
1325 instance = nil
1326 end
1327 end
1328 if instance and instance.wibox.visible then
1329 clear_instance()
1330 return
1331 end
1332 local clients = {
1333 items = {},
1334 theme = { width = 400 },
1335 }
1336 local next = next
1337 local t = awful.tag.selected()
1338 if t then
1339 for _, c in pairs(t:clients()) do
1340 if c.focusable and c.pid ~= 0 then
1341 table.insert(clients.items, {
1342 c.name .. " ~" .. tostring(c.pid) or "",
1343 function ()
1344 clear_instance()
1345 client.focus = c
1346 c:raise()
1347 end,
1348 c.icon
1349 })
1350 end
1351 end
1352 if next(clients.items) ~= nil then
1353 instance = awful.menu(clients)
1354 instance:toggle({keygrabber=true})
1355 end
1356 end
1357 end
1358end
1359
1360customization.func.clients_on_tag_prompt = function ()
1361 local clients = {}
1362 local next = next
1363 local t = awful.tag.selected()
1364 if t then
1365 local keywords = {}
1366 local scr = awful.screen.focused()
1367 for _, c in pairs(t:clients()) do
1368 if c.focusable and c.pid ~= 0 then
1369 local k = c.name .. " ~" .. tostring(c.pid) or ""
1370 if k ~= "" then
1371 clients[k] = c
1372 table.insert(keywords, k)
1373 end
1374 end
1375 end
1376 if next(clients) ~= nil then
1377 awful.prompt.run({prompt = "Focus on client on current tag: "},
1378 customization.widgets.promptbox[scr].widget,
1379 function (t)
1380 local c = clients[t]
1381 if c then
1382 client.focus = c
1383 c:raise()
1384 end
1385 end,
1386 function (t, p, n)
1387 return awful.completion.generic(t, p, n, keywords)
1388 end)
1389 end
1390 end
1391end
1392
1393do
1394 local instance = nil
1395 customization.func.all_clients = function ()
1396 local clear_instance = function ()
1397 if instance then
1398 instance:hide()
1399 instance = nil
1400 end
1401 end
1402 if instance and instance.wibox.visible then
1403 clear_instance()
1404 return
1405 end
1406 local clients = {
1407 items = {},
1408 theme = { width = 400},
1409 }
1410 local next = next
1411 for _, c in pairs(client.get()) do
1412 if c.focusable and c.pid ~= 0 then
1413 table.insert(clients.items, {
1414 c.name .. " ~" .. tostring(c.pid) or "",
1415 function ()
1416 local t = c:tags()
1417 if t then
1418 awful.tag.viewonly(t[1])
1419 end
1420 clear_instance()
1421 client.focus = c
1422 c:raise()
1423 end,
1424 c.icon
1425 })
1426 end
1427 end
1428 if next(clients.items) ~= nil then
1429 instance = awful.menu(clients)
1430 instance:toggle({keygrabber=true})
1431 end
1432 end
1433end
1434
1435customization.func.all_clients_prompt = function ()
1436 local clients = {}
1437 local next = next
1438 local keywords = {}
1439 local scr = awful.screen.focused()
1440 for _, c in pairs(client.get()) do
1441 if c.focusable and c.pid ~= 0 then
1442 local k = c.name .. " ~" .. tostring(c.pid) or ""
1443 if k ~= "" then
1444 clients[k] = c
1445 table.insert(keywords, k)
1446 end
1447 end
1448 end
1449 if next(clients) ~= nil then
1450 awful.prompt.run({prompt = "Focus on client from global list: "},
1451 customization.widgets.promptbox[scr].widget,
1452 function (t)
1453 local c = clients[t]
1454 if c then
1455 local t = c:tags()
1456 if t then
1457 awful.tag.viewonly(t[1])
1458 end
1459 client.focus = c
1460 c:raise()
1461 end
1462 end,
1463 function (t, p, n)
1464 return awful.completion.generic(t, p, n, keywords)
1465 end)
1466 end
1467end
1468
1469do
1470 local instance = nil
1471 customization.func.systeminfo = function ()
1472 if instance then
1473 naughty.destroy(instance)
1474 instance = nil
1475 return
1476 end
1477 local info = "Version: " .. awesome.version
1478 info = info .. "\n" .. "Release: " .. awesome.release
1479 info = info .. "\n" .. "Config: " .. awesome.conffile
1480 info = info .. "\n" .. "Config Version: " .. customization.config.version
1481 info = info .. "\n" .. "Config Help: " .. customization.config.help_url
1482 if awesome.composite_manager_running then
1483 info = info .. "\n" .. "<span fgcolor='red'>a composite manager is running</span>"
1484 end
1485 local uname = util.pread("uname -a")
1486 if string.gsub(uname, "%s", "") ~= "" then
1487 info = info .. "\n" .. "OS: " .. string.gsub(uname, "%s+$", "")
1488 end
1489 -- remove color code from screenfetch output
1490 local archey = util.pread("screenfetch -N")
1491 if string.gsub(archey, "%s", "") ~= "" then
1492 info = info .. "\n\n<span face='monospace'>" .. archey .. "</span>"
1493 end
1494 info = string.gsub(info, "(%u[%a ]*:)%f[ ]", "<span color='red'>%1</span>")
1495 local tmp = awesome.composite_manager_running
1496 awesome.composite_manager_running = false
1497 instance = naughty.notify({
1498 preset = naughty.config.presets.normal,
1499 title="awesome info",
1500 text=info,
1501 timeout = 10,
1502 screen = awful.screen.focused(),
1503 })
1504 awesome.composite_manager_running = tmp
1505 end
1506end
1507
1508do
1509 local instance = nil
1510 customization.func.help = function ()
1511 if instance then
1512 naughty.destroy(instance)
1513 instance = nil
1514 return
1515 end
1516 local text = ""
1517 text = text .. "You are running awesome <span fgcolor='red'>" .. awesome.version .. "</span> (<span fgcolor='red'>" .. awesome.release .. "</span>)"
1518 text = text .. "\n" .. "with config version <span fgcolor='red'>" .. customization.config.version .. "</span>"
1519 text = text .. "\n\n" .. "help can be found at the URL: <u>" .. customization.config.help_url .. "</u>"
1520 text = text .. "\n\n\n\n" .. "opening in <b>" .. tools.browser.primary .. "</b>..."
1521 instance = naughty.notify({
1522 preset = naughty.config.presets.normal,
1523 title="help about configuration",
1524 text=text,
1525 timeout = 20,
1526 screen = awful.screen.focused(),
1527 })
1528 awful.util.spawn_with_shell(tools.browser.primary .. " '" .. customization.config.help_url .. "'")
1529 end
1530end
1531
1532-- }}
1533
1534-- }}}
1535
1536-- {{{ Menu
1537
1538-- Create a launcher widget and a main menu
1539mysystemmenu = {
1540 --{ "manual", tools.terminal .. " -e man awesome" },
1541 { "&lock", customization.func.system_lock },
1542 { "&suspend", customization.func.system_suspend },
1543 { "hi&bernate", customization.func.system_hibernate },
1544 { "hybri&d sleep", customization.func.system_hybrid_sleep },
1545 { "&reboot", customization.func.system_reboot },
1546 { "&power off", customization.func.system_power_off }
1547}
1548
1549-- Create a launcher widget and a main menu
1550myawesomemenu = {
1551 --{ "manual", tools.terminal .. " -e man awesome" },
1552 { "hotkeys", function() return false, hotkeys_popup.show_help end},
1553 { "&edit config", tools.editor.primary .. " " .. awful.util.getdir("config") .. "/rc.lua" },
1554 { "&restart", awesome.restart },
1555 { "forcibly restart", customization.orig.restart },
1556 { "&quit", awesome.quit },
1557 { "forcibly quit", function () customization.orig.quit() end },
1558}
1559
1560mymainmenu = awful.menu({
1561 theme = { width=150, },
1562 items = {
1563 { "&system", mysystemmenu },
1564 { "app &finder", customization.func.app_finder },
1565 { "&apps", myapp },
1566 { "&terminal", tools.terminal },
1567 { "a&wesome", myawesomemenu, beautiful.awesome_icon },
1568 { "&client action", function ()
1569 customization.func.client_action_menu()
1570 mymainmenu:hide()
1571 end, beautiful.awesome_icon },
1572 { "&tag action", function ()
1573 customization.func.tag_action_menu()
1574 mymainmenu:hide()
1575 end, beautiful.awesome_icon },
1576 { "clients &on current tag", function ()
1577 customization.func.clients_on_tag()
1578 mymainmenu:hide()
1579 end, beautiful.awesome_icon },
1580 { "clients on a&ll tags", function ()
1581 customization.func.all_clients()
1582 mymainmenu:hide()
1583 end, beautiful.awesome_icon },
1584 }
1585})
1586
1587-- Keyboard map indicator and switcher
1588customization.widgets.keyboardlayout = awful.widget.keyboardlayout()
1589
1590-- Create a textclock widget
1591customization.widgets.textclock = wibox.widget.textclock()
1592
1593-- Launcher
1594customization.widgets.launcher = awful.widget.launcher({
1595 image = beautiful.awesome_icon,
1596 menu = mymainmenu,
1597})
1598
1599-- }}}
1600
1601-- {{{ Wibox
1602--customization.widgets.textclock = wibox.widget.textbox()
1603--bashets.register("date.sh", {widget=customization.widgets.textclock, update_time=1, format="$1 <span fgcolor='red'>$2</span> <small>$3$4</small> <b>$5<small>$6</small></b>"}) -- http://awesome.naquadah.org/wiki/Bashets
1604
1605-- vicious widgets: http://awesome.naquadah.org/wiki/Vicious
1606
1607customization.widgets.cpuusage = awful.widget.graph()
1608customization.widgets.cpuusage:set_width(50)
1609customization.widgets.cpuusage:set_background_color("#494B4F")
1610customization.widgets.cpuusage:set_color({
1611 type = "linear", from = { 0, 0 }, to = { 10,0 },
1612 stops = { {0, "#FF5656"}, {0.5, "#88A175"}, {1, "#AECF96" }}})
1613vicious.register(customization.widgets.cpuusage, vicious.widgets.cpu, "$1", 5)
1614do
1615 local prog=tools.system.taskmanager
1616 local started=false
1617 customization.widgets.cpuusage:buttons(awful.util.table.join(
1618 awful.button({ }, 1, function ()
1619 if started then
1620 awful.util.spawn("pkill -f '" .. prog .. "'")
1621 else
1622 awful.util.spawn(prog)
1623 end
1624 started=not started
1625 end)
1626 ))
1627end
1628
1629customization.widgets.memusage = wibox.widget.textbox()
1630vicious.register(customization.widgets.memusage, vicious.widgets.mem,
1631 "<span fgcolor='yellow'>$1% ($2MB/$3MB)</span>", 3)
1632do
1633 local prog=tools.system.taskmanager
1634 local started=false
1635 customization.widgets.memusage:buttons(awful.util.table.join(
1636 awful.button({ }, 1, function ()
1637 if started then
1638 awful.util.spawn("pkill -f '" .. prog .. "'")
1639 else
1640 awful.util.spawn(prog)
1641 end
1642 started=not started
1643 end)
1644 ))
1645end
1646
1647customization.widgets.bat = awful.widget.progressbar()
1648customization.widgets.bat.last_perc = nil
1649customization.widgets.bat.warning_threshold = 10
1650customization.widgets.bat.instance = "BAT0"
1651customization.widgets.bat:set_width(8)
1652customization.widgets.bat:set_height(10)
1653customization.widgets.bat:set_vertical(true)
1654customization.widgets.bat:set_background_color("#494B4F")
1655customization.widgets.bat:set_border_color(nil)
1656customization.widgets.bat:set_color({
1657 type = "linear", from = { 0, 0 }, to = { 0, 10 },
1658 stops = {{ 0, "#AECF96" }, { 0.5, "#88A175" }, { 1, "#FF5656" }}
1659})
1660vicious.register(customization.widgets.bat, vicious.widgets.bat,
1661 function (bat, args)
1662 local perc = args[2]
1663 -- "perc>0" checks for "no battery" (e.g., desktop computer).
1664 if customization.option.low_battery_notification_p and perc > 0 and perc <= bat.warning_threshold then
1665 if (not bat.last_perc) or (perc < bat.last_perc) then
1666 -- discharging
1667 naughty.notify({
1668 preset = naughty.config.presets.critical,
1669 title = "Low battery: " .. perc .. "%.",
1670 text = "Please connect an AC adapter.",
1671 timeout = 60
1672 })
1673 elseif perc > bat.last_perc then
1674 -- charging
1675 naughty.notify({
1676 preset = naughty.config.presets.low,
1677 title = "Battery is charging.",
1678 text = "Current: " .. perc .. "%; warning threshold: " .. bat.warning_threshold .. "%.",
1679 timeout = 5
1680 })
1681 end
1682 bat.last_perc = perc
1683 else
1684 bat.last_perc = nil
1685 end
1686 return perc
1687 end, 61, customization.widgets.bat.instance)
1688do
1689 local prog="gnome-control-center power"
1690 local started=false
1691 customization.widgets.bat:buttons(awful.util.table.join(
1692 awful.button({ }, 1, function ()
1693 if started then
1694 awful.util.spawn("pkill -f '" .. prog .. "'")
1695 else
1696 awful.util.spawn(prog)
1697 end
1698 started=not started
1699 end)
1700 ))
1701end
1702
1703
1704customization.widgets.volume = wibox.widget.textbox()
1705vicious.register(customization.widgets.volume, vicious.widgets.volume,
1706 "<span fgcolor='cyan'>$1%$2</span>", 1, "Master")
1707do
1708 local prog="pavucontrol"
1709 local started=false
1710 customization.widgets.volume:buttons(awful.util.table.join(
1711 awful.button({ }, 1, function ()
1712 if started then
1713 awful.util.spawn("pkill -f '" .. prog .. "'")
1714 else
1715 awful.util.spawn(prog)
1716 end
1717 started=not started
1718 end),
1719 awful.button({ }, 2, function ()
1720 awful.util.spawn("amixer sset Mic toggle")
1721 end),
1722 awful.button({ }, 3, function ()
1723 awful.util.spawn("amixer sset Master toggle")
1724 end),
1725 awful.button({ }, 4, function ()
1726 awful.util.spawn("amixer sset Master 1%-")
1727 end),
1728 awful.button({ }, 5, function ()
1729 awful.util.spawn("amixer sset Master 1%+")
1730 end)
1731 ))
1732end
1733
1734customization.widgets.date = wibox.widget.textbox()
1735vicious.register(customization.widgets.date, vicious.widgets.date, "%a %x %r %Z", 1)
1736do
1737 local prog1="gnome-control-center datetime"
1738 local started1=false
1739 local prog2="gnome-control-center region"
1740 local started2=false
1741 customization.widgets.date:buttons(awful.util.table.join(
1742 awful.button({ }, 1, function ()
1743 if started1 then
1744 awful.util.spawn("pkill -f '" .. prog1 .. "'")
1745 else
1746 awful.util.spawn(prog1)
1747 end
1748 started1=not started1
1749 end),
1750 awful.button({ }, 3, function ()
1751 if started2 then
1752 awful.util.spawn("pkill -f '" .. prog2 .. "'")
1753 else
1754 awful.util.spawn(prog2)
1755 end
1756 started2=not started2
1757 end)
1758 ))
1759end
1760
1761-- Create a wibox for each screen and add it
1762
1763customization.widgets.uniarg = {}
1764customization.widgets.wibox = {}
1765customization.widgets.promptbox = {}
1766customization.widgets.layoutbox = {}
1767customization.widgets.taglist = {}
1768customization.widgets.taglist.buttons = awful.util.table.join(
1769awful.button({ }, 1, awful.tag.viewonly),
1770awful.button({ modkey }, 1, awful.client.movetotag),
1771awful.button({ }, 2, awful.tag.viewtoggle),
1772awful.button({ modkey }, 2, awful.client.toggletag),
1773awful.button({ }, 3, function (t)
1774 customization.func.tag_action_menu(t)
1775end),
1776awful.button({ modkey }, 3, awful.tag.delete),
1777awful.button({ }, 4, function(t) awful.tag.viewprev(awful.tag.getscreen(t)) end),
1778awful.button({ }, 5, function(t) awful.tag.viewnext(awful.tag.getscreen(t)) end)
1779)
1780
1781customization.widgets.tasklist = {}
1782customization.widgets.tasklist.buttons = awful.util.table.join(
1783
1784awful.button({ }, 1, function (c)
1785 if c == client.focus then
1786 c.minimized = true
1787 else
1788 -- Without this, the following
1789 -- :isvisible() makes no sense
1790 c.minimized = false
1791 if not c:isvisible() then
1792 awful.tag.viewonly(c:tags()[1])
1793 end
1794 -- This will also un-minimize
1795 -- the client, if needed
1796 client.focus = c
1797 c:raise()
1798 end
1799end),
1800
1801awful.button({ }, 2, function (c)
1802 customization.func.clients_on_tag()
1803end),
1804
1805awful.button({ modkey }, 2, function (c)
1806 customization.func.all_clients()
1807end),
1808
1809awful.button({ }, 3, function (c)
1810 customization.func.client_action_menu(c)
1811end),
1812
1813awful.button({ }, 4, function ()
1814 awful.client.focus.byidx(-1)
1815 if client.focus then client.focus:raise() end
1816end),
1817
1818awful.button({ }, 5, function ()
1819 awful.client.focus.byidx(1)
1820 if client.focus then client.focus:raise() end
1821end))
1822
1823-- start bashets
1824bashets.start()
1825
1826local function set_wallpaper(s)
1827 -- Wallpaper
1828 if beautiful.wallpaper then
1829 local wallpaper = beautiful.wallpaper
1830 -- If wallpaper is a function, call it with the screen
1831 if type(wallpaper) == "function" then
1832 wallpaper = wallpaper(s)
1833 end
1834 gears.wallpaper.maximized(wallpaper, s, true)
1835 end
1836end
1837
1838-- Re-set wallpaper when a screen's geometry changes (e.g. different resolution)
1839screen.connect_signal("property::geometry", set_wallpaper)
1840
1841local prev_scr_count = nil
1842awful.screen.connect_for_each_screen(
1843function(s)
1844 -- Wallpaper
1845 set_wallpaper(s)
1846 -- Set a default tag is there is none.
1847 timer.delayed_call(function ()
1848 local si = s.index
1849 if #s.tags < 1 then
1850 local tag = awful.tag.add("main" .. si,
1851 {
1852 screen = si,
1853 layout = customization.default.property.layout,
1854 mwfact = customization.default.property.mwfact,
1855 nmaster = customization.default.property.nmaster,
1856 ncol = customization.default.property.ncol,
1857 }
1858 )
1859 awful.tag.viewonly(tag)
1860 end
1861 end)
1862 -- Create a promptbox for each screen
1863 customization.widgets.promptbox[s] = awful.widget.prompt()
1864 -- Create an imagebox widget which will contains an icon indicating which layout we're using.
1865 -- We need one layoutbox per screen.
1866 customization.widgets.layoutbox[s] = awful.widget.layoutbox(s)
1867 customization.widgets.layoutbox[s]:buttons(awful.util.table.join(
1868 awful.button({ }, 1, function () awful.layout.inc(layouts, 1) end),
1869 awful.button({ }, 3, function () awful.layout.inc(layouts, -1) end),
1870 awful.button({ }, 4, function () awful.layout.inc(layouts, -1) end),
1871 awful.button({ }, 5, function () awful.layout.inc(layouts, 1) end),
1872 nil
1873 ))
1874 -- Create a taglist widget
1875 customization.widgets.taglist[s] = awful.widget.taglist(s, awful.widget.taglist.filter.all, customization.widgets.taglist.buttons)
1876
1877 -- Create a textbox showing current universal argument
1878 customization.widgets.uniarg[s] = wibox.widget.textbox()
1879 -- Create a tasklist widget
1880 customization.widgets.tasklist[s] = awful.widget.tasklist(
1881 s, awful.widget.tasklist.filter.currenttags, customization.widgets.tasklist.buttons
1882 )
1883
1884 -- Create the wibox
1885 customization.widgets.wibox[s] = awful.wibox({ position = "top", screen = s })
1886
1887 customization.widgets.wibox[s]:setup {
1888 layout = wibox.layout.align.horizontal,
1889 { -- Left widgets
1890 layout = wibox.layout.fixed.horizontal,
1891 customization.widgets.launcher,
1892 customization.widgets.taglist[s],
1893 customization.widgets.uniarg[s],
1894 customization.widgets.promptbox[s],
1895 },
1896 customization.widgets.tasklist[s], -- Middle widget
1897 { -- Right widgets
1898 layout = wibox.layout.fixed.horizontal,
1899 customization.widgets.keyboardlayout,
1900 wibox.widget.systray(),
1901 customization.widgets.cpuusage,
1902 customization.widgets.memusage,
1903 customization.widgets.bat,
1904 customization.widgets.mpdstatus,
1905 customization.widgets.volume,
1906 customization.widgets.date,
1907 customization.widgets.layoutbox[s],
1908 },
1909 }
1910
1911end
1912)
1913
1914util.taglist.set_taglist(customization.widgets.taglist)
1915-- }}}
1916
1917do
1918 -- test whether screen 1 tag file exists
1919 local f = io.open(awesome_tags_fname .. ".0", "r")
1920 if f then
1921 local old_scr_count = tonumber(f:read("*l"))
1922 f:close()
1923 os.remove(awesome_tags_fname .. ".0")
1924
1925 local new_scr_count = screen.count()
1926
1927 local count = {}
1928
1929 local scr_count = math.min(new_scr_count, old_scr_count)
1930
1931 if scr_count>0 then
1932 for s = 1, scr_count do
1933 count[s] = 1
1934 end
1935
1936 for s = 1, old_scr_count do
1937 local count_index = math.min(s, scr_count)
1938 local fname = awesome_tags_fname .. "." .. s
1939 local f = io.open(fname, "r")
1940 if f then
1941 f:close()
1942 for tagname in io.lines(fname) do
1943 local tag = awful.tag.add(tagname,
1944 {
1945 screen = count_index,
1946 layout = customization.default.property.layout,
1947 mwfact = customization.default.property.mwfact,
1948 nmaster = customization.default.property.nmaster,
1949 ncol = customization.default.property.ncol,
1950 }
1951 )
1952 awful.tag.move(count[count_index], tag)
1953 count[count_index] = count[count_index]+1
1954 end
1955 end
1956 os.remove(fname)
1957 end
1958 end
1959
1960 for s = 1, screen.count() do
1961 local tags = awful.tag.gettags(s)
1962 if #tags >= 1 then
1963 local fname = awesome_tags_fname .. "-selected." .. s
1964 f = io.open(fname, "r")
1965 if f then
1966 local tag = awful.tag.gettags(s)[tonumber(f:read("*l"))]
1967 if tag then
1968 awful.tag.viewonly(tag)
1969 end
1970 f:close()
1971 end
1972 os.remove(fname)
1973 else
1974 local tag = awful.tag.add("main" .. s,
1975 {
1976 screen = s,
1977 layout = customization.default.property.layout,
1978 mwfact = customization.default.property.mwfact,
1979 nmaster = customization.default.property.nmaster,
1980 ncol = customization.default.property.ncol,
1981 }
1982 )
1983 awful.tag.viewonly(tag)
1984 end
1985 end
1986
1987 else
1988
1989 for s = 1, screen.count() do
1990 local tags = awful.tag.gettags(s)
1991 if #tags < 1 then
1992 local tag = awful.tag.add("main" .. s,
1993 {
1994 screen = s,
1995 layout = customization.default.property.layout,
1996 mwfact = customization.default.property.mwfact,
1997 nmaster = customization.default.property.nmaster,
1998 ncol = customization.default.property.ncol,
1999 }
2000 )
2001 awful.tag.viewonly(tag)
2002 end
2003 end
2004
2005 end
2006end
2007
2008
2009-- {{{ Mouse bindings
2010root.buttons(awful.util.table.join(
2011awful.button({ }, 1, customization.func.all_clients),
2012awful.button({ }, 2, customization.func.tag_action_menu),
2013awful.button({ }, 3, function () mymainmenu:toggle() end),
2014awful.button({ }, 4, awful.tag.viewprev),
2015awful.button({ }, 5, awful.tag.viewprev)
2016))
2017-- }}}
2018notifylist = {}
2019-- {{{ Key bindings
2020
2021local globalkeys = nil
2022local clientkeys = nil
2023
2024uniarg:init(customization.widgets.uniarg)
2025
2026globalkeys = awful.util.table.join(
2027
2028-- universal arguments
2029
2030awful.key({ modkey }, "u",
2031function ()
2032 uniarg:activate()
2033 awful.prompt.run({prompt = "Universal Argument: ", text='' .. uniarg.arg, selectall=true},
2034 customization.widgets.promptbox[awful.screen.focused()].widget,
2035 function (t)
2036 uniarg.persistent = false
2037 local n = t:match("%d+")
2038 if n then
2039 uniarg:set(n)
2040 uniarg:update_textbox()
2041 if uniarg.arg>1 then
2042 return
2043 end
2044 end
2045 uniarg:deactivate()
2046 end)
2047end),
2048
2049-- persistent universal arguments
2050awful.key({ modkey, "Shift" }, "u",
2051function ()
2052 uniarg:activate()
2053 awful.prompt.run({prompt = "Persistent Universal Argument: ", text='' .. uniarg.arg, selectall=true},
2054 customization.widgets.promptbox[awful.screen.focused()].widget,
2055 function (t)
2056 uniarg.persistent = true
2057 local n = t:match("%d+")
2058 if n then
2059 uniarg:set(n)
2060 end
2061 uniarg:update_textbox()
2062 end)
2063end),
2064
2065-- window management
2066
2067--- restart/quit/info
2068
2069awful.key({ modkey, "Control" }, "r", awesome.restart),
2070
2071awful.key({ modkey, "Control", "Shift" }, "r", customization.orig.restart),
2072
2073awful.key({ modkey, "Shift" }, "q", awesome.quit),
2074
2075awful.key({ modkey, "Shift", "Control" }, "q", customization.orig.quit),
2076
2077awful.key({ modkey }, "\\", customization.func.systeminfo),
2078
2079awful.key({ modkey }, "F1", customization.func.help),
2080
2081awful.key({ modkey, "Shift" }, "F1", hotkeys_popup.show_help),
2082
2083awful.key({ "Ctrl", "Shift" }, "Escape", function ()
2084 awful.util.spawn(tools.system.taskmanager)
2085end),
2086
2087--- Layout
2088
2089uniarg:key_repeat({ modkey, }, "space", function () awful.layout.inc(layouts, 1) end),
2090
2091uniarg:key_repeat({ modkey, "Shift" }, "space", function () awful.layout.inc(layouts, -1) end),
2092
2093--- multiple screens/multi-head/RANDR
2094
2095uniarg:key_repeat({ modkey, "Control" }, "j", function () awful.screen.focus_relative( 1) end),
2096
2097uniarg:key_repeat({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end),
2098
2099uniarg:key_repeat({ modkey, }, "o", function ()
2100 customization.func.client_move_screen_relatively( 1)
2101end),
2102
2103uniarg:key_repeat({ modkey, "Shift" }, "o", function ()
2104 customization.func.client_move_screen_relatively(-1)
2105end),
2106
2107uniarg:key_repeat({ modkey, "Shift", "Control", "Mod1" }, "Right", function ()
2108 customization.func.client_move_screen_by_direction("right")
2109end),
2110
2111uniarg:key_repeat({ modkey, "Shift", "Control", "Mod1" }, "Left", function ()
2112 customization.func.client_move_screen_by_direction("left")
2113end),
2114
2115uniarg:key_repeat({ modkey, "Shift", "Control", "Mod1" }, "Up", function ()
2116 customization.func.client_move_screen_by_direction("up")
2117end),
2118
2119uniarg:key_repeat({ modkey, "Shift", "Control", "Mod1" }, "Down", function ()
2120 customization.func.client_move_screen_by_direction("down")
2121end),
2122
2123uniarg:key_repeat({ modkey, "Control" }, "o", customization.func.tag_move_screen_next),
2124
2125uniarg:key_repeat({ modkey, "Shift", "Control" }, "o", customization.func.tag_move_screen_prev),
2126
2127uniarg:key_repeat({ modkey, "Shift", "Control" }, "\\", xrandr.xrandr),
2128
2129uniarg:key_repeat({ modkey, "Mod1", "Control" }, "\\", foggy.menu),
2130
2131--- misc
2132
2133awful.key({modkey}, "F2", function()
2134 awful.prompt.run(
2135 {prompt = "Run: "},
2136 customization.widgets.promptbox[awful.screen.focused()].widget,
2137 awful.util.spawn, awful.completion.shell,
2138 awful.util.getdir("cache") .. "/history"
2139 )
2140end),
2141
2142awful.key({modkey}, "r", function()
2143 awful.prompt.run(
2144 {prompt = "Run: "},
2145 customization.widgets.promptbox[awful.screen.focused()].widget,
2146 awful.util.spawn, awful.completion.shell,
2147 awful.util.getdir("cache") .. "/history"
2148 )
2149end),
2150
2151awful.key({modkey}, "F3", function()
2152 local config_path = awful.util.getdir("config")
2153 awful.util.spawn_with_shell(config_path .. "/bin/trackpad-toggle.sh")
2154end),
2155
2156awful.key({modkey}, "F4", function()
2157 awful.prompt.run(
2158 {prompt = "Run Lua code: "},
2159 customization.widgets.promptbox[awful.screen.focused()].widget,
2160 awful.util.eval, nil,
2161 awful.util.getdir("cache") .. "/history_eval"
2162 )
2163end),
2164
2165awful.key({ modkey }, "c", function ()
2166 awful.util.spawn(tools.editor.primary .. " " .. awful.util.getdir("config") .. "/rc.lua" )
2167end),
2168
2169awful.key({ modkey, "Shift" }, "/", function() mymainmenu:toggle({keygrabber=true}) end),
2170
2171awful.key({ modkey, }, ";", function()
2172 local c = client.focus
2173 if c then
2174 customization.func.client_action_menu(c)
2175 end
2176end),
2177
2178awful.key({ modkey, "Shift" }, ";", customization.func.tag_action_menu),
2179
2180awful.key({ modkey, }, "'", customization.func.clients_on_tag),
2181
2182awful.key({ modkey, "Ctrl" }, "'", customization.func.clients_on_tag_prompt),
2183
2184awful.key({ modkey, "Shift" }, "'", customization.func.all_clients),
2185
2186awful.key({ modkey, "Shift", "Ctrl" }, "'", customization.func.all_clients_prompt),
2187
2188awful.key({ modkey, }, "x", function() mymainmenu:toggle({keygrabber=true}) end),
2189
2190awful.key({ modkey, }, "X", function() mymainmenu:toggle({keygrabber=true}) end),
2191
2192uniarg:key_repeat({ modkey, }, "Return", function () awful.util.spawn(tools.terminal) end),
2193
2194uniarg:key_repeat({ modkey, "Mod1" }, "Return", function () awful.util.spawn("gksudo " .. tools.terminal) end),
2195
2196-- dynamic tagging
2197
2198awful.key({ modkey, "Ctrl", "Mod1" }, "t", function ()
2199 customization.option.tag_persistent_p = not customization.option.tag_persistent_p
2200 local msg = nil
2201 if customization.option.tag_persistent_p then
2202 msg = "Tags will persist across exit/restart."
2203 else
2204 msg = "Tags will <span fgcolor='red'>NOT</span> persist across exit/restart."
2205 end
2206 naughty.notify({
2207 preset = naughty.config.presets.normal,
2208 title="Tag persistence",
2209 text=msg,
2210 timeout = 1,
2211 screen = awful.screen.focused(),
2212 })
2213end),
2214
2215--- add/delete/rename
2216
2217awful.key({modkey}, "a", customization.func.tag_add_after),
2218
2219awful.key({modkey, "Shift"}, "a", customization.func.tag_add_before),
2220
2221awful.key({modkey, "Shift"}, "d", customization.func.tag_delete),
2222
2223awful.key({modkey, "Shift"}, "r", customization.func.tag_rename),
2224
2225--- view
2226
2227uniarg:key_repeat({modkey,}, "p", customization.func.tag_view_prev),
2228
2229uniarg:key_repeat({modkey,}, "n", customization.func.tag_view_next),
2230
2231awful.key({modkey,}, "z", customization.func.tag_last),
2232
2233awful.key({modkey,}, "g", customization.func.tag_goto),
2234
2235--- move
2236
2237uniarg:key_repeat({modkey, "Control"}, "p", customization.func.tag_move_backward),
2238
2239uniarg:key_repeat({modkey, "Control"}, "n", customization.func.tag_move_forward),
2240
2241-- client management
2242
2243--- change focus
2244
2245uniarg:key_repeat({ modkey, }, "j", customization.func.client_focus_next),
2246
2247uniarg:key_repeat({ modkey, }, "Tab", customization.func.client_focus_next),
2248
2249uniarg:key_repeat({ modkey, }, "k", customization.func.client_focus_prev),
2250
2251uniarg:key_repeat({ modkey, "Shift" }, "Tab", customization.func.client_focus_prev),
2252
2253awful.key({ modkey, }, "y", customization.func.client_focus_urgent),
2254
2255--- swap order/select master
2256
2257uniarg:key_repeat({ modkey, "Shift" }, "j", customization.func.client_swap_next),
2258
2259uniarg:key_repeat({ modkey, "Shift" }, "k", customization.func.client_swap_prev),
2260
2261--- move/copy to tag
2262
2263uniarg:key_repeat({modkey, "Shift"}, "n", customization.func.client_move_next),
2264
2265uniarg:key_repeat({modkey, "Shift"}, "p", customization.func.client_move_prev),
2266
2267awful.key({modkey, "Shift"}, "g", customization.func.client_move_to_tag),
2268
2269awful.key({modkey, "Control", "Shift"}, "g", customization.func.client_toggle_tag),
2270
2271--- change space allocation in tile layout
2272
2273awful.key({ modkey, }, "=", function () awful.tag.setmwfact(0.5) end),
2274
2275awful.key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end),
2276
2277awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end),
2278
2279uniarg:key_repeat({ modkey, "Shift" }, "l", function () awful.tag.incnmaster( 1) end),
2280
2281uniarg:key_repeat({ modkey, "Shift" }, "h", function () awful.tag.incnmaster(-1) end),
2282
2283uniarg:key_repeat({ modkey, "Control" }, "l", function () awful.tag.incncol( 1) end),
2284
2285uniarg:key_repeat({ modkey, "Control" }, "h", function () awful.tag.incncol(-1) end),
2286
2287--- misc
2288
2289awful.key({ modkey, "Shift" }, "`", customization.func.client_toggle_titlebar),
2290
2291-- app bindings
2292
2293--- admin
2294
2295awful.key({ modkey, }, "`", customization.func.system_lock),
2296
2297awful.key({ modkey, }, "Home", customization.func.system_lock),
2298
2299awful.key({ modkey, }, "End", customization.func.system_suspend),
2300
2301awful.key({ modkey, "Mod1" }, "Home", customization.func.system_hibernate),
2302
2303awful.key({ modkey, "Mod1" }, "End", customization.func.system_hybrid_sleep),
2304
2305awful.key({ modkey, }, "Insert", customization.func.system_reboot),
2306
2307awful.key({ modkey, }, "Delete", customization.func.system_power_off),
2308
2309awful.key({ modkey, }, "/", customization.func.app_finder),
2310
2311--- everyday
2312
2313uniarg:key_repeat({ modkey, "Mod1", }, "l", function ()
2314 awful.util.spawn(tools.system.filemanager)
2315end),
2316
2317uniarg:key_repeat({ modkey, }, "e", function ()
2318 awful.util.spawn(tools.system.filemanager)
2319end),
2320
2321uniarg:key_repeat({ modkey, }, "E", function ()
2322 awful.util.spawn(tools.system.filemanager)
2323end),
2324
2325uniarg:key_repeat({ modkey, "Mod1", }, "p", function ()
2326 awful.util.spawn("putty")
2327end),
2328
2329uniarg:key_repeat({ modkey, "Mod1", }, "r", function ()
2330 awful.util.spawn("remmina")
2331end),
2332
2333uniarg:key_repeat({ modkey, }, "i", function ()
2334 awful.util.spawn(tools.editor.primary)
2335end),
2336
2337uniarg:key_repeat({ modkey, "Shift" }, "i", function ()
2338 awful.util.spawn(tools.editor.secondary)
2339end),
2340
2341uniarg:key_repeat({ modkey, }, "b", function ()
2342 awful.util.spawn(tools.browser.primary)
2343end),
2344
2345uniarg:key_repeat({ modkey, "Shift" }, "b", function ()
2346 awful.util.spawn(tools.browser.secondary)
2347end),
2348
2349uniarg:key_repeat({ modkey, "Mod1", }, "v", function ()
2350 awful.util.spawn("virtualbox")
2351end),
2352
2353uniarg:key_repeat({modkey, "Shift" }, "\\", function()
2354 awful.util.spawn("kmag")
2355end),
2356
2357--- the rest
2358
2359uniarg:key_repeat({}, "XF86AudioPrev", function ()
2360 awful.util.spawn("mpc prev")
2361end),
2362
2363uniarg:key_repeat({}, "XF86AudioNext", function ()
2364 awful.util.spawn("mpc next")
2365end),
2366
2367awful.key({}, "XF86AudioPlay", function ()
2368 awful.util.spawn("mpc toggle")
2369end),
2370
2371awful.key({}, "XF86AudioStop", function ()
2372 awful.util.spawn("mpc stop")
2373end),
2374
2375uniarg:key_numarg({}, "XF86AudioRaiseVolume",
2376function ()
2377 awful.util.spawn("amixer sset Master 5%+")
2378end,
2379function (n)
2380 awful.util.spawn("amixer sset Master " .. n .. "%+")
2381end),
2382
2383uniarg:key_numarg({}, "XF86AudioLowerVolume",
2384function ()
2385 awful.util.spawn("amixer sset Master 5%-")
2386end,
2387function (n)
2388 awful.util.spawn("amixer sset Master " .. n .. "%-")
2389end),
2390
2391awful.key({}, "XF86AudioMute", function ()
2392 awful.util.spawn("amixer sset Master toggle")
2393end),
2394
2395awful.key({}, "XF86AudioMicMute", function ()
2396 awful.util.spawn("amixer sset Mic toggle")
2397end),
2398
2399awful.key({}, "XF86ScreenSaver", function ()
2400 awful.util.spawn("xscreensaver-command -l")
2401end),
2402
2403awful.key({}, "XF86WebCam", function ()
2404 awful.util.spawn("cheese")
2405end),
2406
2407uniarg:key_numarg({}, "XF86MonBrightnessUp",
2408function ()
2409 awful.util.spawn("xbacklight -inc 10")
2410end,
2411function (n)
2412 awful.util.spawn("xbacklight -inc " .. n)
2413end),
2414
2415uniarg:key_numarg({}, "XF86MonBrightnessDown",
2416function ()
2417 awful.util.spawn("xbacklight -dec 10")
2418end,
2419function (n)
2420 awful.util.spawn("xbacklight -dec " .. n)
2421end),
2422
2423awful.key({}, "XF86WLAN", function ()
2424 awful.util.spawn("nm-connection-editor")
2425end),
2426
2427awful.key({}, "XF86Display", function ()
2428 awful.util.spawn("arandr")
2429end),
2430
2431awful.key({}, "Print", function ()
2432 awful.util.spawn("xfce4-screenshooter")
2433end),
2434
2435uniarg:key_repeat({}, "XF86Launch1", function ()
2436 awful.util.spawn(tools.terminal)
2437end),
2438
2439awful.key({ }, "XF86Sleep", function ()
2440 awful.util.spawn("systemctl suspend")
2441end),
2442
2443
2444awful.key({ modkey }, "XF86Sleep", function ()
2445 awful.util.spawn("systemctl hibernate")
2446end),
2447
2448--- hacks for Thinkpad W530 FN mal-function
2449
2450uniarg:key_repeat({ modkey }, "F10", function ()
2451 awful.util.spawn("mpc prev")
2452end),
2453
2454awful.key({ modkey }, "F11", function ()
2455 awful.util.spawn("mpc toggle")
2456end),
2457
2458uniarg:key_repeat({ modkey }, "F12", function ()
2459 awful.util.spawn("mpc next")
2460end),
2461
2462uniarg:key_repeat({ modkey, "Control" }, "Left", function ()
2463 awful.util.spawn("mpc prev")
2464end),
2465
2466awful.key({ modkey, "Control" }, "Down", function ()
2467 awful.util.spawn("mpc toggle")
2468end),
2469
2470uniarg:key_repeat({ modkey, "Control" }, "Right", function ()
2471 awful.util.spawn("mpc next")
2472end),
2473
2474awful.key({ modkey, "Control" }, "Up", function ()
2475 awful.util.spawn("pavucontrol")
2476end),
2477
2478uniarg:key_numarg({ modkey, "Shift" }, "Left",
2479function ()
2480 awful.util.spawn("mpc seek -1%")
2481end,
2482function (n)
2483 awful.util.spawn("mpc seek -" .. n .. "%")
2484end),
2485
2486uniarg:key_numarg({ modkey, "Shift" }, "Right",
2487function ()
2488 awful.util.spawn("mpc seek +1%")
2489end,
2490function (n)
2491 awful.util.spawn("mpc seek +" .. n .. "%")
2492end),
2493
2494uniarg:key_numarg({ modkey, "Shift" }, "Down",
2495function ()
2496 awful.util.spawn("mpc seek -10%")
2497end,
2498function (n)
2499 awful.util.spawn("mpc seek -" .. n .. "%")
2500end),
2501
2502uniarg:key_numarg({ modkey, "Shift" }, "Up",
2503function ()
2504 awful.util.spawn("mpc seek +10%")
2505end,
2506function (n)
2507 awful.util.spawn("mpc seek +" .. n .. "%")
2508end),
2509
2510nil
2511
2512)
2513
2514-- client management
2515
2516--- operation
2517clientkeys = awful.util.table.join(
2518
2519awful.key({ modkey, "Shift" }, "c", customization.func.client_kill),
2520
2521awful.key({ "Mod1", }, "F4", customization.func.client_kill),
2522
2523awful.key({ modkey, }, "f", customization.func.client_fullscreen),
2524
2525awful.key({ modkey, }, "m", customization.func.client_maximize),
2526
2527-- move client to sides, i.e., sidelining
2528
2529awful.key({ modkey, }, "Left", customization.func.client_sideline_left),
2530
2531awful.key({ modkey, }, "Right", customization.func.client_sideline_right),
2532
2533awful.key({ modkey, }, "Up", customization.func.client_sideline_top),
2534
2535awful.key({ modkey, }, "Down", customization.func.client_sideline_bottom),
2536
2537-- extend client sides
2538
2539uniarg:key_numarg({ modkey, "Mod1" }, "Left",
2540customization.func.client_sideline_extend_left,
2541function (n, c)
2542customization.func.client_sideline_extend_left(c, n)
2543end),
2544
2545uniarg:key_numarg({ modkey, "Mod1" }, "Right",
2546customization.func.client_sideline_extend_right,
2547function (n, c)
2548customization.func.client_sideline_extend_right(c, n)
2549end),
2550
2551uniarg:key_numarg({ modkey, "Mod1" }, "Up",
2552customization.func.client_sideline_extend_top,
2553function (n, c)
2554customization.func.client_sideline_extend_top(c, n)
2555end),
2556
2557uniarg:key_numarg({ modkey, "Mod1" }, "Down",
2558customization.func.client_sideline_extend_bottom,
2559function (n, c)
2560customization.func.client_sideline_extend_bottom(c, n)
2561end),
2562
2563-- shrink client sides
2564
2565uniarg:key_numarg({ modkey, "Mod1", "Shift" }, "Left",
2566customization.func.client_sideline_shrink_left,
2567function (n, c)
2568customization.func.client_sideline_shrink_left(c, n)
2569end
2570),
2571
2572uniarg:key_numarg({ modkey, "Mod1", "Shift" }, "Right",
2573customization.func.client_sideline_shrink_right,
2574function (n, c)
2575customization.func.client_sideline_shrink_right(c, n)
2576end
2577),
2578
2579uniarg:key_numarg({ modkey, "Mod1", "Shift" }, "Up",
2580customization.func.client_sideline_shrink_top,
2581function (n, c)
2582customization.func.client_sideline_shrink_top(c, n)
2583end
2584),
2585
2586uniarg:key_numarg({ modkey, "Mod1", "Shift" }, "Down",
2587customization.func.client_sideline_shrink_bottom,
2588function (n, c)
2589customization.func.client_sideline_shrink_bottom(c, n)
2590end
2591),
2592
2593-- maximize/minimize
2594
2595awful.key({ modkey, "Shift" }, "m", customization.func.client_minimize),
2596
2597awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle),
2598
2599
2600awful.key({ modkey, }, "t", customization.func.client_toggle_top),
2601
2602awful.key({ modkey, }, "s", customization.func.client_toggle_sticky),
2603
2604awful.key({ modkey, }, ",", customization.func.client_maximize_horizontal),
2605
2606awful.key({ modkey, }, ".", customization.func.client_maximize_vertical),
2607
2608awful.key({ modkey, }, "[", customization.func.client_opaque_less),
2609
2610awful.key({ modkey, }, "]", customization.func.client_opaque_more),
2611
2612awful.key({ modkey, 'Shift' }, "[", customization.func.client_opaque_off),
2613
2614awful.key({ modkey, 'Shift' }, "]", customization.func.client_opaque_on),
2615
2616awful.key({ modkey, "Control" }, "Return", customization.func.client_swap_with_master),
2617
2618nil
2619
2620)
2621
2622-- Bind all key numbers to tags.
2623-- Be careful: we use keycodes to make it works on any keyboard layout.
2624-- This should map on the top row of your keyboard, usually 1 to 9, plus 0.
2625
2626for i = 1, 10 do
2627 local keycode = "#" .. i+9
2628
2629 globalkeys = awful.util.table.join(globalkeys,
2630
2631 awful.key({ modkey }, keycode,
2632 function ()
2633 local tag
2634 local tags = awful.tag.gettags(awful.screen.focused())
2635 if i <= #tags then
2636 tag = tags[i]
2637 else
2638 local scr = awful.screen.focused()
2639 awful.prompt.run({prompt = "<span fgcolor='red'>new tag: </span>"},
2640 customization.widgets.promptbox[scr].widget,
2641 function (text)
2642 if #text>0 then
2643 tag = awful.tag.add(text)
2644 awful.tag.setscreen(tag, scr)
2645 awful.tag.move(#tags+1, tag)
2646 awful.tag.viewonly(tag)
2647 end
2648 end,
2649 nil)
2650 end
2651 if tag then
2652 awful.tag.viewonly(tag)
2653 end
2654 end),
2655
2656 awful.key({ modkey, "Control" }, keycode,
2657 function ()
2658 local tag
2659 local tags = awful.tag.gettags(awful.screen.focused())
2660 if i <= #tags then
2661 tag = tags[i]
2662 else
2663 local scr = awful.screen.focused()
2664 awful.prompt.run({prompt = "<span fgcolor='red'>new tag: </span>"},
2665 customization.widgets.promptbox[scr].widget,
2666 function (text)
2667 if #text>0 then
2668 tag = awful.tag.add(text)
2669 awful.tag.setscreen(tag, scr)
2670 awful.tag.move(#tags+1, tag)
2671 awful.tag.viewonly(tag)
2672 end
2673 end,
2674 nil)
2675 end
2676 if tag then
2677 awful.tag.viewtoggle(tag)
2678 end
2679 end),
2680
2681 awful.key({ modkey, "Shift" }, keycode,
2682 function ()
2683 local focus = client.focus
2684
2685 if focus then
2686 local tag
2687 local tags = awful.tag.gettags(focus.screen)
2688 if i <= #tags then
2689 tag = tags[i]
2690 else
2691 local scr = awful.screen.focused()
2692 awful.prompt.run({prompt = "<span fgcolor='red'>new tag: </span>"},
2693 customization.widgets.promptbox[scr].widget,
2694 function (text)
2695 if #text>0 then
2696 tag = awful.tag.add(text)
2697 awful.tag.setscreen(tag, scr)
2698 awful.tag.move(#tags+1, tag)
2699 awful.tag.viewonly(tag)
2700 end
2701 end,
2702 nil)
2703 end
2704 if tag then
2705 awful.client.movetotag(tag)
2706 end
2707 end
2708 end),
2709
2710 awful.key({ modkey, "Control", "Shift" }, keycode,
2711 function ()
2712 local focus = client.focus
2713
2714 if focus then
2715 local tag
2716 local tags = awful.tag.gettags(client.focus.screen)
2717 if i <= #tags then
2718 tag = tags[i]
2719 else
2720 local scr = awful.screen.focused()
2721 awful.prompt.run({prompt = "<span fgcolor='red'>new tag: </span>"},
2722 customization.widgets.promptbox[scr].widget,
2723 function (text)
2724 if #text>0 then
2725 tag = awful.tag.add(text)
2726 awful.tag.setscreen(tag, scr)
2727 awful.tag.move(#tags+1, tag)
2728 awful.tag.viewonly(tag)
2729 end
2730 end,
2731 nil)
2732 end
2733 if tag then
2734 awful.client.toggletag(tag)
2735 end
2736 end
2737 end),
2738
2739 nil
2740 )
2741end
2742
2743clientbuttons = awful.util.table.join(
2744awful.button({ }, 1, function (c)
2745 if awful.client.focus.filter(c) then
2746 client.focus = c
2747 c:raise()
2748 end
2749end),
2750awful.button({ modkey }, 1, awful.mouse.client.move),
2751awful.button({ modkey }, 3, awful.mouse.client.resize))
2752
2753-- Set keys
2754root.keys(globalkeys)
2755-- }}}
2756
2757-- {{{ Rules
2758-- Rules to apply to new clients (through the "manage" signal).
2759awful.rules.rules = {
2760
2761 -- All clients will match this rule.
2762 {
2763 rule = { },
2764 properties = {
2765 border_width = beautiful.border_width,
2766 border_color = beautiful.border_normal,
2767 focus = awful.client.focus.filter,
2768 raise = true,
2769 keys = clientkeys,
2770 buttons = clientbuttons,
2771 opacity = customization.default.property.default_naughty_opacity,
2772 screen = awful.screen.preferred,
2773 placement = awful.placement.no_overlap+awful.placement.no_offscreen,
2774 }
2775 },
2776
2777 {
2778 rule = { class = "MPlayer" },
2779 properties = {
2780 floating = true,
2781 opacity = 1,
2782 }
2783 },
2784
2785 {
2786 rule = { class = "gimp" },
2787 properties = {
2788 floating = true,
2789 },
2790 },
2791
2792 --[[
2793 Set Firefox to always map on tags number 2 of screen 1.
2794 { rule = { class = "Firefox" },
2795 properties = { tag = tags[1][2] } },
2796 --]]
2797
2798 {
2799 rule = { class = "Kmag" },
2800 properties = {
2801 ontop = true,
2802 floating = true,
2803 opacity = 0.8,
2804 sticky = true,
2805 },
2806 callback = function (c)
2807 end,
2808 },
2809
2810
2811 {
2812 rule = { class = "Conky" },
2813 properties = {
2814 sticky = true,
2815 opacity = 0.4,
2816 focusable = false,
2817 ontop = false,
2818 },
2819 }
2820
2821}
2822-- }}}
2823
2824-- {{{ Signals
2825-- Signal function to execute when a new client appears.
2826client.connect_signal("manage", function (c, startup)
2827 -- Enable sloppy focus
2828 c:connect_signal("mouse::enter", function(c)
2829 if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
2830 and awful.client.focus.filter(c) then
2831 client.focus = c
2832 end
2833 end)
2834
2835 if not startup then
2836 -- Set the windows at the slave,
2837 -- i.e. put it at the end of others instead of setting it master.
2838 -- awful.client.setslave(c)
2839
2840 -- Put windows in a smart way, only if they does not set an initial position.
2841 if not c.size_hints.user_position and not c.size_hints.program_position then
2842 awful.placement.no_overlap(c)
2843 awful.placement.no_offscreen(c)
2844 end
2845 end
2846
2847 local titlebars_enabled = true
2848 if titlebars_enabled and (c.type == "normal" or c.type == "dialog") then
2849
2850 -- buttons for the titlebar
2851 local buttons = awful.util.table.join(
2852 awful.button({ }, 1, function()
2853 client.focus = c
2854 c:raise()
2855 awful.mouse.client.move(c)
2856 end),
2857 awful.button({ }, 3, function()
2858 client.focus = c
2859 c:raise()
2860 awful.mouse.client.resize(c)
2861 end)
2862 )
2863
2864 -- Widgets that are aligned to the left
2865 local left_layout = wibox.layout.fixed.horizontal()
2866 left_layout:add(awful.titlebar.widget.iconwidget(c))
2867 left_layout:buttons(buttons)
2868
2869 -- Widgets that are aligned to the right
2870 local right_layout = wibox.layout.fixed.horizontal()
2871 right_layout:add(awful.titlebar.widget.floatingbutton(c))
2872 right_layout:add(awful.titlebar.widget.maximizedbutton(c))
2873 right_layout:add(awful.titlebar.widget.stickybutton(c))
2874 right_layout:add(awful.titlebar.widget.ontopbutton(c))
2875 right_layout:add(awful.titlebar.widget.closebutton(c))
2876
2877 -- The title goes in the middle
2878 local middle_layout = wibox.layout.flex.horizontal()
2879 local title = awful.titlebar.widget.titlewidget(c)
2880 title:set_align("center")
2881 middle_layout:add(title)
2882 middle_layout:buttons(buttons)
2883
2884 -- Now bring it all together
2885 local layout = wibox.layout.align.horizontal()
2886 layout:set_left(left_layout)
2887 layout:set_right(right_layout)
2888 layout:set_middle(middle_layout)
2889
2890 awful.titlebar(c):set_widget(layout)
2891
2892 -- hide the titlebar by default (it takes space)
2893 awful.titlebar.hide(c)
2894
2895 end
2896
2897end)
2898
2899client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end)
2900
2901client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
2902
2903customization.func.client_manage_tag = function (c, startup)
2904 if startup then
2905 local client_id = c.pid .. '-' .. c.window
2906
2907 local fname = awesome_client_tags_fname .. '/' .. client_id
2908 local f = io.open(fname, 'r')
2909
2910 if f then
2911 local tags = {}
2912 for tag in io.lines(fname) do
2913 tags = awful.util.table.join(tags, {util.tag.name2tag(tag)})
2914 end
2915 -- remove the file after using it to reduce clutter
2916 os.remove(fname)
2917
2918 if #tags>0 then
2919 c:tags(tags)
2920 -- set c's screen to that of its first (often the only) tag
2921 -- this prevents client to be placed off screen in case of randr change (on the number of screen)
2922 c.screen = awful.tag.getscreen(tags[1])
2923 awful.placement.no_overlap(c)
2924 awful.placement.no_offscreen(c)
2925 end
2926 end
2927 end
2928end
2929
2930client.connect_signal("manage", customization.func.client_manage_tag)
2931
2932-- }}}
2933
2934-- disable startup-notification globally
2935-- prevent unintended mouse cursor change
2936customization.orig.awful_util_spawn = awful.util.spawn
2937awful.util.spawn = function (s)
2938 customization.orig.awful_util_spawn(s, false)
2939end
2940
2941-- XDG style autostart with "dex"
2942-- HACK continue
2943awful.util.spawn_with_shell("if ! [ -e " .. awesome_autostart_once_fname .. " ]; then dex -a -e awesome; touch " .. awesome_autostart_once_fname .. "; fi")
2944customization.func.client_opaque_on(nil) -- start xcompmgr