Make tasklist garbage-collectable
Again, instead of directly connecting to various signals for updating a tasklist, this commit changes the code so that there is just a single, global connections and based on this a weak table with all tasklist instances is used do the updates. Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
40db0b7337
commit
abc5a552a4
|
@ -23,6 +23,8 @@ local timer = require("gears.timer")
|
||||||
|
|
||||||
local tasklist = { mt = {} }
|
local tasklist = { mt = {} }
|
||||||
|
|
||||||
|
local instances
|
||||||
|
|
||||||
-- Public structures
|
-- Public structures
|
||||||
tasklist.filter = {}
|
tasklist.filter = {}
|
||||||
|
|
||||||
|
@ -169,7 +171,7 @@ function tasklist.new(screen, filter, buttons, style, update_function, base_widg
|
||||||
local data = setmetatable({}, { __mode = 'k' })
|
local data = setmetatable({}, { __mode = 'k' })
|
||||||
|
|
||||||
local queued_update = false
|
local queued_update = false
|
||||||
local u = function ()
|
function w._do_tasklist_update()
|
||||||
-- Add a delayed callback for the first update.
|
-- Add a delayed callback for the first update.
|
||||||
if not queued_update then
|
if not queued_update then
|
||||||
timer.delayed_call(function()
|
timer.delayed_call(function()
|
||||||
|
@ -179,8 +181,24 @@ function tasklist.new(screen, filter, buttons, style, update_function, base_widg
|
||||||
queued_update = true
|
queued_update = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
tag.attached_connect_signal(screen, "property::selected", u)
|
if instances == nil then
|
||||||
tag.attached_connect_signal(screen, "property::activated", u)
|
instances = {}
|
||||||
|
local function us(s)
|
||||||
|
local i = instances[s]
|
||||||
|
if i then
|
||||||
|
for _, tlist in pairs(i) do
|
||||||
|
tlist._do_tasklist_update()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local function u()
|
||||||
|
for s in ipairs(instances) do
|
||||||
|
us(s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
tag.attached_connect_signal(nil, "property::selected", u)
|
||||||
|
tag.attached_connect_signal(nil, "property::activated", u)
|
||||||
capi.client.connect_signal("property::urgent", u)
|
capi.client.connect_signal("property::urgent", u)
|
||||||
capi.client.connect_signal("property::sticky", u)
|
capi.client.connect_signal("property::sticky", u)
|
||||||
capi.client.connect_signal("property::ontop", u)
|
capi.client.connect_signal("property::ontop", u)
|
||||||
|
@ -195,9 +213,8 @@ function tasklist.new(screen, filter, buttons, style, update_function, base_widg
|
||||||
capi.client.connect_signal("property::icon", u)
|
capi.client.connect_signal("property::icon", u)
|
||||||
capi.client.connect_signal("property::skip_taskbar", u)
|
capi.client.connect_signal("property::skip_taskbar", u)
|
||||||
capi.client.connect_signal("property::screen", function(c, old_screen)
|
capi.client.connect_signal("property::screen", function(c, old_screen)
|
||||||
if screen == c.screen or screen == old_screen then
|
us(c.screen)
|
||||||
u()
|
us(old_screen)
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
capi.client.connect_signal("property::hidden", u)
|
capi.client.connect_signal("property::hidden", u)
|
||||||
capi.client.connect_signal("tagged", u)
|
capi.client.connect_signal("tagged", u)
|
||||||
|
@ -206,7 +223,14 @@ function tasklist.new(screen, filter, buttons, style, update_function, base_widg
|
||||||
capi.client.connect_signal("list", u)
|
capi.client.connect_signal("list", u)
|
||||||
capi.client.connect_signal("focus", u)
|
capi.client.connect_signal("focus", u)
|
||||||
capi.client.connect_signal("unfocus", u)
|
capi.client.connect_signal("unfocus", u)
|
||||||
u()
|
end
|
||||||
|
w._do_tasklist_update()
|
||||||
|
local list = instances[s]
|
||||||
|
if not list then
|
||||||
|
list = setmetatable({}, { __mode = "v" })
|
||||||
|
instances[screen] = list
|
||||||
|
end
|
||||||
|
table.insert(list, w)
|
||||||
return w
|
return w
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,8 @@ local errors = {}
|
||||||
local prepare_for_collect = nil
|
local prepare_for_collect = nil
|
||||||
|
|
||||||
-- Test if some objects can be garbage collected
|
-- Test if some objects can be garbage collected
|
||||||
local function collectable(a, b, c, d, e, f, g, h)
|
local function collectable(a, b, c, d, e, f, g, h, last)
|
||||||
|
assert(last == nil, "got more arguments than supported")
|
||||||
local objs = setmetatable({ a, b, c, d, e, f, g, h }, { __mode = "v" })
|
local objs = setmetatable({ a, b, c, d, e, f, g, h }, { __mode = "v" })
|
||||||
a, b, c, d, e, f, g, h = nil, nil, nil, nil, nil, nil, nil, nil
|
a, b, c, d, e, f, g, h = nil, nil, nil, nil, nil, nil, nil, nil
|
||||||
if prepare_for_collect then
|
if prepare_for_collect then
|
||||||
|
@ -37,12 +38,19 @@ collectable(awful.widget.launcher({ image = cairo.ImageSurface(cairo.Format.ARGB
|
||||||
collectable(awful.widget.prompt())
|
collectable(awful.widget.prompt())
|
||||||
collectable(awful.widget.textclock())
|
collectable(awful.widget.textclock())
|
||||||
collectable(awful.widget.layoutbox(1))
|
collectable(awful.widget.layoutbox(1))
|
||||||
|
|
||||||
function prepare_for_collect()
|
function prepare_for_collect()
|
||||||
-- Only after doing the pending update can a taglist be GC'd.
|
-- Only after doing the pending update can a taglist be GC'd.
|
||||||
awesome.emit_signal("refresh")
|
awesome.emit_signal("refresh")
|
||||||
end
|
end
|
||||||
collectable(awful.widget.taglist(1, awful.widget.taglist.filter.all))
|
collectable(awful.widget.taglist(1, awful.widget.taglist.filter.all))
|
||||||
|
|
||||||
|
function prepare_for_collect()
|
||||||
|
-- Only after doing the pending update can a taglist be GC'd.
|
||||||
|
awesome.emit_signal("refresh")
|
||||||
|
end
|
||||||
|
collectable(awful.widget.tasklist(1, awful.widget.tasklist.filter.currenttags))
|
||||||
|
|
||||||
-- And finally a full wibox
|
-- And finally a full wibox
|
||||||
function prepare_for_collect()
|
function prepare_for_collect()
|
||||||
-- Only after doing the pending repaint can a wibox be GC'd.
|
-- Only after doing the pending repaint can a wibox be GC'd.
|
||||||
|
|
Loading…
Reference in New Issue