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
This commit is contained in:
parent
87836dcb55
commit
5012121d33
|
@ -467,20 +467,41 @@ static void read_surface_title(struct wlr_xwm *xwm,
|
||||||
wlr_signal_emit_safe(&xsurface->events.set_title, xsurface);
|
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,
|
static void read_surface_parent(struct wlr_xwm *xwm,
|
||||||
struct wlr_xwayland_surface *xsurface,
|
struct wlr_xwayland_surface *xsurface,
|
||||||
xcb_get_property_reply_t *reply) {
|
xcb_get_property_reply_t *reply) {
|
||||||
|
struct wlr_xwayland_surface *found_parent = NULL;
|
||||||
if (reply->type != XCB_ATOM_WINDOW) {
|
if (reply->type != XCB_ATOM_WINDOW) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_window_t *xid = xcb_get_property_value(reply);
|
xcb_window_t *xid = xcb_get_property_value(reply);
|
||||||
if (xid != NULL) {
|
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 {
|
} else {
|
||||||
xsurface->parent = NULL;
|
xsurface->parent = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
wl_list_remove(&xsurface->parent_link);
|
wl_list_remove(&xsurface->parent_link);
|
||||||
if (xsurface->parent != NULL) {
|
if (xsurface->parent != NULL) {
|
||||||
wl_list_insert(&xsurface->parent->children, &xsurface->parent_link);
|
wl_list_insert(&xsurface->parent->children, &xsurface->parent_link);
|
||||||
|
|
Loading…
Reference in New Issue