From ecb959f06857197f2b0cfd035189f37f88ae2c24 Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Wed, 1 Mar 2023 23:04:42 +0100 Subject: [PATCH] View: fix frame perfection on unmap --- river/XdgToplevel.zig | 10 ++++++++++ river/XwaylandView.zig | 8 +++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig index cb5a20c..cade2eb 100644 --- a/river/XdgToplevel.zig +++ b/river/XdgToplevel.zig @@ -220,7 +220,17 @@ fn handleUnmap(listener: *wl.Listener(void)) void { self.set_title.link.remove(); self.set_app_id.link.remove(); + // TODO(wlroots): This enable/disable dance is a workaround for an signal + // ordering issue with the scene xdg surface helper's unmap handler that + // disables the node. We however need the node enabled for View.unmap() + // so that we can save buffers for frame perfection. + var it = self.view.surface_tree.children.iterator(.forward); + const xdg_surface_tree_node = it.next().?; + xdg_surface_tree_node.setEnabled(true); + self.view.unmap(); + + xdg_surface_tree_node.setEnabled(false); } fn handleNewPopup(listener: *wl.Listener(*wlr.XdgPopup), wlr_xdg_popup: *wlr.XdgPopup) void { diff --git a/river/XwaylandView.zig b/river/XwaylandView.zig index 10373d5..d94393b 100644 --- a/river/XwaylandView.zig +++ b/river/XwaylandView.zig @@ -222,9 +222,6 @@ pub fn handleMap(listener: *wl.Listener(*wlr.XwaylandSurface), xwayland_surface: fn handleUnmap(listener: *wl.Listener(*wlr.XwaylandSurface), _: *wlr.XwaylandSurface) void { const self = @fieldParentPtr(Self, "unmap", listener); - self.surface_tree.?.node.destroy(); - self.surface_tree = null; - // Remove listeners that are only active while mapped self.set_title.link.remove(); self.set_class.link.remove(); @@ -232,6 +229,11 @@ fn handleUnmap(listener: *wl.Listener(*wlr.XwaylandSurface), _: *wlr.XwaylandSur self.request_minimize.link.remove(); self.view.unmap(); + + // Don't destroy the surface tree until after View.unmap() has a chance + // to save buffers for frame perfection. + self.surface_tree.?.node.destroy(); + self.surface_tree = null; } fn handleRequestConfigure(