From a922428c41dedea2c27f614963e7876926bba7fb Mon Sep 17 00:00:00 2001 From: Kirill Primak Date: Thu, 22 Dec 2022 13:18:47 +0300 Subject: [PATCH] xwayland/xwm: dissociate even if surface is NULL If a window is unmapped too quickly, we might receive UnmapNotify before we get the corresponding wl_surface, which will later lead to associating the same window twice. To fix this, move the NULL surface check to xwayland_surface_dissociate(), which makes resetting the unpaired link and the wl_surface object ID unconditional. Fixes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3552 --- xwayland/xwm.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/xwayland/xwm.c b/xwayland/xwm.c index b03e0b96..917aaaff 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -393,22 +393,23 @@ static void xwayland_surface_set_mapped(struct wlr_xwayland_surface *xsurface, b static void xwayland_surface_dissociate(struct wlr_xwayland_surface *xsurface) { xwayland_surface_set_mapped(xsurface, false); + if (xsurface->surface != NULL) { + wl_list_remove(&xsurface->surface_commit.link); + wl_list_remove(&xsurface->surface_precommit.link); + wlr_addon_finish(&xsurface->surface_addon); + xsurface->surface = NULL; + } + // Make sure we're not on the unpaired surface list or we // could be assigned a surface during surface creation that // was mapped before this unmap request. wl_list_remove(&xsurface->unpaired_link); wl_list_init(&xsurface->unpaired_link); - wl_list_remove(&xsurface->surface_commit.link); - wl_list_remove(&xsurface->surface_precommit.link); - wlr_addon_finish(&xsurface->surface_addon); xsurface->surface_id = 0; - xsurface->surface = NULL; } static void xwayland_surface_destroy(struct wlr_xwayland_surface *xsurface) { - if (xsurface->surface != NULL) { - xwayland_surface_dissociate(xsurface); - } + xwayland_surface_dissociate(xsurface); wl_signal_emit_mutable(&xsurface->events.destroy, xsurface); @@ -1087,9 +1088,7 @@ static void xwm_handle_unmap_notify(struct wlr_xwm *xwm, return; } - if (xsurface->surface != NULL) { - xwayland_surface_dissociate(xsurface); - } + xwayland_surface_dissociate(xsurface); xsurface_set_wm_state(xsurface, XCB_ICCCM_WM_STATE_WITHDRAWN); }