awful.tag: add index property for custom tag order
[awesome.git] / lib / awful / widget / taglist.lua.in
blobe10b4cfc5d4b34cc3f44668834bc4a9ec3fd17b8
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_resize = theme.taglist_squares_resize or args.squares_resize or "true"
40 local font = args.font or theme.taglist_font or theme.font or ""
41 local text = "<span font_desc='"..font.."'>"
42 local sel = capi.client.focus
43 local bg_color = nil
44 local fg_color = nil
45 local bg_image
46 local icon
47 local bg_resize = false
48 local is_selected = false
49 if t.selected then
50 bg_color = bg_focus
51 fg_color = fg_focus
52 end
53 if sel then
54 if taglist_squares_sel then
55 -- Check that the selected clients is tagged with 't'.
56 local seltags = sel:tags()
57 for _, v in ipairs(seltags) do
58 if v == t then
59 bg_image = surface.load(taglist_squares_sel)
60 bg_resize = taglist_squares_resize == "true"
61 is_selected = true
62 break
63 end
64 end
65 end
66 end
67 if not is_selected then
68 local cls = t:clients()
69 if #cls > 0 then
70 if taglist_squares_unsel then
71 bg_image = surface.load(taglist_squares_unsel)
72 bg_resize = taglist_squares_resize == "true"
73 end
74 if bg_occupied then bg_color = bg_occupied end
75 if fg_occupied then fg_color = fg_occupied end
76 end
77 for k, c in pairs(cls) do
78 if c.urgent then
79 if bg_urgent then bg_color = bg_urgent end
80 if fg_urgent then fg_color = fg_urgent end
81 break
82 end
83 end
84 end
85 if not tag.getproperty(t, "icon_only") then
86 if fg_color then
87 text = text .. "<span color='"..util.color_strip_alpha(fg_color).."'>" ..
88 (util.escape(t.name) or "") .. "</span>"
89 else
90 text = text .. (util.escape(t.name) or "")
91 end
92 end
93 text = text .. "</span>"
94 if tag.geticon(t) and type(tag.geticon(t)) == "image" then
95 icon = tag.geticon(t)
96 elseif tag.geticon(t) then
97 icon = surface.load(tag.geticon(t))
98 end
100 return text, bg_color, bg_image, icon
103 local function taglist_update(s, w, buttons, filter, data, style, update_function)
104 local tags = {}
105 for k, t in ipairs(tag.gettags(s)) do
106 if not tag.getproperty(t, "hide") and filter(t) then
107 table.insert(tags, t)
111 local function label(c) return taglist.taglist_label(c, style) end
113 update_function(w, buttons, label, data, tags)
116 --- Get the tag object the given widget appears on.
117 -- @param widget The widget the look for.
118 -- @return The tag object.
119 function taglist.gettag(widget)
120 return common.tagwidgets[widget]
123 --- Create a new taglist widget. The last two arguments (update_function
124 -- and base_widget) serve to customize the layout of the taglist (eg. to
125 -- make it vertical). For that, you will need to copy the
126 -- awful.widget.common.list_update function, make your changes to it
127 -- and pass it as update_function here. Also change the base_widget if the
128 -- default is not what you want.
129 -- @param screen The screen to draw taglist for.
130 -- @param filter Filter function to define what clients will be listed.
131 -- @param buttons A table with buttons binding to set.
132 -- @param style The style overrides default theme.
133 -- @param update_function Optional function to create a tag widget on each
134 -- update. @see awful.widget.common.
135 -- @param base_widget Optional container widget for tag widgets. Default
136 -- is wibox.layout.fixed.horizontal().
137 -- bg_focus The background color for focused client.
138 -- fg_focus The foreground color for focused client.
139 -- bg_urgent The background color for urgent clients.
140 -- fg_urgent The foreground color for urgent clients.
141 -- squares_sel Optional: a user provided image for selected squares.
142 -- squares_unsel Optional: a user provided image for unselected squares.
143 -- squares_resize Optional: true or false to resize squares.
144 -- font The font.
145 function taglist.new(screen, filter, buttons, style, update_function, base_widget)
146 local uf = update_function or common.list_update
147 local w = base_widget or fixed.horizontal()
149 local data = setmetatable({}, { __mode = 'k' })
150 local u = function (s)
151 if s == screen then
152 taglist_update(s, w, buttons, filter, data, style, uf)
155 local uc = function (c) return u(c.screen) end
156 local ut = function (t) return u(tag.getscreen(t)) end
157 capi.client.connect_signal("focus", uc)
158 capi.client.connect_signal("unfocus", uc)
159 tag.attached_connect_signal(screen, "property::selected", ut)
160 tag.attached_connect_signal(screen, "property::icon", ut)
161 tag.attached_connect_signal(screen, "property::hide", ut)
162 tag.attached_connect_signal(screen, "property::name", ut)
163 tag.attached_connect_signal(screen, "property::activated", ut)
164 tag.attached_connect_signal(screen, "property::screen", ut)
165 tag.attached_connect_signal(screen, "property::index", ut)
166 capi.client.connect_signal("property::urgent", uc)
167 capi.client.connect_signal("property::screen", function(c)
168 -- If client change screen, refresh it anyway since we don't from
169 -- which screen it was coming :-)
170 u(screen)
171 end)
172 capi.client.connect_signal("tagged", uc)
173 capi.client.connect_signal("untagged", uc)
174 capi.client.connect_signal("unmanage", uc)
175 u(screen)
176 return w
179 --- Filtering function to include all nonempty tags on the screen.
180 -- @param t The tag.
181 -- @param args unused list of extra arguments.
182 -- @return true if t is not empty, else false
183 function taglist.filter.noempty(t, args)
184 return #t:clients() > 0 or t.selected
187 --- Filtering function to include all tags on the screen.
188 -- @param t The tag.
189 -- @param args unused list of extra arguments.
190 -- @return true
191 function taglist.filter.all(t, args)
192 return true
195 function taglist.mt:__call(...)
196 return taglist.new(...)
199 return setmetatable(taglist, taglist.mt)
201 -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80