wibox.drawable: React to screen changes

The previous commit made wibox.drawable turn a "normal redraw" into a complete
repaint when it was moved to another screen. However, nothing happened until
that normal redraw.

This commit triggers a normal redraw when we are (possibly) moved to another
screen. More precise, this means that whenever a screen appears, disappears or
changes its geometry and when the drawable is moved, we trigger a normal redraw.
This redraw will likely do nothing, because no relayout is pending and no part
of the surface needs a redraw, so it is cheap.

However, if the drawable really ends up on another screen, then the code from
the previous commits makes us do a full relayout and redraw.

This commit likely fixes the current instability of test-screen-changes.lua. See
https://github.com/awesomeWM/awesome/issues/982#issuecomment-231712056.

As explained there, the test fails because the fake screen that it created is
still referenced, so cannot be garbage collected, but the test doesn't succeed
unless the screen is garbage collected. So something is still referencing the
screen that was removed. This something can be a client's titlebar, because the
underlying drawable still has a context member referring to the old screen.

This commit should fix that problem, because we now trigger a redraw which will
compute a new context and thus the reference to the old screen is released.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2016-09-23 10:07:29 +02:00
parent 752d49ed47
commit f6761e662c
1 changed files with 23 additions and 3 deletions

View File

@ -24,7 +24,8 @@ 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 = setmetatable({}, { __mode = 'k' }) local drawables_draw = setmetatable({}, { __mode = 'k' })
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.
@ -357,9 +358,18 @@ 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[ret._do_complete_repaint] = true 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) d:connect_signal("property::surface", ret._do_complete_repaint)
-- Do a normal redraw when the drawable moves. This will likely do nothing
-- in most cases, but it makes us do a complete repaint when we are moved to
-- a different screen.
d:connect_signal("property::x", ret.draw)
d:connect_signal("property::y", ret.draw)
-- Currently we aren't redrawing on move (signals not connected). -- Currently we aren't redrawing on move (signals not connected).
-- :set_bg() will later recompute this. -- :set_bg() will later recompute this.
ret._redraw_on_move = false ret._redraw_on_move = false
@ -427,11 +437,21 @@ 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) do for k in pairs(drawables_force_complete_repaint) do
k() k()
end end
end) end)
-- Give drawables a chance to react to screen changes
local function draw_all()
for k in pairs(drawables_draw) do
k()
end
end
screen.connect_signal("property::geometry", draw_all)
screen.connect_signal("added", draw_all)
screen.connect_signal("removed", draw_all)
return setmetatable(drawable, { __call = function(_, ...) return drawable.new(...) end }) return setmetatable(drawable, { __call = function(_, ...) return drawable.new(...) end })
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80