Merge branch 'drawable-visibility' of https://github.com/psychon/awesome

This commit is contained in:
Uli Schlachter 2016-10-06 20:59:38 +02:00
commit 01a9cb2031
3 changed files with 32 additions and 16 deletions

View File

@ -282,6 +282,7 @@ local function new(c, args)
position = position position = position
} }
ret = drawable(d, context, "awful.titlebar") ret = drawable(d, context, "awful.titlebar")
ret:_inform_visible(true)
local function update_colors() local function update_colors()
local args_ = bars[position].args local args_ = bars[position].args
ret:set_bg(get_color("bg", c, args_)) ret:set_bg(get_color("bg", c, args_))
@ -298,6 +299,9 @@ local function new(c, args)
-- Update the colors when focus changes -- Update the colors when focus changes
c:connect_signal("focus", update_colors) c:connect_signal("focus", update_colors)
c:connect_signal("unfocus", update_colors) c:connect_signal("unfocus", update_colors)
-- Inform the drawable when it becomes invisible
c:connect_signal("unmanage", function() ret:_inform_visible(false) end)
else else
bars[position].args = args bars[position].args = args
ret = bars[position].drawable ret = bars[position].drawable

View File

@ -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.
@ -274,6 +273,17 @@ function drawable:set_fg(c)
self._do_complete_repaint() self._do_complete_repaint()
end end
function drawable:_inform_visible(visible)
self._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) local function emit_difference(name, list, skip)
local function in_table(table, val) local function in_table(table, val)
for _, v in pairs(table) do for _, v in pairs(table) do
@ -366,8 +376,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)
@ -407,13 +415,8 @@ function drawable.new(d, widget_context_skeleton, drawable_name)
-- Set up our callbacks for repaints -- Set up our callbacks for repaints
ret._redraw_callback = function(hierar, arg) ret._redraw_callback = function(hierar, arg)
-- XXX: lgi will lead us into memory-corruption-land when we use an -- Avoid crashes when a drawable was partly finalized and dirty_area is broken.
-- object after it was GC'd. Try to detect this situation by checking if if not ret._visible then
-- the drawable is still valid. This is only a weak indication, but it
-- seems to be the best that we can do. The problem is that the drawable
-- could not yet be GC'd, but is pending finalisation, while the
-- cairo.Region below was already GC'd. This would still lead to corruption.
if not ret.drawable.valid then
return return
end end
if ret._widget_hierarchy_callback_arg ~= arg then if ret._widget_hierarchy_callback_arg ~= arg then
@ -433,8 +436,12 @@ function drawable.new(d, widget_context_skeleton, drawable_name)
return return
end end
ret._need_relayout = true ret._need_relayout = true
-- When not visible, we will be redrawn when we become visible. In the
-- mean-time, the layout does not matter much.
if ret._visible then
ret:draw() ret:draw()
end end
end
-- Add __tostring method to metatable. -- Add __tostring method to metatable.
ret.drawable_name = drawable_name or object.modulename(3) ret.drawable_name = drawable_name or object.modulename(3)
@ -453,15 +460,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)

View File

@ -169,6 +169,11 @@ local function new(args)
ret._drawable = wibox.drawable(w.drawable, { wibox = ret }, ret._drawable = wibox.drawable(w.drawable, { wibox = ret },
"wibox drawable (" .. object.modulename(3) .. ")") "wibox drawable (" .. object.modulename(3) .. ")")
ret._drawable:_inform_visible(w.visible)
w:connect_signal("property::visible", function()
ret._drawable:_inform_visible(w.visible)
end)
for k, v in pairs(wibox) do for k, v in pairs(wibox) do
if type(v) == "function" then if type(v) == "function" then
ret[k] = v ret[k] = v