aboutsummaryrefslogtreecommitdiff
path: root/xwayland/xwm.c
diff options
context:
space:
mode:
authorRouven Czerwinski <rouven@czerwinskis.de>2020-09-19 11:36:33 +0200
committerSimon Ser <contact@emersion.fr>2020-10-08 19:32:58 +0200
commit5012121d331c97bc6af856dd58d68b5be336b573 (patch)
tree62aed3acd48adc08b8b251a03e458c972f5512fb /xwayland/xwm.c
parent87836dcb55e15cd1f19f5549d4fcd666135dba15 (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/xwm.c')
-rw-r--r--xwayland/xwm.c23
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);