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:
parent
2e7c1dbe6a
commit
88410cc2b8
3 changed files with 13 additions and 2 deletions
|
@ -169,6 +169,10 @@ fn handleRequest(layout: *river.LayoutV2, request: river.LayoutV2.Request, self:
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handleDestroy(layout: *river.LayoutV2, self: *Self) void {
|
fn handleDestroy(layout: *river.LayoutV2, self: *Self) void {
|
||||||
|
self.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy(self: *Self) void {
|
||||||
log.debug(
|
log.debug(
|
||||||
"destroying layout '{s}' on output '{s}'",
|
"destroying layout '{s}' on output '{s}'",
|
||||||
.{ self.namespace, mem.sliceTo(&self.output.wlr_output.name, 0) },
|
.{ 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.free(self.namespace);
|
||||||
util.gpa.destroy(node);
|
util.gpa.destroy(node);
|
||||||
|
|
||||||
|
self.layout.setHandler(?*c_void, handleRequestInert, null, null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const assert = std.debug.assert;
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
const fmt = std.fmt;
|
const fmt = std.fmt;
|
||||||
const wlr = @import("wlroots");
|
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 {
|
fn handleDestroy(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) void {
|
||||||
const self = @fieldParentPtr(Self, "destroy", listener);
|
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
|
// Remove the destroyed output from root if it wasn't already removed
|
||||||
server.root.removeOutput(self);
|
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;
|
var it = server.root.all_outputs.first;
|
||||||
while (it) |all_node| : (it = all_node.next) {
|
while (it) |all_node| : (it = all_node.next) {
|
||||||
|
|
|
@ -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
|
// Arrange the root in case evacuated views affect the layout
|
||||||
fallback_output.arrangeViews();
|
fallback_output.arrangeViews();
|
||||||
self.startTransaction();
|
self.startTransaction();
|
||||||
|
|
Loading…
Reference in a new issue