wibox.drawable: Stop using weak tables

Instead of tracking all drawables that are alive, the code now only
tracks visible drawables. When a drawable is made visible it is
completely repainted. This should not cause a difference when a wibox is
initially made visible, because it has to be redrawn anyway. However,
this introduces a full repaint when a wibox is hidden and then made
visible again.

Thanks to this change, we can stop using weak tables. Visible drawables
cannot be collected and so we can keep a strong reference to them. This
allows us to get rid of the weak tables which solves various problems
involving finalizers and using objects after finalisation.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2016-10-04 21:20:55 +02:00
parent 843d0bdcf5
commit 650b01eb71

View file

@ -24,8 +24,7 @@ local matrix = require("gears.matrix")
local hierarchy = require("wibox.hierarchy")
local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1)
local drawables_draw = setmetatable({}, { __mode = 'k' })
local drawables_force_complete_repaint = setmetatable({}, { __mode = 'k' })
local visible_drawables = {}
-- Get the widget context. This should always return the same table (if
-- possible), so that our draw and fit caches can work efficiently.
@ -267,6 +266,13 @@ function drawable:set_fg(c)
end
function drawable:_inform_visible(visible)
if visible then
visible_drawables[self] = true
-- The wallpaper or widgets might have changed
self:_do_complete_repaint()
else
visible_drawables[self] = nil
end
end
local function emit_difference(name, list, skip)
@ -361,8 +367,6 @@ function drawable.new(d, widget_context_skeleton, drawable_name)
ret._need_complete_repaint = true
ret:draw()
end
drawables_draw[ret.draw] = true
drawables_force_complete_repaint[ret._do_complete_repaint] = true
-- Do a full redraw if the surface changes (the new surface has no content yet)
d:connect_signal("property::surface", ret._do_complete_repaint)
@ -449,15 +453,15 @@ end
-- Redraw all drawables when the wallpaper changes
capi.awesome.connect_signal("wallpaper_changed", function()
for k in pairs(drawables_force_complete_repaint) do
k()
for d in pairs(visible_drawables) do
d:_do_complete_repaint()
end
end)
-- Give drawables a chance to react to screen changes
local function draw_all()
for k in pairs(drawables_draw) do
k()
for d in pairs(visible_drawables) do
d:draw()
end
end
screen.connect_signal("property::geometry", draw_all)