From 5012121d331c97bc6af856dd58d68b5be336b573 Mon Sep 17 00:00:00 2001 From: Rouven Czerwinski Date: Sat, 19 Sep 2020 11:36:33 +0200 Subject: [PATCH] xwm: add loop detection for read_surface_parent Implement a simple loop detection while trying to retrieve the parent for a TRANSIENT_FOR window. Fixes swaywm/sway#4624 --- xwayland/xwm.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 87b9edc1..b3e6c885 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -467,20 +467,41 @@ static void read_surface_title(struct wlr_xwm *xwm, wlr_signal_emit_safe(&xsurface->events.set_title, xsurface); } +static bool has_parent(struct wlr_xwayland_surface *parent, + struct wlr_xwayland_surface *child) { + while (parent) { + if (child == parent) { + return true; + } + + parent = parent->parent; + } + + return false; +} + static void read_surface_parent(struct wlr_xwm *xwm, struct wlr_xwayland_surface *xsurface, xcb_get_property_reply_t *reply) { + struct wlr_xwayland_surface *found_parent = NULL; if (reply->type != XCB_ATOM_WINDOW) { return; } xcb_window_t *xid = xcb_get_property_value(reply); if (xid != NULL) { - xsurface->parent = lookup_surface(xwm, *xid); + found_parent = lookup_surface(xwm, *xid); + if (!has_parent(found_parent, xsurface)) { + xsurface->parent = found_parent; + } else { + wlr_log(WLR_INFO, "%p with %p would create a loop", xsurface, + found_parent); + } } else { xsurface->parent = NULL; } + wl_list_remove(&xsurface->parent_link); if (xsurface->parent != NULL) { wl_list_insert(&xsurface->parent->children, &xsurface->parent_link);