wibox.drawable: Support forced screens
Up to now, a drawable always figured out the screen that it is on by looking at its position. This causes memleak-like problems with wibars: A wibar has a screen assigned, but its underlying drawable will end up referring to another screen. Via this, we were managing to build a long reference chain of screens and drawable that meant that none of the fake screens that our test suite added could be garbage collected. To fix this, add wibox.drawable._force_screen(s). After this function is called, the normal screen detection based on the position is skipped and instead the given screen is always used. This breaks the above reference chain and things become garbage-collectable. Also, this chains the drawable to the life time of the screen: When the screen becomes invalid (.valid == false), the drawable will stop redrawing. Fixes: https://github.com/awesomeWM/awesome/issues/1237 Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
ab38876b0d
commit
4d2a1d5534
|
@ -30,14 +30,17 @@ local visible_drawables = {}
|
|||
local function get_widget_context(self)
|
||||
local geom = self.drawable:geometry()
|
||||
|
||||
local sgeos = {}
|
||||
local s = self._forced_screen
|
||||
if not s then
|
||||
local sgeos = {}
|
||||
|
||||
for s in capi.screen do
|
||||
sgeos[s] = s.geometry
|
||||
for s in capi.screen do
|
||||
sgeos[s] = s.geometry
|
||||
end
|
||||
|
||||
s = grect.get_by_coord(sgeos, geom.x, geom.y) or capi.screen.primary
|
||||
end
|
||||
|
||||
local s = grect.get_by_coord(sgeos, geom.x, geom.y) or capi.screen.primary
|
||||
|
||||
local context = self._widget_context
|
||||
local dpi = beautiful.xresources.get_dpi(s)
|
||||
if (not context) or context.screen ~= s or context.dpi ~= dpi then
|
||||
|
@ -59,6 +62,7 @@ end
|
|||
|
||||
local function do_redraw(self)
|
||||
if not self.drawable.valid then return end
|
||||
if self._forced_screen and not self._forced_screen.valid then return end
|
||||
|
||||
local surf = surface.load_silently(self.drawable.surface, false)
|
||||
-- The surface can be nil if the drawable's parent was already finalized
|
||||
|
@ -274,6 +278,10 @@ function drawable:set_fg(c)
|
|||
self._do_complete_repaint()
|
||||
end
|
||||
|
||||
function drawable:_force_screen(s)
|
||||
self._forced_screen = s
|
||||
end
|
||||
|
||||
function drawable:_inform_visible(visible)
|
||||
self._visible = visible
|
||||
if visible then
|
||||
|
|
|
@ -86,6 +86,7 @@ function wibox:set_screen(s)
|
|||
-- Remember this screen so things work correctly if screens overlap and
|
||||
-- (x,y) is not enough to figure out the correct screen.
|
||||
self.screen_assigned = s
|
||||
self._drawable:_force_screen(s)
|
||||
end
|
||||
|
||||
for _, k in pairs{ "buttons", "struts", "geometry", "get_xproperty", "set_xproperty" } do
|
||||
|
|
Loading…
Reference in New Issue