All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@git.madduck.net.
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
5 Layouts, widgets and utilities for Awesome WM
9 Licensed under GNU General Public License v2
10 * (c) 2013, Luke Bonham
11 * (c) 2010-2012, Peter Hofmann
15 local awful = require("awful")
16 local beautiful = require("beautiful")
17 local math = { sqrt = math.sqrt }
20 local string = { gsub = string.gsub }
23 local tonumber = tonumber
25 local wrequire = require("lain.helpers").wrequire
26 local setmetatable = setmetatable
28 -- Lain utilities submodule
30 local util = { _NAME = "lain.util" }
32 -- Like awful.menu.clients, but only show clients of currently selected
34 function util.menu_clients_current_tags(menu, args)
35 -- List of currently selected tags.
36 local cls_tags = awful.tag.selectedlist(mouse.screen)
38 -- Final list of menu items.
46 -- For each selected tag get all clients of that tag and add them to
47 -- the menu. A click on a menu item will raise that client.
51 local cls = t:clients()
53 for k, c in pairs(cls)
55 cls_t[#cls_t + 1] = { awful.util.escape(c.name) or "",
65 -- No clients? Then quit.
71 -- menu may contain some predefined values, otherwise start with a
78 -- Set the list of items and show the menu.
80 local m = awful.menu.new(menu)
85 -- Magnify a client: Set it to "float" and resize it.
86 function util.magnify_client(c)
87 awful.client.floating.set(c, true)
89 local mg = screen[mouse.screen].geometry
90 local tag = awful.tag.selected(mouse.screen)
91 local mwfact = awful.tag.getmwfact(tag)
93 g.width = math.sqrt(mwfact) * mg.width
94 g.height = math.sqrt(mwfact) * mg.height
95 g.x = mg.x + (mg.width - g.width) / 2
96 g.y = mg.y + (mg.height - g.height) / 2
100 -- Read the nice value of pid from /proc.
101 local function get_nice_value(pid)
102 local n = first_line('/proc/' .. pid .. '/stat')
105 -- This should not happen. But I don't want to crash, either.
109 -- Remove pid and tcomm. This is necessary because tcomm may contain
110 -- nasty stuff such as whitespace or additional parentheses...
111 n = string.gsub(n, '.*%) ', '')
113 -- Field number 17 now is the nice value.
114 fields = split(n, ' ')
115 return tonumber(fields[17])
118 -- To be used as a signal handler for "focus"
119 -- This requires beautiful.border_focus{,_highprio,_lowprio}.
120 function util.niceborder_focus(c)
121 local n = get_nice_value(c.pid)
124 c.border_color = beautiful.border_focus
127 c.border_color = beautiful.border_focus_highprio
129 c.border_color = beautiful.border_focus_lowprio
133 -- To be used as a signal handler for "unfocus"
134 -- This requires beautiful.border_normal{,_highprio,_lowprio}.
135 function util.niceborder_unfocus(c)
136 local n = get_nice_value(c.pid)
139 c.border_color = beautiful.border_normal
142 c.border_color = beautiful.border_normal_highprio
144 c.border_color = beautiful.border_normal_lowprio
148 -- Non-empty tag browsing
149 -- direction in {-1, 1} <-> {previous, next} non-empty tag
150 function util.tag_view_nonempty(direction, sc)
151 local s = sc or mouse.screen or 1
152 local scr = screen[s]
154 for i = 1, #tags[s] do
155 awful.tag.viewidx(direction,s)
156 if #awful.client.visible(s) > 0 then
162 -- Dynamically rename the current tag you have focused.
163 function util.prompt_rename_tag(mypromptbox)
164 local tag = awful.tag.selected(mouse.screen)
165 awful.prompt.run({prompt="Rename tag: "}, mypromptbox[mouse.screen].widget,
167 if text:len() > 0 then
169 tag:emit_signal("property::name")
174 -- On the fly useless gaps change
175 function util.useless_gaps_resize(thatmuch)
176 if beautiful.useless_gap_width then
177 beautiful.useless_gap_width = tonumber(beautiful.useless_gap_width) + thatmuch
178 awful.layout.arrange(mouse.screen)
182 return setmetatable(util, { __index = wrequire })