diff options
author | Rouven Czerwinski <rouven@czerwinskis.de> | 2020-09-19 11:36:33 +0200 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2020-10-08 19:32:58 +0200 |
commit | 5012121d331c97bc6af856dd58d68b5be336b573 (patch) | |
tree | 62aed3acd48adc08b8b251a03e458c972f5512fb /xwayland | |
parent | 87836dcb55e15cd1f19f5549d4fcd666135dba15 (diff) |
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
Diffstat (limited to 'xwayland')
-rw-r--r-- | xwayland/xwm.c | 23 |
1 files changed, 22 insertions, 1 deletions
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); |