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

fs: asynchronous
[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 tag    = s.selected_tag
93     local mwfact = beautiful.master_width_factor or 0.5
94     local g      = {}
95     g.width      = math.sqrt(mwfact) * mg.width
96     g.height     = math.sqrt(mwfact) * mg.height
97     g.x          = mg.x + (mg.width - g.width) / 2
98     g.y          = mg.y + (mg.height - g.height) / 2
99
100     if c then c:geometry(g) end -- if c is still a valid object
101 end
102
103 -- Non-empty tag browsing
104 -- direction in {-1, 1} <-> {previous, next} non-empty tag
105 function util.tag_view_nonempty(direction, sc)
106    local s = sc or awful.screen.focused()
107
108    for i = 1, #s.tags do
109        awful.tag.viewidx(direction, s)
110        if #s.clients > 0 then
111            return
112        end
113    end
114 end
115
116 -- {{{ Dynamic tagging
117
118 -- Add a new tag
119 function util.add_tag()
120     awful.prompt.run {
121         prompt       = "New tag name: ",
122         textbox      = awful.screen.focused().mypromptbox.widget,
123         exe_callback = function(name)
124             if not name or #name == 0 then return end
125             awful.tag.add(name, { screen = awful.screen.focused() }):view_only()
126         end
127     }
128 end
129
130 -- Rename current tag
131 function util.rename_tag()
132     awful.prompt.run {
133         prompt       = "Rename tag: ",
134         textbox      = awful.screen.focused().mypromptbox.widget,
135         exe_callback = function(new_name)
136             if not new_name or #new_name == 0 then return end
137             local t = awful.screen.focused().selected_tag
138             if t then
139                 t.name = new_name
140             end
141         end
142     }
143 end
144
145 -- Move current tag
146 -- pos in {-1, 1} <-> {previous, next} tag position
147 function util.move_tag(pos)
148     local tag = awful.screen.focused().selected_tag
149     local idx = awful.tag.getidx(tag)
150     if tonumber(pos) <= -1 then
151         awful.tag.move(idx - 1, tag)
152     else
153         awful.tag.move(idx + 1, tag)
154     end
155 end
156
157 -- Delete current tag
158 -- Any rule set on the tag shall be broken
159 function util.delete_tag()
160     local t = awful.screen.focused().selected_tag
161     if not t then return end
162     t:delete()
163 end
164
165 -- }}}
166
167 -- On the fly useless gaps change
168 function util.useless_gaps_resize(thatmuch)
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 })