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 if not awful.client.floating.get(c) then
88 awful.client.floating.set(c, true)
90 local mg = screen[mouse.screen].geometry
91 local tag = awful.tag.selected(mouse.screen)
92 local mwfact = awful.tag.getmwfact(tag)
94 g.width = math.sqrt(mwfact) * mg.width
95 g.height = math.sqrt(mwfact) * mg.height
96 g.x = mg.x + (mg.width - g.width) / 2
97 g.y = mg.y + (mg.height - g.height) / 2
100 awful.client.floating.set(c, false)
104 -- Read the nice value of pid from /proc.
105 local function get_nice_value(pid)
106 local n = first_line('/proc/' .. pid .. '/stat')
109 -- This should not happen. But I don't want to crash, either.
113 -- Remove pid and tcomm. This is necessary because tcomm may contain
114 -- nasty stuff such as whitespace or additional parentheses...
115 n = string.gsub(n, '.*%) ', '')
117 -- Field number 17 now is the nice value.
118 fields = split(n, ' ')
119 return tonumber(fields[17])
122 -- To be used as a signal handler for "focus"
123 -- This requires beautiful.border_focus{,_highprio,_lowprio}.
124 function util.niceborder_focus(c)
125 local n = get_nice_value(c.pid)
128 c.border_color = beautiful.border_focus
131 c.border_color = beautiful.border_focus_highprio
133 c.border_color = beautiful.border_focus_lowprio
137 -- To be used as a signal handler for "unfocus"
138 -- This requires beautiful.border_normal{,_highprio,_lowprio}.
139 function util.niceborder_unfocus(c)
140 local n = get_nice_value(c.pid)
143 c.border_color = beautiful.border_normal
146 c.border_color = beautiful.border_normal_highprio
148 c.border_color = beautiful.border_normal_lowprio
152 -- Non-empty tag browsing
153 -- direction in {-1, 1} <-> {previous, next} non-empty tag
154 function util.tag_view_nonempty(direction, sc)
155 local s = sc or mouse.screen or 1
156 local scr = screen[s]
158 for i = 1, #tags[s] do
159 awful.tag.viewidx(direction,s)
160 if #awful.client.visible(s) > 0 then
166 -- {{{ Dynamic tagging
169 function util.add_tag(mypromptbox)
170 awful.prompt.run({prompt="New tag name: "}, mypromptbox[mouse.screen].widget,
172 if text:len() > 0 then
173 props = { selected = true }
174 tag = awful.tag.add(new_name, props)
176 tag:emit_signal("property::name")
181 -- Rename current tag
183 function util.rename_tag(mypromptbox)
184 local tag = awful.tag.selected(mouse.screen)
185 awful.prompt.run({prompt="Rename tag: "}, mypromptbox[mouse.screen].widget,
187 if text:len() > 0 then
189 tag:emit_signal("property::name")
195 -- pos in {-1, 1} <-> {previous, next} tag position
196 function util.move_tag(pos)
197 local tag = awful.tag.selected(mouse.screen)
198 local idx = awful.tag.getidx(tag)
199 if tonumber(pos) <= -1 then
200 awful.tag.move(idx - 1, tag)
202 awful.tag.move(idx + 1, tag)
206 -- Delete current tag (if empty)
207 -- Any rule set on the tag shall be broken
208 function util.remove_tag()
209 local tag = awful.tag.selected(mouse.screen)
210 local prevtag = awful.tag.gettags(mouse.screen)[awful.tag.getidx(tag) - 1]
211 awful.tag.delete(tag, prevtag)
216 -- On the fly useless gaps change
217 function util.useless_gaps_resize(thatmuch)
218 beautiful.useless_gap_width = tonumber(beautiful.useless_gap_width) + thatmuch
219 awful.layout.arrange(mouse.screen)
222 return setmetatable(util, { __index = wrequire })