]> git.madduck.net Git - etc/awesome.git/blob - util/init.lua

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

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.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

c0545b6ebc365c37158bd88fb9888f97c7a60ff9
[etc/awesome.git] / util / init.lua
1
2 --[[
3                                                    
4      Lain                                          
5      Layouts, widgets and utilities for Awesome WM 
6                                                    
7      Utilities section                             
8                                                    
9      Licensed under GNU General Public License v2  
10       * (c) 2013,      Luke Bonham                 
11       * (c) 2010-2012, Peter Hofmann               
12                                                    
13 --]]
14
15 local awful        = require("awful")
16 local beautiful    = require("beautiful")
17 local math         = { sqrt = math.sqrt }
18 local mouse        = mouse
19 local pairs        = pairs
20 local string       = { gsub = string.gsub }
21 local client       = client
22 local screen       = screen
23 local tonumber     = tonumber
24
25 local wrequire     = require("lain.helpers").wrequire
26 local setmetatable = setmetatable
27
28 -- Lain utilities submodule
29 -- lain.util
30 local util = { _NAME = "lain.util" }
31
32 -- Like awful.menu.clients, but only show clients of currently selected
33 -- tags.
34 function util.menu_clients_current_tags(menu, args)
35     -- List of currently selected tags.
36     local cls_tags = awful.tag.selectedlist(mouse.screen)
37
38     -- Final list of menu items.
39     local cls_t = {}
40
41     if cls_tags == nil
42     then
43         return nil
44     end
45
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.
48     for i = 1,#cls_tags
49     do
50         local t = cls_tags[i]
51         local cls = t:clients()
52
53         for k, c in pairs(cls)
54         do
55             cls_t[#cls_t + 1] = { awful.util.escape(c.name) or "",
56                                   function ()
57                                       c.minimized = false
58                                       client.focus = c
59                                       c:raise()
60                                   end,
61                                   c.icon }
62         end
63     end
64
65     -- No clients? Then quit.
66     if #cls_t <= 0
67     then
68         return nil
69     end
70
71     -- menu may contain some predefined values, otherwise start with a
72     -- fresh menu.
73     if not menu
74     then
75         menu = {}
76     end
77
78     -- Set the list of items and show the menu.
79     menu.items = cls_t
80     local m = awful.menu.new(menu)
81     m:show(args)
82     return m
83 end
84
85 -- Magnify a client: Set it to "float" and resize it.
86 function util.magnify_client(c)
87     awful.client.floating.set(c, true)
88
89     local mg = screen[mouse.screen].geometry
90     local tag = awful.tag.selected(mouse.screen)
91     local mwfact = awful.tag.getmwfact(tag)
92     local g = {}
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
97     c:geometry(g)
98 end
99
100 -- Read the nice value of pid from /proc.
101 local function get_nice_value(pid)
102     local n = first_line('/proc/' .. pid .. '/stat')
103     if n == nil
104     then
105         -- This should not happen. But I don't want to crash, either.
106         return 0
107     end
108
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, '.*%) ', '')
112
113     -- Field number 17 now is the nice value.
114     fields = split(n, ' ')
115     return tonumber(fields[17])
116 end
117
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)
122     if n == 0
123     then
124         c.border_color = beautiful.border_focus
125     elseif n < 0
126     then
127         c.border_color = beautiful.border_focus_highprio
128     else
129         c.border_color = beautiful.border_focus_lowprio
130     end
131 end
132
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)
137     if n == 0
138     then
139         c.border_color = beautiful.border_normal
140     elseif n < 0
141     then
142         c.border_color = beautiful.border_normal_highprio
143     else
144         c.border_color = beautiful.border_normal_lowprio
145     end
146 end
147
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]
153
154    for i = 1, #tags[s] do
155        awful.tag.viewidx(direction,s)
156        if #awful.client.visible(s) > 0 then
157            return
158        end
159    end
160 end
161
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,
166     function(text)
167         if text:len() > 0 then
168             tag.name = text
169             tag:emit_signal("property::name")
170         end
171     end)
172 end
173
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)
179     end
180 end
181
182 return setmetatable(util, { __index = wrequire })