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:
parent
843d0bdcf5
commit
650b01eb71
|
@ -24,8 +24,7 @@ local matrix = require("gears.matrix")
|
||||||
local hierarchy = require("wibox.hierarchy")
|
local hierarchy = require("wibox.hierarchy")
|
||||||
local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1)
|
local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1)
|
||||||
|
|
||||||
local drawables_draw = setmetatable({}, { __mode = 'k' })
|
local visible_drawables = {}
|
||||||
local drawables_force_complete_repaint = setmetatable({}, { __mode = 'k' })
|
|
||||||
|
|
||||||
-- Get the widget context. This should always return the same table (if
|
-- Get the widget context. This should always return the same table (if
|
||||||
-- possible), so that our draw and fit caches can work efficiently.
|
-- possible), so that our draw and fit caches can work efficiently.
|
||||||
|
@ -267,6 +266,13 @@ function drawable:set_fg(c)
|
||||||
end
|
end
|
||||||
|
|
||||||
function drawable:_inform_visible(visible)
|
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
|
end
|
||||||
|
|
||||||
local function emit_difference(name, list, skip)
|
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._need_complete_repaint = true
|
||||||
ret:draw()
|
ret:draw()
|
||||||
end
|
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)
|
-- Do a full redraw if the surface changes (the new surface has no content yet)
|
||||||
d:connect_signal("property::surface", ret._do_complete_repaint)
|
d:connect_signal("property::surface", ret._do_complete_repaint)
|
||||||
|
@ -449,15 +453,15 @@ end
|
||||||
|
|
||||||
-- Redraw all drawables when the wallpaper changes
|
-- Redraw all drawables when the wallpaper changes
|
||||||
capi.awesome.connect_signal("wallpaper_changed", function()
|
capi.awesome.connect_signal("wallpaper_changed", function()
|
||||||
for k in pairs(drawables_force_complete_repaint) do
|
for d in pairs(visible_drawables) do
|
||||||
k()
|
d:_do_complete_repaint()
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Give drawables a chance to react to screen changes
|
-- Give drawables a chance to react to screen changes
|
||||||
local function draw_all()
|
local function draw_all()
|
||||||
for k in pairs(drawables_draw) do
|
for d in pairs(visible_drawables) do
|
||||||
k()
|
d:draw()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
screen.connect_signal("property::geometry", draw_all)
|
screen.connect_signal("property::geometry", draw_all)
|
||||||
|
|
Loading…
Reference in New Issue