awful.layout: Apply layouts in a protected context

If an error occurs while a layout is being applied, arrange_lock could
get stuck at true, meaning that no more re-arranges will happen, thus
breaking the whole layout machinery.

Such errors could happen because the layout itself produces an error,
but also because a width is too large and c:geometry() throws an error.
Thus, this commit moves all of the actual "apply a layout"-code into a
protected context.

Fixes: https://github.com/awesomeWM/awesome/issues/1853
Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2017-06-20 09:40:31 +02:00
parent d8412cb51d
commit de05ee6678
1 changed files with 15 additions and 11 deletions

View File

@ -21,6 +21,7 @@ local client = require("awful.client")
local ascreen = require("awful.screen") local ascreen = require("awful.screen")
local timer = require("gears.timer") local timer = require("gears.timer")
local gmath = require("gears.math") local gmath = require("gears.math")
local protected_call = require("gears.protected_call")
local function get_screen(s) local function get_screen(s)
return s and capi.screen[s] return s and capi.screen[s]
@ -197,19 +198,22 @@ function layout.arrange(screen)
if arrange_lock then return end if arrange_lock then return end
arrange_lock = true arrange_lock = true
local p = layout.parameters(nil, screen) -- protected call to ensure that arrange_lock will be reset
protected_call(function()
local p = layout.parameters(nil, screen)
local useless_gap = p.useless_gap local useless_gap = p.useless_gap
p.geometries = setmetatable({}, {__mode = "k"}) p.geometries = setmetatable({}, {__mode = "k"})
layout.get(screen).arrange(p) layout.get(screen).arrange(p)
for c, g in pairs(p.geometries) do for c, g in pairs(p.geometries) do
g.width = math.max(1, g.width - c.border_width * 2 - useless_gap * 2) g.width = math.max(1, g.width - c.border_width * 2 - useless_gap * 2)
g.height = math.max(1, g.height - c.border_width * 2 - useless_gap * 2) g.height = math.max(1, g.height - c.border_width * 2 - useless_gap * 2)
g.x = g.x + useless_gap g.x = g.x + useless_gap
g.y = g.y + useless_gap g.y = g.y + useless_gap
c:geometry(g) c:geometry(g)
end end
end)
arrange_lock = false arrange_lock = false
delayed_arrange[screen] = nil delayed_arrange[screen] = nil