Add ability to set background images for empty tag
[awesome.git] / lib / awful / widget / taglist.lua.in
blob39dcc7ee6f562f09daf44d24487a66993a434e04
1 ---------------------------------------------------------------------------
2 -- @author Julien Danjou <julien@danjou.info>
3 -- @copyright 2008-2009 Julien Danjou
4 -- @release @AWESOME_VERSION@
5 ---------------------------------------------------------------------------
7 -- Grab environment we need
8 local capi = { screen = screen,
9 awesome = awesome,
10 client = client }
11 local type = type
12 local setmetatable = setmetatable
13 local pairs = pairs
14 local ipairs = ipairs
15 local table = table
16 local common = require("awful.widget.common")
17 local util = require("awful.util")
18 local tag = require("awful.tag")
19 local beautiful = require("beautiful")
20 local fixed = require("wibox.layout.fixed")
21 local surface = require("gears.surface")
23 --- Taglist widget module for awful
24 -- awful.widget.taglist
25 local taglist = { mt = {} }
26 taglist.filter = {}
28 function taglist.taglist_label(t, args)
29 if not args then args = {} end
30 local theme = beautiful.get()
31 local fg_focus = args.fg_focus or theme.taglist_fg_focus or theme.fg_focus
32 local bg_focus = args.bg_focus or theme.taglist_bg_focus or theme.bg_focus
33 local fg_urgent = args.fg_urgent or theme.taglist_fg_urgent or theme.fg_urgent
34 local bg_urgent = args.bg_urgent or theme.taglist_bg_urgent or theme.bg_urgent
35 local bg_occupied = args.bg_occupied or theme.taglist_bg_occupied
36 local fg_occupied = args.fg_occupied or theme.taglist_fg_occupied
37 local taglist_squares_sel = args.squares_sel or theme.taglist_squares_sel
38 local taglist_squares_unsel = args.squares_unsel or theme.taglist_squares_unsel
39 local taglist_squares_sel_empty = args.squares_sel_empty or theme.taglist_squares_sel_empty
40 local taglist_squares_unsel_empty = args.squares_unsel_empty or theme.taglist_squares_unsel_empty
41 local taglist_squares_resize = theme.taglist_squares_resize or args.squares_resize or "true"
42 local font = args.font or theme.taglist_font or theme.font or ""
43 local text = "<span font_desc='"..font.."'>"
44 local sel = capi.client.focus
45 local bg_color = nil
46 local fg_color = nil
47 local bg_image
48 local icon
49 local bg_resize = false
50 local is_selected = false
51 if t.selected then
52 bg_color = bg_focus
53 fg_color = fg_focus
54 end
55 if sel then
56 if taglist_squares_sel then
57 -- Check that the selected clients is tagged with 't'.
58 local seltags = sel:tags()
59 for _, v in ipairs(seltags) do
60 if v == t then
61 bg_image = taglist_squares_sel
62 bg_resize = taglist_squares_resize == "true"
63 is_selected = true
64 break
65 end
66 end
67 end
68 end
69 if t:clients() == 0 and t.selected and taglist_squares_sel_empty then
70 bg_image = taglist_squares_sel_empty
71 bg_resize = taglist_squares_resize == "true"
72 elseif not is_selected then
73 local cls = t:clients()
74 if #cls > 0 then
75 if taglist_squares_unsel then
76 bg_image = taglist_squares_unsel
77 bg_resize = taglist_squares_resize == "true"
78 end
79 if bg_occupied then bg_color = bg_occupied end
80 if fg_occupied then fg_color = fg_occupied end
81 else
82 if taglist_squares_unsel_empty then
83 bg_image = taglist_squares_unsel_empty
84 bg_resize = taglist_squares_resize == "true"
85 end
86 end
87 for k, c in pairs(cls) do
88 if c.urgent then
89 if bg_urgent then bg_color = bg_urgent end
90 if fg_urgent then fg_color = fg_urgent end
91 break
92 end
93 end
94 end
95 if not tag.getproperty(t, "icon_only") then
96 if fg_color then
97 text = text .. "<span color='"..util.color_strip_alpha(fg_color).."'>" ..
98 (util.escape(t.name) or "") .. "</span>"
99 else
100 text = text .. (util.escape(t.name) or "")
103 text = text .. "</span>"
104 if tag.geticon(t) and type(tag.geticon(t)) == "image" then
105 icon = tag.geticon(t)
106 elseif tag.geticon(t) then
107 icon = surface.load(tag.geticon(t))
110 return text, bg_color, bg_image, icon
113 local function taglist_update(s, w, buttons, filter, data, style, update_function)
114 local tags = {}
115 for k, t in ipairs(tag.gettags(s)) do
116 if not tag.getproperty(t, "hide") and filter(t) then
117 table.insert(tags, t)
121 local function label(c) return taglist.taglist_label(c, style) end
123 update_function(w, buttons, label, data, tags)
126 --- Get the tag object the given widget appears on.
127 -- @param widget The widget the look for.
128 -- @return The tag object.
129 function taglist.gettag(widget)
130 return common.tagwidgets[widget]
133 --- Create a new taglist widget. The last two arguments (update_function
134 -- and base_widget) serve to customize the layout of the taglist (eg. to
135 -- make it vertical). For that, you will need to copy the
136 -- awful.widget.common.list_update function, make your changes to it
137 -- and pass it as update_function here. Also change the base_widget if the
138 -- default is not what you want.
139 -- @param screen The screen to draw taglist for.
140 -- @param filter Filter function to define what clients will be listed.
141 -- @param buttons A table with buttons binding to set.
142 -- @param style The style overrides default theme.
143 -- @param update_function Optional function to create a tag widget on each
144 -- update. @see awful.widget.common.
145 -- @param base_widget Optional container widget for tag widgets. Default
146 -- is wibox.layout.fixed.horizontal().
147 -- bg_focus The background color for focused client.
148 -- fg_focus The foreground color for focused client.
149 -- bg_urgent The background color for urgent clients.
150 -- fg_urgent The foreground color for urgent clients.
151 -- squares_sel Optional: a user provided image for selected squares.
152 -- squares_unsel Optional: a user provided image for unselected squares.
153 -- squares_sel_empty Optional: a user provided image for selected squares for empty tags.
154 -- squares_unsel_empty Optional: a user provided image for unselected squares for empty tags.
155 -- squares_resize Optional: true or false to resize squares.
156 -- font The font.
157 function taglist.new(screen, filter, buttons, style, update_function, base_widget)
158 local uf = update_function or common.list_update
159 local w = base_widget or fixed.horizontal()
161 local data = setmetatable({}, { __mode = 'k' })
162 local u = function (s)
163 if s == screen then
164 taglist_update(s, w, buttons, filter, data, style, uf)
167 local uc = function (c) return u(c.screen) end
168 local ut = function (t) return u(tag.getscreen(t)) end
169 capi.client.connect_signal("focus", uc)
170 capi.client.connect_signal("unfocus", uc)
171 tag.attached_connect_signal(screen, "property::selected", ut)
172 tag.attached_connect_signal(screen, "property::icon", ut)
173 tag.attached_connect_signal(screen, "property::hide", ut)
174 tag.attached_connect_signal(screen, "property::name", ut)
175 tag.attached_connect_signal(screen, "property::activated", ut)
176 tag.attached_connect_signal(screen, "property::screen", ut)
177 tag.attached_connect_signal(screen, "property::index", ut)
178 capi.client.connect_signal("property::urgent", uc)
179 capi.client.connect_signal("property::screen", function(c)
180 -- If client change screen, refresh it anyway since we don't from
181 -- which screen it was coming :-)
182 u(screen)
183 end)
184 capi.client.connect_signal("tagged", uc)
185 capi.client.connect_signal("untagged", uc)
186 capi.client.connect_signal("unmanage", uc)
187 u(screen)
188 return w
191 --- Filtering function to include all nonempty tags on the screen.
192 -- @param t The tag.
193 -- @param args unused list of extra arguments.
194 -- @return true if t is not empty, else false
195 function taglist.filter.noempty(t, args)
196 return #t:clients() > 0 or t.selected
199 --- Filtering function to include all tags on the screen.
200 -- @param t The tag.
201 -- @param args unused list of extra arguments.
202 -- @return true
203 function taglist.filter.all(t, args)
204 return true
207 function taglist.mt:__call(...)
208 return taglist.new(...)
211 return setmetatable(taglist, taglist.mt)
213 -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80