xdg-toplevel: remove listeners before view destroy

Currently in handleUnmap() we call View.unmap() before removing
listeners. However View.unmap() may destroy the view before returning
if the transaction started doesn't have to wait on any configures.

To ensure that we don't try to remove listeners which have already been
free'd, do this before calling View.unmap().
This commit is contained in:
Isaac Freund 2021-06-17 20:57:14 +00:00
parent 5daec347c0
commit a2c81adba0
No known key found for this signature in database
GPG key ID: 86DED400DDFD7A11
3 changed files with 6 additions and 4 deletions

View file

@ -384,13 +384,12 @@ fn commitTransaction(self: *Self) void {
var view_it = output.views.first;
while (view_it) |view_node| {
const view = &view_node.view;
view_it = view_node.next;
if (view.destroying) {
view_it = view_node.next;
view.destroy();
continue;
}
defer view_it = view_node.next;
if (view.pending_serial != null and !view.shouldTrackConfigure()) continue;

View file

@ -19,6 +19,7 @@ const Self = @This();
const build_options = @import("build_options");
const std = @import("std");
const assert = std.debug.assert;
const math = std.math;
const os = std.os;
const wlr = @import("wlroots");
@ -486,7 +487,9 @@ pub fn map(self: *Self) void {
pub fn unmap(self: *Self) void {
log.debug("view '{s}' unmapped", .{self.getTitle()});
assert(!self.destroying);
self.destroying = true;
if (self.saved_buffers.items.len == 0) self.saveBuffers();
if (self.opacity_timer != null) {

View file

@ -248,8 +248,6 @@ fn handleMap(listener: *wl.Listener(*wlr.XdgSurface), xdg_surface: *wlr.XdgSurfa
fn handleUnmap(listener: *wl.Listener(*wlr.XdgSurface), xdg_surface: *wlr.XdgSurface) void {
const self = @fieldParentPtr(Self, "unmap", listener);
self.view.unmap();
// Remove listeners that are only active while mapped
self.commit.link.remove();
self.request_fullscreen.link.remove();
@ -257,6 +255,8 @@ fn handleUnmap(listener: *wl.Listener(*wlr.XdgSurface), xdg_surface: *wlr.XdgSur
self.request_resize.link.remove();
self.set_title.link.remove();
self.set_app_id.link.remove();
self.view.unmap();
}
/// Called when the surface is comitted