output: handle OutputDamage destroy

This may be destroyed before our output destroy listener is called.
This commit is contained in:
Isaac Freund 2021-06-14 22:17:01 +00:00
parent 20eb94317a
commit 37251c8758
No known key found for this signature in database
GPG key ID: 86DED400DDFD7A11

View file

@ -93,6 +93,7 @@ destroy: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleDestroy)
enable: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleEnable),
mode: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleMode),
frame: wl.Listener(*wlr.OutputDamage) = wl.Listener(*wlr.OutputDamage).init(handleFrame),
damage_destroy: wl.Listener(*wlr.OutputDamage) = wl.Listener(*wlr.OutputDamage).init(handleDamageDestroy),
pub fn init(self: *Self, wlr_output: *wlr.Output) !void {
assert(!wlr_output.isNoop());
@ -120,6 +121,7 @@ pub fn init(self: *Self, wlr_output: *wlr.Output) !void {
wlr_output.events.mode.add(&self.mode);
self.damage.events.frame.add(&self.frame);
self.damage.events.destroy.add(&self.damage_destroy);
// Ensure that a cursor image at the output's scale factor is loaded
// for each seat.
@ -403,6 +405,15 @@ fn arrangeLayer(
}
}
fn handleDamageDestroy(listener: *wl.Listener(*wlr.OutputDamage), wlr_output: *wlr.OutputDamage) void {
const self = @fieldParentPtr(Self, "damage_destroy", listener);
// The wlr.OutputDamage is only destroyed by wlroots when the output is
// destroyed and is never destroyed manually by river.
self.frame.link.remove();
// Ensure that it is safe to call remove() again in handleDestroy()
self.frame.link = .{ .prev = &self.frame.link, .next = &self.frame.link };
}
fn handleDestroy(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) void {
const self = @fieldParentPtr(Self, "destroy", listener);