1 ---------------------------------------------------------------------------
2 -- @author Julien Danjou <julien@danjou.info>
3 -- @copyright 2008 Julien Danjou
4 -- @release @AWESOME_VERSION@
5 ---------------------------------------------------------------------------
7 -- Grab environment we need
19 local util
= require("awful.util")
20 local hooks
= require("awful.hooks")
21 local beautiful
= require("awful.beautiful")
22 local menu
= require("awful.menu")
24 --- Widget module for awful
25 module("awful.widget")
27 -- Various public structures
33 --- Create a new taglist widget.
34 -- @param screen The screen to draw tag list.
35 -- @param label Label function to use.
36 -- @param buttons A table with buttons binding to set.
37 function taglist
.new(scr
, label
, buttons
)
39 local function taglist_update (screen
)
40 -- Return right now if we do not care about this screen
41 if scr
~= screen
then return end
42 local tags
= capi
.screen
[screen
]:tags()
43 -- Hack: if it has been registered as a widget in a wibox,
44 -- it's w.len since __len meta does not work on table until Lua 5.2.
45 -- Otherwise it's standard #w.
46 local len
= w
.len
or #w
49 for i
= len
+ 1, #tags
do
50 w
[i
] = capi
.widget({ type = "textbox", name
= "taglist" .. i
})
53 elseif len
> #tags
then
58 -- Update widgets text
59 for k
, tag in ipairs(tags
) do
60 w
[k
].text
= label(tag)
62 -- Replace press function by a new one calling with tags as
64 -- This is done here because order of tags can change
66 for kb
, b
in ipairs(buttons
) do
68 mbuttons
[kb
] = capi
.button(b
)
69 mbuttons
[kb
].press
= function () b
.press(tag) end
71 w
[k
]:buttons(mbuttons
)
75 hooks
.arrange
.register(taglist_update
)
76 hooks
.tags
.register(taglist_update
)
77 hooks
.tagged
.register(function (c
, tag) taglist_update(c
.screen
) end)
78 hooks
.property
.register(function (c
, prop
)
79 if c
.screen
== scr
and prop
== "urgent" then
80 taglist_update(c
.screen
)
87 --- Return labels for a taglist widget with all tag from screen.
88 -- It returns the tag name and set a special
89 -- foreground and background color for selected tags.
91 -- @param args The arguments table.
92 -- bg_focus The background color for selected tag.
93 -- fg_focus The foreground color for selected tag.
94 -- bg_urgent The background color for urgent tags.
95 -- fg_urgent The foreground color for urgent tags.
96 -- taglist_squares Optional: set "true" or nil to display the taglist squares.
97 -- taglist_squares_sel Optional: an user provided image for selected squares.
98 -- taglist_squares_unsel Optional: an user provided image for unselected squares.
99 -- @return A string to print.
100 function taglist
.label
.all(t
, args
)
101 if not args
then args
= {} end
102 local theme
= beautiful
.get()
103 local fg_focus
= args
.fg_focus
or theme
.taglist_fg_focus
or theme
.fg_focus
104 local bg_focus
= args
.bg_focus
or theme
.taglist_bg_focus
or theme
.bg_focus
105 local fg_urgent
= args
.fg_urgent
or theme
.taglist_fg_urgent
or theme
.fg_urgent
106 local bg_urgent
= args
.bg_urgent
or theme
.taglist_bg_urgent
or theme
.bg_urgent
107 local taglist_squares
= args
.taglist_squares
or theme
.taglist_squares
108 local taglist_squares_sel
= args
.squares_sel
or theme
.squares_sel
109 local taglist_squares_unsel
= args
.squares_unsel
or theme
.squares_unsel
111 local background
= ""
112 local sel
= capi
.client
.focus
119 if sel
and sel
:tags()[t
] then
120 if not taglist_squares
or taglist_squares
== "true" then
121 if taglist_squares_sel
then
122 background
= "resize=\"true\" image=\"" .. taglist_squares_sel
.. "\""
124 background
= "resize=\"true\" image=\"@AWESOME_ICON_PATH@/taglist/squarefw.png\""
127 elseif bg_urgent
or fg_urgent
then
128 for k
, c
in pairs(t
:clients()) do
129 if not taglist_squares
or taglist_squares
== "true" then
130 if taglist_squares_unsel
then
131 background
= "resize=\"true\" image=\"" .. taglist_squares_unsel
.. "\""
133 background
= "resize=\"true\" image=\"@AWESOME_ICON_PATH@/taglist/squarew.png\""
143 if bg_color
and fg_color
then
144 text
= "<bg "..background
.." color='"..bg_color
.."'/> <span color='"..util
.color_strip_alpha(fg_color
).."'>"..util
.escape(t
.name
).."</span> "
146 text
= " <bg "..background
.." />"..util
.escape(t
.name
).." "
151 --- Return labels for a taglist widget with all *non empty* tags from screen.
152 -- It returns the tag name and set a special
153 -- foreground and background color for selected tags.
155 -- @param args The arguments table.
156 -- bg_focus The background color for selected tag.
157 -- fg_focus The foreground color for selected tag.
158 -- bg_urgent The background color for urgent tags.
159 -- fg_urgent The foreground color for urgent tags.
160 -- @return A string to print.
161 function taglist
.label
.noempty(t
, args
)
162 if #t
:clients() > 0 or t
.selected
then
163 if not args
then args
= {} end
164 local theme
= beautiful
.get()
165 local fg_focus
= args
.fg_focus
or theme
.taglist_fg_focus
or theme
.fg_focus
166 local bg_focus
= args
.bg_focus
or theme
.taglist_bg_focus
or theme
.bg_focus
167 local fg_urgent
= args
.fg_urgent
or theme
.taglist_fg_urgent
or theme
.fg_urgent
168 local bg_urgent
= args
.bg_urgent
or theme
.taglist_bg_urgent
or theme
.bg_urgent
177 if bg_urgent
and fg_urgent
then
178 for k
, c
in pairs(t
:clients()) do
186 if fg_color
and bg_color
then
187 text
= "<bg color='" .. bg_color
.. "'/> <span color='" .. util
.color_strip_alpha(fg_color
) .. "'>" .. util
.escape(t
.name
) .. "</span> "
189 text
= " " .. util
.escape(t
.name
) .. " "
195 --- Create a new tasklist widget.
196 -- @param label Label function to use.
197 -- @param buttons A table with buttons binding to set.
198 function tasklist
.new(label
, buttons
)
200 local function tasklist_update ()
201 local clients
= capi
.client
.get()
202 for k
, c
in ipairs(clients
) do
203 if c
.skip_taskbar
or c
.hide
204 or c
.type == "splash" or c
.type == "dock" or c
.type == "desktop" then
205 table.remove(clients
, k
)
208 -- Hack: if it has been registered as a widget in a wibox,
209 -- it's w.len since __len meta does not work on table until Lua 5.2.
210 -- Otherwise it's standard #w.
211 local len
= (w
.len
or #w
) / 2
213 if len
< #clients
then
214 for i
= len
* 2 + 1, #clients
* 2, 2 do
215 w
[i
] = capi
.widget({ type = "imagebox", name
= "tasklist_icon" .. i
, align
= "flex" })
216 w
[i
+ 1] = capi
.widget({ type = "textbox", name
= "tasklist_text" .. i
, align
= "flex" })
219 elseif len
> #clients
then
220 for i
= #clients
* 2 + 1, len
* 2, 2 do
225 -- Update widgets text
226 for k
= 1, #clients
* 2, 2 do
228 -- Replace press function by a new one calling with tags as
231 for kb
, b
in ipairs(buttons
) do
233 mbuttons
[kb
] = capi
.button(b
)
234 mbuttons
[kb
].press
= function () b
.press(clients
[(k
+ 1) / 2]) end
236 w
[k
]:buttons(mbuttons
)
237 w
[k
+ 1]:buttons(mbuttons
)
239 w
[k
+ 1].text
, w
[k
].bg
= label(clients
[(k
+ 1) / 2])
240 if w
[k
+ 1].text
then
242 w
[k
].image
= clients
[(k
+ 1) / 2].icon
248 w
[k
+ 1].visible
= true
251 w
[k
+ 1].visible
= false
255 hooks
.clients
.register(tasklist_update
)
256 hooks
.tagged
.register(tasklist_update
)
257 hooks
.focus
.register(tasklist_update
)
258 hooks
.unfocus
.register(tasklist_update
)
259 hooks
.property
.register(function (c
, prop
)
261 or prop
== "floating"
264 or prop
== "icon_name" then
272 local function widget_tasklist_label_common(c
, args
)
273 if not args
then args
= {} end
274 local theme
= beautiful
.get()
275 local fg_focus
= args
.fg_focus
or theme
.tasklist_fg_focus
or theme
.fg_focus
276 local bg_focus
= args
.bg_focus
or theme
.tasklist_bg_focus
or theme
.bg_focus
277 local fg_urgent
= args
.fg_urgent
or theme
.tasklist_fg_urgent
or theme
.fg_urgent
278 local bg_urgent
= args
.bg_urgent
or theme
.tasklist_bg_urgent
or theme
.bg_urgent
280 local text
= "<margin left=\"2\" right=\"2\"/>"
283 text
= text
.."<bg image=\"@AWESOME_ICON_PATH@/tasklist/floatingw.png\" align=\"right\"/>"
286 name
= util
.escape(c
.icon_name
) or ""
288 name
= util
.escape(c
.name
) or ""
290 if capi
.client
.focus
== c
then
291 if bg_focus
and fg_focus
then
293 text
= text
.. "<bg color='"..bg_focus
.."'/><span color='"..util
.color_strip_alpha(fg_focus
).."'>"..name
.."</span>"
297 elseif c
.urgent
and bg_urgent
and fg_urgent
then
299 text
= text
.. "<bg color='"..bg_urgent
.."'/><span color='"..util
.color_strip_alpha(fg_urgent
).."'>"..name
.."</span>"
306 --- Return labels for a tasklist widget with clients from all tags and screen.
307 -- It returns the client name and set a special
308 -- foreground and background color for focused client.
309 -- It also puts a special icon for floating windows.
310 -- @param c The client.
311 -- @param screen The screen we are drawing on.
312 -- @param args The arguments table.
313 -- bg_focus The background color for focused client.
314 -- fg_focus The foreground color for focused client.
315 -- bg_urgent The background color for urgent clients.
316 -- fg_urgent The foreground color for urgent clients.
317 -- @return A string to print.
318 function tasklist
.label
.allscreen(c
, screen
, args
)
319 return widget_tasklist_label_common(c
, args
)
322 --- Return labels for a tasklist widget with clients from all tags.
323 -- It returns the client name and set a special
324 -- foreground and background color for focused client.
325 -- It also puts a special icon for floating windows.
326 -- @param c The client.
327 -- @param screen The screen we are drawing on.
328 -- @param args The arguments table.
329 -- bg_focus The background color for focused client.
330 -- fg_focus The foreground color for focused client.
331 -- bg_urgent The background color for urgent clients.
332 -- fg_urgent The foreground color for urgent clients.
333 -- @return A string to print.
334 function tasklist
.label
.alltags(c
, screen
, args
)
335 -- Only print client on the same screen as this widget
336 if c
.screen
~= screen
then return end
337 return widget_tasklist_label_common(c
, args
)
340 --- Return labels for a tasklist widget with clients from currently selected tags.
341 -- It returns the client name and set a special
342 -- foreground and background color for focused client.
343 -- It also puts a special icon for floating windows.
344 -- @param c The client.
345 -- @param screen The screen we are drawing on.
346 -- @param args The arguments table.
347 -- bg_focus The background color for focused client.
348 -- fg_focus The foreground color for focused client.
349 -- bg_urgent The background color for urgent clients.
350 -- fg_urgent The foreground color for urgent clients.
351 -- @return A string to print.
352 function tasklist
.label
.currenttags(c
, screen
, args
)
353 -- Only print client on the same screen as this widget
354 if c
.screen
~= screen
then return end
355 for k
, t
in ipairs(capi
.screen
[screen
]:tags()) do
356 if t
.selected
and c
:tags()[t
] then
357 return widget_tasklist_label_common(c
, args
)
362 --- Create a button widget. When clicked, the image is deplaced to make it like
364 -- @param args Standard widget table arguments, plus image for the image path.
365 -- @return A textbox widget configured as a button.
366 function button(args
)
367 if not args
then return end
368 args
.type = "textbox"
369 local w
= capi
.widget(args
)
370 local img_release
= "<bg image=\"" .. args
.image
.. "\" resize=\"true\"/>"
371 local img_press
= "<bg_margin top=\"2\" left=\"2\"/><bg image=\"" .. args
.image
.. "\" resize=\"true\"/>"
373 w
:buttons({ capi
.button({}, 1, function () w
.text
= img_press
end, function () w
.text
= img_release
end) })
374 function w
.mouse_leave(s
) w
.text
= img_release
end
375 function w
.mouse_enter(s
) if capi
.mouse
.coords().buttons
[1] then w
.text
= img_press
end end
379 --- Create a button widget which will launch a command.
380 -- @param args Standard widget table arguments, plus image for the image path
381 -- and command for the command to run on click, or either menu to create menu.
382 -- @return A launcher widget.
383 function launcher(args
)
384 if not args
.command
and not args
.menu
then return end
385 local w
= button(args
)
386 local b
= w
:buttons()
389 b
[#b
+ 1] = capi
.button({}, 1, nil, function () util
.spawn(args
.command
) end)
390 elseif args
.menu
then
391 b
[#b
+ 1] = capi
.button({}, 1, nil, function () menu
.new(args
.menu
[1], args
.menu
[2]) end)
398 -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80