From 88410cc2b8947513c762abb43c4dd0c216b57d62 Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Wed, 9 Jun 2021 20:03:19 +0000 Subject: [PATCH] output: destroy Layouts on Output removal The Layout struct holds a pointer to the Output which becomes invalid when the Output is destroyed so we must ensure all the layouts of an Output are destroyed first. --- river/Layout.zig | 6 ++++++ river/Output.zig | 6 ++++-- river/Root.zig | 3 +++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/river/Layout.zig b/river/Layout.zig index 9b607ac..3682ec1 100644 --- a/river/Layout.zig +++ b/river/Layout.zig @@ -169,6 +169,10 @@ fn handleRequest(layout: *river.LayoutV2, request: river.LayoutV2.Request, self: } fn handleDestroy(layout: *river.LayoutV2, self: *Self) void { + self.destroy(); +} + +pub fn destroy(self: *Self) void { log.debug( "destroying layout '{s}' on output '{s}'", .{ self.namespace, mem.sliceTo(&self.output.wlr_output.name, 0) }, @@ -189,4 +193,6 @@ fn handleDestroy(layout: *river.LayoutV2, self: *Self) void { util.gpa.free(self.namespace); util.gpa.destroy(node); + + self.layout.setHandler(?*c_void, handleRequestInert, null, null); } diff --git a/river/Output.zig b/river/Output.zig index 38fc13e..010e6d4 100644 --- a/river/Output.zig +++ b/river/Output.zig @@ -18,6 +18,7 @@ const Self = @This(); const std = @import("std"); +const assert = std.debug.assert; const mem = std.mem; const fmt = std.fmt; const wlr = @import("wlroots"); @@ -410,8 +411,6 @@ fn arrangeLayer( } } -/// Called when the output is destroyed. Evacuate all views from the output -/// and then remove it from the list of outputs. fn handleDestroy(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) void { const self = @fieldParentPtr(Self, "destroy", listener); @@ -419,6 +418,9 @@ fn handleDestroy(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) v // Remove the destroyed output from root if it wasn't already removed server.root.removeOutput(self); + assert(self.views.first == null and self.views.last == null); + for (self.layers) |layer| assert(layer.len == 0); + assert(self.layouts.len == 0); var it = server.root.all_outputs.first; while (it) |all_node| : (it = all_node.next) { diff --git a/river/Root.zig b/river/Root.zig index 5f600e2..3d443b0 100644 --- a/river/Root.zig +++ b/river/Root.zig @@ -206,6 +206,9 @@ pub fn removeOutput(self: *Self, output: *Output) void { } } + // Destroy all layouts of the output + while (output.layouts.first) |layout_node| layout_node.data.destroy(); + // Arrange the root in case evacuated views affect the layout fallback_output.arrangeViews(); self.startTransaction();