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.
41 if cls_tags == nil then return nil end
43 -- For each selected tag get all clients of that tag and add them to
44 -- the menu. A click on a menu item will raise that client.
48 local cls = t:clients()
50 for k, c in pairs(cls)
52 cls_t[#cls_t + 1] = { awful.util.escape(c.name) or "",
62 -- No clients? Then quit.
63 if #cls_t <= 0 then return nil end
65 -- menu may contain some predefined values, otherwise start with a
67 if not menu then menu = {} end
69 -- Set the list of items and show the menu.
71 local m = awful.menu.new(menu)
76 -- Magnify a client: Set it to "float" and resize it.
77 function util.magnify_client(c)
78 if not awful.client.floating.get(c) then
79 awful.client.floating.set(c, true)
81 local mg = screen[mouse.screen].geometry
82 local tag = awful.tag.selected(mouse.screen)
83 local mwfact = awful.tag.getmwfact(tag)
85 g.width = math.sqrt(mwfact) * mg.width
86 g.height = math.sqrt(mwfact) * mg.height
87 g.x = mg.x + (mg.width - g.width) / 2
88 g.y = mg.y + (mg.height - g.height) / 2
91 awful.client.floating.set(c, false)
95 -- Read the nice value of pid from /proc.
96 local function get_nice_value(pid)
97 local n = first_line('/proc/' .. pid .. '/stat')
100 -- This should not happen. But I don't want to crash, either.
104 -- Remove pid and tcomm. This is necessary because tcomm may contain
105 -- nasty stuff such as whitespace or additional parentheses...
106 n = string.gsub(n, '.*%) ', '')
108 -- Field number 17 now is the nice value.
109 fields = split(n, ' ')
110 return tonumber(fields[17])
113 -- To be used as a signal handler for "focus"
114 -- This requires beautiful.border_focus{,_highprio,_lowprio}.
115 function util.niceborder_focus(c)
116 local n = get_nice_value(c.pid)
119 c.border_color = beautiful.border_focus
122 c.border_color = beautiful.border_focus_highprio
124 c.border_color = beautiful.border_focus_lowprio
128 -- To be used as a signal handler for "unfocus"
129 -- This requires beautiful.border_normal{,_highprio,_lowprio}.
130 function util.niceborder_unfocus(c)
131 local n = get_nice_value(c.pid)
134 c.border_color = beautiful.border_normal
137 c.border_color = beautiful.border_normal_highprio
139 c.border_color = beautiful.border_normal_lowprio
143 -- Non-empty tag browsing
144 -- direction in {-1, 1} <-> {previous, next} non-empty tag
145 function util.tag_view_nonempty(direction, sc)
146 local s = sc or mouse.screen or 1
147 local scr = screen[s]
149 for i = 1, #awful.tag.gettags(s) do
150 awful.tag.viewidx(direction,s)
151 if #awful.client.visible(s) > 0 then
157 -- {{{ Dynamic tagging
160 function util.add_tag(mypromptbox)
161 awful.prompt.run({prompt="New tag name: "}, mypromptbox[mouse.screen].widget,
163 if text:len() > 0 then
164 props = { selected = true }
165 tag = awful.tag.add(new_name, props)
167 tag:emit_signal("property::name")
172 -- Rename current tag
174 function util.rename_tag(mypromptbox)
175 local tag = awful.tag.selected(mouse.screen)
176 awful.prompt.run({prompt="Rename tag: "}, mypromptbox[mouse.screen].widget,
178 if text:len() > 0 then
180 tag:emit_signal("property::name")
186 -- pos in {-1, 1} <-> {previous, next} tag position
187 function util.move_tag(pos)
188 local tag = awful.tag.selected(mouse.screen)
189 local idx = awful.tag.getidx(tag)
190 if tonumber(pos) <= -1 then
191 awful.tag.move(idx - 1, tag)
193 awful.tag.move(idx + 1, tag)
197 -- Remove current tag (if empty)
198 -- Any rule set on the tag shall be broken
199 function util.remove_tag()
200 local tag = awful.tag.selected(mouse.screen)
201 local prevtag = awful.tag.gettags(mouse.screen)[awful.tag.getidx(tag) - 1]
202 awful.tag.delete(tag, prevtag)
207 -- On the fly useless gaps change
208 function util.useless_gaps_resize(thatmuch)
209 beautiful.useless_gap_width = tonumber(beautiful.useless_gap_width) + thatmuch
210 awful.layout.arrange(mouse.screen)
213 -- Check if an element exist on a table
214 function util.element_in_table(element, tbl)
215 for _, i in pairs(tbl) do
223 return setmetatable(util, { __index = wrequire })