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.
This commit is contained in:
Isaac Freund 2021-06-09 20:03:19 +00:00
parent 2e7c1dbe6a
commit 88410cc2b8
No known key found for this signature in database
GPG Key ID: 86DED400DDFD7A11
3 changed files with 13 additions and 2 deletions

View File

@ -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);
}

View File

@ -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) {

View File

@ -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();