From adf6e1f19db41dc7e722fb00da1a7a350f7275ed Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Sat, 5 Mar 2022 14:20:04 +0100 Subject: [PATCH] layer-shell: allow surfaces larger than the output The motivation for this change is to simplify the implementation and remove a massive footgun that is currently present and causing UB/crashes. If a layer surface is destroyed in arrangeLayers() then the code in LayerSurface.handleCommit() after the arrangeLayers() call accesses free'd memory. This is of course possible to fix, but it's far simpler to loosen up the protocol implementation a bit. The new implementation is also in line with what sway and the new wlroots layer shell helper do and is perfectly valid according to the protocol. --- river/Output.zig | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/river/Output.zig b/river/Output.zig index 4ec4d0d..6f7a76a 100644 --- a/river/Output.zig +++ b/river/Output.zig @@ -308,17 +308,7 @@ fn arrangeLayer( var new_box: Box = undefined; // Horizontal alignment - const horizontal_margin_size = current_state.margin.left + current_state.margin.right; - if (horizontal_margin_size + current_state.desired_width > bounds.width) { - std.log.scoped(.layer_shell).warn( - "margins of layer surface '{s}' are too large to be reasonably handled. Closing.", - .{layer_surface.wlr_layer_surface.namespace}, - ); - // This will cause the output to be rearranged, so it's fine to - // stop this attempt early. - layer_surface.wlr_layer_surface.destroy(); - return; - } else if (current_state.desired_width == 0) { + if (current_state.desired_width == 0) { assert(current_state.anchor.right and current_state.anchor.left); new_box.x = bounds.x + @intCast(i32, current_state.margin.left); new_box.width = bounds.width - (current_state.margin.left + current_state.margin.right); @@ -336,17 +326,7 @@ fn arrangeLayer( } // Vertical alignment - const vertical_margin_size = current_state.margin.bottom + current_state.margin.top; - if (vertical_margin_size + current_state.desired_height > bounds.height) { - std.log.scoped(.layer_shell).warn( - "margins of layer surface '{s}' are too large to be reasonably handled. Closing.", - .{layer_surface.wlr_layer_surface.namespace}, - ); - layer_surface.wlr_layer_surface.destroy(); - // This will cause the output to be rearranged, so it's fine to - // stop this attempt early. - return; - } else if (current_state.desired_height == 0) { + if (current_state.desired_height == 0) { assert(current_state.anchor.top and current_state.anchor.bottom); new_box.y = bounds.y + @intCast(i32, current_state.margin.top); new_box.height = bounds.height - (current_state.margin.top + current_state.margin.bottom);