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")
12 local setmetatable
= setmetatable
21 --- Useful functions for tag manipulation.
27 data
.tags
= setmetatable({}, { __mode
= 'k' })
33 --- Move a tag to an absolute position in the screen[]:tags() table.
34 -- @param new_index Integer absolute position in the table to insert.
35 function move(new_index
, target_tag
)
36 local target_tag
= target_tag
or selected()
37 local scr
= target_tag
.screen
38 local tmp_tags
= capi
.screen
[scr
]:tags()
40 if (not new_index
) or (new_index
< 1) or (new_index
> #tmp_tags
) then
44 for i
, t
in ipairs(tmp_tags
) do
45 if t
== target_tag
then
46 table.remove(tmp_tags
, i
)
51 table.insert(tmp_tags
, new_index
, target_tag
)
52 capi
.screen
[scr
]:tags(tmp_tags
)
55 --- Create a set of tags and attach it to a screen.
56 -- @param names The tag name, in a table
57 -- @param screen The tag screen, or 1 if not set.
58 -- @param layout The layout or layout table to set for this tags by default.
59 -- @return A table with all created tags.
60 function new(names
, screen
, layout
)
61 local screen
= screen
or 1
63 for id
, name
in ipairs(names
) do
64 tags
[#tags
+ 1] = capi
.tag { name
= name
}
65 tags
[#tags
].screen
= screen
66 -- Select the first tag.
68 tags
[#tags
].selected
= true
70 setproperty(tags
[#tags
], "layout", layout
and (layout
[#tags
] or layout
[1]) or layout
)
75 --- Update the tag history.
76 -- @param obj Screen object.
77 function history
.update(obj
)
79 local curtags
= capi
.screen
[s
]:tags()
80 -- create history table
81 if not data
.history
[s
] then
84 elseif #data
.history
[s
] >= history
.limit
then
85 for i
= history
.limit
, #data
.history
[s
] do
86 data
.history
[s
][i
] = nil
89 -- store previously selected tags in the history table
90 table.insert(data
.history
[s
], 1, data
.history
[s
].current
)
91 data
.history
[s
].previous
= data
.history
[s
][1]
92 -- store currently selected tags
93 data
.history
[s
].current
= setmetatable(selectedlist(s
), { __mode
= 'v' })
96 --- Revert tag history.
97 -- @param screen The screen number.
98 -- @param idx Index in history. Defaults to "previous" which is a special index
99 -- toggling between last two selected sets of tags. Number (eg 1) will go back
100 -- to the given index in history.
101 function history
.restore(screen
, idx
)
102 local s
= screen
or capi
.mouse
.screen
103 local i
= idx
or "previous"
104 local sel
= selectedlist(s
)
105 -- do nothing if history empty
106 if not data
.history
[s
] or not data
.history
[s
][i
] then return end
107 -- if all tags been deleted, try next entry
108 if #data
.history
[s
][i
] == 0 then
109 if i
== "previous" then i
= 0 end
110 history
.restore(s
, i
+ 1)
115 -- select tags from the history entry
116 for _
, t
in ipairs(data
.history
[s
][i
]) do
119 -- update currently selected tags table
120 data
.history
[s
].current
= data
.history
[s
][i
]
121 -- store previously selected tags
122 data
.history
[s
].previous
= setmetatable(sel
, { __mode
= 'v' })
123 -- remove the reverted history entry
124 if i
~= "previous" then table.remove(data
.history
[s
], i
) end
127 --- Return a table with all visible tags
128 -- @param s Screen number.
129 -- @return A table with all selected tags.
130 function selectedlist(s
)
131 local screen
= s
or capi
.mouse
.screen
132 local tags
= capi
.screen
[screen
]:tags()
134 for i
, t
in pairs(tags
) do
136 vtags
[#vtags
+ 1] = t
142 --- Return only the first visible tag.
143 -- @param s Screen number.
145 return selectedlist(s
)[1]
148 --- Set master width factor.
149 -- @param mwfact Master width factor.
150 function setmwfact(mwfact
, t
)
151 local t
= t
or selected()
152 if mwfact
>= 0 and mwfact
<= 1 then
153 setproperty(t
, "mwfact", mwfact
)
157 --- Increase master width factor.
158 -- @param add Value to add to master width factor.
159 function incmwfact(add
, t
)
160 setmwfact(getmwfact(t
) + add
)
163 --- Get master width factor.
164 -- @param t Optional tag.
165 function getmwfact(t
)
166 local t
= t
or selected()
167 return getproperty(t
, "mwfact") or 0.5
170 --- Set the number of master windows.
171 -- @param nmaster The number of master windows.
172 -- @param t Optional tag.
173 function setnmaster(nmaster
, t
)
174 local t
= t
or selected()
176 setproperty(t
, "nmaster", nmaster
)
180 --- Get the number of master windows.
181 -- @param t Optional tag.
182 function getnmaster(t
)
183 local t
= t
or selected()
184 return getproperty(t
, "nmaster") or 1
187 --- Increase the number of master windows.
188 -- @param add Value to add to number of master windows.
189 function incnmaster(add
, t
)
190 setnmaster(getnmaster(t
) + add
)
195 -- @param icon the icon to set, either path or image object
196 -- @param tag the tag
197 function seticon(icon
, tag)
198 local tag = tag or selected()
199 setproperty(tag, "icon", icon
)
204 function geticon(tag)
205 local tag = tag or selected()
206 return getproperty(tag, "icon")
209 --- Set number of column windows.
210 -- @param ncol The number of column.
211 function setncol(ncol
, t
)
212 local t
= t
or selected()
214 setproperty(t
, "ncol", ncol
)
218 --- Get number of column windows.
219 -- @param t Optional tag.
221 local t
= t
or selected()
222 return getproperty(t
, "ncol") or 1
225 --- Increase number of column windows.
226 -- @param add Value to add to number of column windows.
227 function incncol(add
, t
)
228 setncol(getncol(t
) + add
)
232 -- @param Optional screen number.
233 function viewnone(screen
)
234 local tags
= capi
.screen
[screen
or capi
.mouse
.screen
]:tags()
235 for i
, t
in pairs(tags
) do
240 --- View a tag by its taglist index.
241 -- @param i The relative index to see.
242 -- @param screen Optional screen number.
243 function viewidx(i
, screen
)
244 local screen
= screen
and screen
.index
or capi
.mouse
.screen
245 local tags
= capi
.screen
[screen
]:tags()
247 for k
, t
in ipairs(tags
) do
248 if not getproperty(t
, "hide") then
249 table.insert(showntags
, t
)
252 local sel
= selected(screen
)
254 for k
, t
in ipairs(showntags
) do
256 showntags
[util
.cycle(#showntags
, k
+ i
)].selected
= true
259 capi
.screen
[screen
]:emit_signal("tag::history::update")
262 --- View next tag. This is the same as tag.viewidx(1).
263 -- @param screen The screen number.
264 function viewnext(screen
)
265 return viewidx(1, screen
)
268 --- View previous tag. This is the same a tag.viewidx(-1).
269 -- @param screen The screen number.
270 function viewprev(screen
)
271 return viewidx(-1, screen
)
275 -- @param t The tag object.
277 local tags
= capi
.screen
[t
.screen
]:tags()
278 -- First, untag everyone except the viewed tag.
279 for _
, tag in pairs(tags
) do
284 -- Then, set this one to selected.
285 -- We need to do that in 2 operations so we avoid flickering and several tag
286 -- selected at the same time.
288 capi
.screen
[t
.screen
]:emit_signal("tag::history::update")
291 --- View only a set of tags.
292 -- @param tags A table with tags to view only.
293 -- @param screen Optional screen number of the tags.
294 function viewmore(tags
, screen
)
295 local screen_tags
= capi
.screen
[screen
or capi
.mouse
.screen
]:tags()
296 for _
, tag in ipairs(screen_tags
) do
297 if not util
.table.hasitem(tags
, tag) then
301 for _
, tag in ipairs(tags
) do
304 capi
.screen
[screen
]:emit_signal("tag::history::update")
307 --- Toggle selection of a tag
308 -- @param tag Tag to be toggled
309 function viewtoggle(t
)
310 t
.selected
= not t
.selected
311 capi
.screen
[t
.screen
]:emit_signal("tag::history::update")
314 --- Get tag data table.
315 -- @param tag The Tag.
316 -- @return The data table.
317 function getdata(tag)
318 return data
.tags
[tag]
321 --- Get a tag property.
322 -- @param tag The tag.
323 -- @param prop The property name.
324 -- @return The property.
325 function getproperty(tag, prop
)
326 if data
.tags
[tag] then
327 return data
.tags
[tag][prop
]
331 --- Set a tag property.
332 -- This properties are internal to awful. Some are used to draw taglist, or to
333 -- handle layout, etc.
334 -- @param tag The tag.
335 -- @param prop The property name.
336 -- @param value The value.
337 function setproperty(tag, prop
, value
)
338 if not data
.tags
[tag] then
341 data
.tags
[tag][prop
] = value
342 tag:emit_signal("property::" .. prop
)
345 --- Tag a client with the set of current tags.
346 -- @param c The client to tag.
347 -- @param startup Optional: don't do anything if true.
348 function withcurrent(c
, startup
)
349 if startup
~= true and c
.sticky
== false then
350 if #c
:tags() == 0 then
351 c
:tags(selectedlist(c
.screen
))
356 local function attached_add_signal_screen(screen
, sig
, func
)
357 capi
.screen
[screen
]:add_signal("tag::attach", function (s
, tag)
358 tag:add_signal(sig
, func
)
360 capi
.screen
[screen
]:add_signal("tag::detach", function (s
, tag)
361 tag:remove_signal(sig
, func
)
363 for _
, tag in ipairs(capi
.screen
[screen
]:tags()) do
364 tag:add_signal(sig
, func
)
368 --- Add a signal to all attached tag and all tag that will be attached in the
369 -- future. When a tag is detach from the screen, its signal is removed.
370 -- @param screen The screen concerned, or all if nil.
371 function attached_add_signal(screen
, ...)
373 attached_add_signal_screen(screen
, ...)
375 for screen
= 1, capi
.screen
.count() do
376 attached_add_signal_screen(screen
, ...)
381 -- Register standards signals
382 capi
.client
.add_signal("manage", function(c
, startup
)
383 -- If we are not managing this application at startup,
384 -- move it to the screen where the mouse is.
385 -- We only do it for "normal" windows (i.e. no dock, etc).
387 and c
.type ~= "desktop"
389 and c
.type ~= "splash" then
390 if c
.transient_for
then
391 c
.screen
= c
.transient_for
.screen
393 c
:tags(c
.transient_for
:tags())
396 c
.screen
= capi
.mouse
.screen
399 c
:add_signal("property::screen", withcurrent
)
402 capi
.client
.add_signal("manage", withcurrent
)
404 for s
= 1, capi
.screen
.count() do
405 capi
.screen
[s
]:add_signal("tag::history::update", history
.update
)
408 setmetatable(_M
, { __call
= function (_
, ...) return new(...) end })
410 -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80