]> 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:

imap: fixed async call
[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 pairs        = pairs
19 local string       = { gsub = string.gsub }
20 local client       = client
21 local screen       = screen
22 local tonumber     = tonumber
23
24 local wrequire     = require("lain.helpers").wrequire
25 local setmetatable = setmetatable
26
27 -- Lain utilities submodule
28 -- lain.util
29 local util = { _NAME = "lain.util" }
30
31 -- Like awful.menu.clients, but only show clients of currently selected tags
32 function util.menu_clients_current_tags(menu, args)
33     -- List of currently selected tags.
34     local cls_tags = awful.screen.focused().selected_tags
35
36     if cls_tags == nil then return nil end
37
38     -- Final list of menu items.
39     local cls_t = {}
40
41     -- For each selected tag get all clients of that tag and add them to
42     -- the menu. A click on a menu item will raise that client.
43     for i = 1,#cls_tags do
44         local t   = cls_tags[i]
45         local cls = t:clients()
46
47         for k, c in pairs(cls) do
48             cls_t[#cls_t + 1] = { awful.util.escape(c.name) or "",
49                                   function ()
50                                       c.minimized = false
51                                       client.focus = c
52                                       c:raise()
53                                   end,
54                                   c.icon }
55         end
56     end
57
58     -- No clients? Then quit.
59     if #cls_t <= 0 then return nil end
60
61     -- menu may contain some predefined values, otherwise start with a
62     -- fresh menu.
63     if not menu then menu = {} end
64
65     -- Set the list of items and show the menu.
66     menu.items = cls_t
67     local m = awful.menu(menu)
68     m:show(args)
69
70     return m
71 end
72
73 -- Magnify a client: set it to "float" and resize it.
74 function util.magnify_client(c)
75     if c and not c.floating then
76         util.mc(c)
77         util.magnified_client = c
78     else
79         c.floating = false
80         util.magnified_client = nil
81     end
82 end
83
84 -- https://github.com/copycat-killer/lain/issues/195
85 function util.mc(c)
86     c = c or util.magnified_client
87     if not c then return end
88
89     c.floating   = true
90     local s      = awful.screen.focused()
91     local mg     = s.geometry
92     local mwfact = beautiful.master_width_factor or 0.5
93     local g      = {}
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
98
99     if c then c:geometry(g) end -- if c is still a valid object
100 end
101
102 -- Non-empty tag browsing
103 -- direction in {-1, 1} <-> {previous, next} non-empty tag
104 function util.tag_view_nonempty(direction, sc)
105    local s = sc or awful.screen.focused()
106
107    for i = 1, #s.tags do
108        awful.tag.viewidx(direction, s)
109        if #s.clients > 0 then
110            return
111        end
112    end
113 end
114
115 -- {{{ Dynamic tagging
116
117 -- Add a new tag
118 function util.add_tag()
119     awful.prompt.run {
120         prompt       = "New tag name: ",
121         textbox      = awful.screen.focused().mypromptbox.widget,
122         exe_callback = function(name)
123             if not name or #name == 0 then return end
124             awful.tag.add(name, { screen = awful.screen.focused() }):view_only()
125         end
126     }
127 end
128
129 -- Rename current tag
130 function util.rename_tag()
131     awful.prompt.run {
132         prompt       = "Rename tag: ",
133         textbox      = awful.screen.focused().mypromptbox.widget,
134         exe_callback = function(new_name)
135             if not new_name or #new_name == 0 then return end
136             local t = awful.screen.focused().selected_tag
137             if t then
138                 t.name = new_name
139             end
140         end
141     }
142 end
143
144 -- Move current tag
145 -- pos in {-1, 1} <-> {previous, next} tag position
146 function util.move_tag(pos)
147     local tag = awful.screen.focused().selected_tag
148     local idx = awful.tag.getidx(tag)
149     if tonumber(pos) <= -1 then
150         awful.tag.move(idx - 1, tag)
151     else
152         awful.tag.move(idx + 1, tag)
153     end
154 end
155
156 -- Delete current tag
157 -- Any rule set on the tag shall be broken
158 function util.delete_tag()
159     local t = awful.screen.focused().selected_tag
160     if not t then return end
161     t:delete()
162 end
163
164 -- }}}
165
166 -- On the fly useless gaps change
167 function util.useless_gaps_resize(thatmuch)
168     beautiful.useless_gap = beautiful.useless_gap or 0
169     beautiful.useless_gap = tonumber(beautiful.useless_gap) + thatmuch
170     awful.layout.arrange(awful.screen.focused())
171 end
172
173 return setmetatable(util, { __index = wrequire })