screen: move the tagging on screen change to Lua
[awesome.git] / lib / awful / tag.lua.in
blob3c9b8e1e1d3263958bac831f5e5e4e9afdde26e9
1 ---------------------------------------------------------------------------
2 -- @author Julien Danjou <julien@danjou.info>
3 -- @copyright 2008 Julien Danjou
4 -- @release @AWESOME_VERSION@
5 ---------------------------------------------------------------------------
7 -- Grab environment we need
8 local util = require("awful.util")
9 local pairs = pairs
10 local ipairs = ipairs
11 local table = table
12 local setmetatable = setmetatable
13 local capi =
15 tag = tag,
16 screen = screen,
17 mouse = mouse,
18 client = client
21 --- Tag module for awful
22 module("awful.tag")
24 -- Private data
25 local data = {}
26 data.history = {}
27 data.history.past = {}
28 data.history.current = {}
29 data.tags = setmetatable({}, { __mode = 'k' })
31 -- History functions
32 history = {}
34 -- Compare 2 tables of tags.
35 -- @param a The first table.
36 -- @param b The second table of tags.
37 -- @return True if the tables are identical, false otherwise.
38 local function compare_select(a, b)
39 if not a or not b then
40 return false
41 end
42 -- Quick size comparison
43 if #a ~= #b then
44 return false
45 end
46 for ka, va in pairs(a) do
47 if b[ka] ~= va.selected then
48 return false
49 end
50 end
51 for kb, vb in pairs(b) do
52 if a[kb].selected ~= vb then
53 return false
54 end
55 end
56 return true
57 end
59 --- Create a set of tags and attach it to a screen.
60 -- @param names The tag name, in a table
61 -- @param screen The tag screen, or 1 if not set.
62 -- @param layout The layout to set for this tags by default.
63 -- @return A table with all created tags.
64 function new(names, screen, layout)
65 local screen = screen or 1
66 local tags = {}
67 for id, name in ipairs(names) do
68 tags[#tags + 1] = capi.tag { name = name }
69 tags[#tags].screen = screen
70 -- Select the first tag.
71 if id == 1 then
72 tags[#tags].selected = true
73 end
74 setproperty(tags[#tags], "layout", layout)
75 end
76 return tags
77 end
79 --- Update the tag history.
80 -- @param screen The screen number.
81 function history.update(screen)
82 local curtags = capi.screen[screen]:tags()
83 if not compare_select(curtags, data.history.current[screen]) then
84 data.history.past[screen] = data.history.current[screen]
85 data.history.current[screen] = {}
86 for k, v in ipairs(curtags) do
87 data.history.current[screen][k] = v.selected
88 end
89 end
90 end
92 --- Revert tag history.
93 -- @param screen The screen number.
94 function history.restore(screen)
95 local s = screen or capi.mouse.screen
96 local tags = capi.screen[s]:tags()
97 for k, t in pairs(tags) do
98 t.selected = data.history.past[s][k]
99 end
102 --- Return a table with all visible tags
103 -- @param s Screen number.
104 -- @return A table with all selected tags.
105 function selectedlist(s)
106 local screen = s or capi.mouse.screen
107 local tags = capi.screen[screen]:tags()
108 local vtags = {}
109 for i, t in pairs(tags) do
110 if t.selected then
111 vtags[#vtags + 1] = t
114 return vtags
117 --- Return only the first visible tag.
118 -- @param s Screen number.
119 function selected(s)
120 return selectedlist(s)[1]
123 --- Set master width factor.
124 -- @param mwfact Master width factor.
125 function setmwfact(mwfact, t)
126 local t = t or selected()
127 if mwfact >= 0 and mwfact <= 1 then
128 setproperty(t, "mwfact", mwfact)
132 --- Increase master width factor.
133 -- @param add Value to add to master width factor.
134 function incmwfact(add, t)
135 setmwfact(getmwfact(t) + add)
138 --- Get master width factor.
139 -- @param t Optional tag.
140 function getmwfact(t)
141 local t = t or selected()
142 return getproperty(t, "mwfact") or 0.5
145 --- Set the number of master windows.
146 -- @param nmaster The number of master windows.
147 -- @param t Optional tag.
148 function setnmaster(nmaster, t)
149 local t = t or selected()
150 if nmaster >= 0 then
151 setproperty(t, "nmaster", nmaster)
155 --- Get the number of master windows.
156 -- @param t Optional tag.
157 function getnmaster(t)
158 local t = t or selected()
159 return getproperty(t, "nmaster") or 1
162 --- Increase the number of master windows.
163 -- @param add Value to add to number of master windows.
164 function incnmaster(add, t)
165 setnmaster(getnmaster(t) + add)
169 --- Set the tag icon
170 -- @param icon the icon to set, either path or image object
171 -- @param tag the tag
172 function seticon(icon, tag)
173 local tag = tag or selected()
174 setproperty(tag, "icon", icon)
177 --- Get the tag icon
178 -- @param t the tag
179 function geticon(tag)
180 local tag = tag or selected()
181 return getproperty(tag, "icon")
184 --- Set number of column windows.
185 -- @param ncol The number of column.
186 function setncol(ncol, t)
187 local t = t or selected()
188 if ncol >= 1 then
189 setproperty(t, "ncol", ncol)
193 --- Get number of column windows.
194 -- @param t Optional tag.
195 function getncol(t)
196 local t = t or selected()
197 return getproperty(t, "ncol") or 1
200 --- Increase number of column windows.
201 -- @param add Value to add to number of column windows.
202 function incncol(add, t)
203 setncol(getncol(t) + add)
206 --- View no tag.
207 -- @param Optional screen number.
208 function viewnone(screen)
209 local tags = capi.screen[screen or capi.mouse.screen]:tags()
210 for i, t in pairs(tags) do
211 t.selected = false
215 --- View a tag by its taglist index.
216 -- @param i The relative index to see.
217 -- @param screen Optional screen number.
218 function viewidx(i, screen)
219 local screen = scree or capi.mouse.screen
220 local tags = capi.screen[screen]:tags()
221 local showntags = {}
222 for k, t in ipairs(tags) do
223 if not getproperty(t, "hide") then
224 table.insert(showntags, t)
227 local sel = selected(screen)
228 viewnone(screen)
229 for k, t in ipairs(showntags) do
230 if t == sel then
231 showntags[util.cycle(#showntags, k + i)].selected = true
236 --- View next tag. This is the same as tag.viewidx(1).
237 -- @param screen The screen number.
238 function viewnext(screen)
239 return viewidx(1, screen)
242 --- View previous tag. This is the same a tag.viewidx(-1).
243 -- @param screen The screen number.
244 function viewprev(screen)
245 return viewidx(-1, screen)
248 --- View only a tag.
249 -- @param t The tag object.
250 function viewonly(t)
251 viewnone(t.screen)
252 t.selected = true
255 --- View only a set of tags.
256 -- @param tags A table with tags to view only.
257 -- @param screen Optional screen number of the tags.
258 function viewmore(tags, screen)
259 viewnone(screen)
260 for i, t in pairs(tags) do
261 t.selected = true
265 --- Get tag data table.
266 -- @param tag The Tag.
267 -- @return The data table.
268 function getdata(tag)
269 return data.tags[tag]
272 --- Get a tag property.
273 -- @param tag The tag.
274 -- @param prop The property name.
275 -- @return The property.
276 function getproperty(tag, prop)
277 if data.tags[tag] then
278 return data.tags[tag][prop]
282 --- Set a tag property.
283 -- This properties are internal to awful. Some are used to draw taglist, or to
284 -- handle layout, etc.
285 -- @param tag The tag.
286 -- @param prop The property name.
287 -- @param value The value.
288 function setproperty(tag, prop, value)
289 if not data.tags[tag] then
290 data.tags[tag] = {}
292 data.tags[tag][prop] = value
293 tag:emit_signal("property::" .. prop)
296 --- Tag a client with the set of current tags.
297 -- @param c The client to tag.
298 -- @param startup Optional: don't do anything if true.
299 function withcurrent(c, startup)
300 if startup ~= true and c.sticky == false then
301 if c.transient_for then
302 c.screen = c.transient_for.screen
303 c:tags(c.transient_for:tags())
305 if #c:tags() == 0 then
306 c:tags(selectedlist(c.screen))
311 local function attached_add_signal_screen(screen, sig, func)
312 capi.screen[screen]:add_signal("tag::attach", function (s, tag)
313 tag:add_signal(sig, func)
314 end)
315 capi.screen[screen]:add_signal("tag::detach", function (s, tag)
316 tag:remove_signal(sig, func)
317 end)
318 for _, tag in ipairs(capi.screen[screen]:tags()) do
319 tag:add_signal(sig, func)
323 --- Add a signal to all attached tag and all tag that will be attached in the
324 -- future. When a tag is detach from the screen, its signal is removed.
325 -- @param screen The screen concerned, or all if nil.
326 function attached_add_signal(screen, ...)
327 if screen then
328 attached_add_signal_screen(screen, ...)
329 else
330 for screen = 1, capi.screen.count() do
331 attached_add_signal_screen(screen, ...)
336 -- Register standards signals
337 capi.client.add_signal("manage", function(c)
338 withcurrent(c)
339 c:add_signal("property::screen", withcurrent)
340 end)
342 setmetatable(_M, { __call = function (_, ...) return new(...) end })
344 -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80