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
,
12 local setmetatable
= setmetatable
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
= {} }
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
49 local bg_resize
= false
50 local is_selected
= false
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
61 bg_image
= taglist_squares_sel
62 bg_resize
= taglist_squares_resize
== "true"
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()
75 if taglist_squares_unsel
then
76 bg_image
= taglist_squares_unsel
77 bg_resize
= taglist_squares_resize
== "true"
79 if bg_occupied
then bg_color
= bg_occupied
end
80 if fg_occupied
then fg_color
= fg_occupied
end
82 if taglist_squares_unsel_empty
then
83 bg_image
= taglist_squares_unsel_empty
84 bg_resize
= taglist_squares_resize
== "true"
87 for k
, c
in pairs(cls
) do
89 if bg_urgent
then bg_color
= bg_urgent
end
90 if fg_urgent
then fg_color
= fg_urgent
end
95 if not tag.getproperty(t
, "icon_only") then
97 text
= text
.. "<span color='"..util
.color_strip_alpha(fg_color
).."'>" ..
98 (util
.escape(t
.name
) or "") .. "</span>"
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
)
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.
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
)
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 :-)
184 capi
.client
.connect_signal("tagged", uc
)
185 capi
.client
.connect_signal("untagged", uc
)
186 capi
.client
.connect_signal("unmanage", uc
)
191 --- Filtering function to include all nonempty tags on the screen.
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.
201 -- @param args unused list of extra arguments.
203 function taglist
.filter
.all(t
, args
)
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