From e5d459aa0cf4b173cd37ecc7267591f544c42800 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Thu, 21 Sep 2023 18:13:44 +0200 Subject: [PATCH] Ensure xdg and xwayland string_prop() handlers deal with destroying views When a view is destroyed (including override_redirect in the xwayland case), the view_destroy() handler is called which checks for a currently open A-Tab window switcher and causes an update there to remove the destroying view from the list. Before view_destroy() is called, both xwayland and xdg handlers reset the xdg_surface / xwayland_surface. The window switcher update then creates a list of all windows which do not have the 'skipWindowSwitcher' window rule property set. If there is at least one 'matchOnce' window rule configured, this also tries to get string properties of the destroying view which already had their xdg_surface / xwayland_surface reset and thus run into an assert. This patch fixes that so that the string_prop() handlers always return an empty string in those cases rather than running into the assert. For a more in-depth analyses and alternative solutions see the linked issue. Fixes #1082 --- src/xdg.c | 14 +++++++++++++- src/xwayland.c | 13 +++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/xdg.c b/src/xdg.c index 9be6338b..5cddf44a 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -439,7 +439,19 @@ position_xdg_toplevel_view(struct view *view) static const char * xdg_toplevel_view_get_string_prop(struct view *view, const char *prop) { - struct wlr_xdg_toplevel *xdg_toplevel = xdg_toplevel_from_view(view); + struct xdg_toplevel_view *xdg_view = xdg_toplevel_view_from_view(view); + struct wlr_xdg_toplevel *xdg_toplevel = xdg_view->xdg_surface + ? xdg_view->xdg_surface->toplevel + : NULL; + if (!xdg_toplevel) { + /* + * This may happen due to a matchOnce rule when + * a view is destroyed while A-Tab is open. See + * https://github.com/labwc/labwc/issues/1082#issuecomment-1716137180 + */ + return ""; + } + if (!strcmp(prop, "title")) { return xdg_toplevel->title; } diff --git a/src/xwayland.c b/src/xwayland.c index b00119c6..ae405311 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -355,8 +355,17 @@ xwayland_view_close(struct view *view) static const char * xwayland_view_get_string_prop(struct view *view, const char *prop) { - struct wlr_xwayland_surface *xwayland_surface = - xwayland_surface_from_view(view); + struct xwayland_view *xwayland_view = xwayland_view_from_view(view); + struct wlr_xwayland_surface *xwayland_surface = xwayland_view->xwayland_surface; + if (!xwayland_surface) { + /* + * This may happen due to a matchOnce rule when + * a view is destroyed while A-Tab is open. See + * https://github.com/labwc/labwc/issues/1082#issuecomment-1716137180 + */ + return ""; + } + if (!strcmp(prop, "title")) { return xwayland_surface->title; }