From 1ab2633f35dcac724a7fc0b26c777b27d7d358e6 Mon Sep 17 00:00:00 2001 From: oldosfan Date: Sat, 24 Sep 2022 00:44:24 +0000 Subject: [PATCH] Update for new versions of xdg-shell * xdg-shell.xml: Update protocol definition. * xdg_popup.c (Commit, AckConfigure): Fix repositioning by adding ommitted flag. * xdg_toplevel.c (SetParent): Disallow circular parenting. --- xdg-shell.xml | 6 ++++++ xdg_popup.c | 11 +++++------ xdg_toplevel.c | 15 +++++++++++++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/xdg-shell.xml b/xdg-shell.xml index 8c9804f..993c54a 100644 --- a/xdg-shell.xml +++ b/xdg-shell.xml @@ -608,6 +608,8 @@ + @@ -628,6 +630,10 @@ the now-unmapped surface. If the now-unmapped surface has no parent, its children's parent is unset. If the now-unmapped surface becomes mapped again, its parent-child relationship is not restored. + + The parent toplevel must not be one of the child toplevel's + descendants, and the parent must be different from the child toplevel, + otherwise the invalid_parent protocol error is raised. diff --git a/xdg_popup.c b/xdg_popup.c index be1a411..e6be419 100644 --- a/xdg_popup.c +++ b/xdg_popup.c @@ -350,12 +350,7 @@ Commit (Role *role, Surface *surface, XdgRoleImplementation *impl) popup = PopupFromRoleImpl (impl); if (popup->state & StatePendingPosition) - { - popup->x = popup->pending_x; - popup->y = popup->pending_y; - - MoveWindow (popup); - } + MoveWindow (popup); popup->state &= ~StatePendingPosition; @@ -395,7 +390,11 @@ AckConfigure (Role *role, XdgRoleImplementation *impl, uint32_t serial) popup->x = popup->pending_x; popup->y = popup->pending_y; + /* The position has been acked. Clear that flag. */ popup->state &= ~StateAckPosition; + + /* Set a new flag which tells commit to move the popup. */ + popup->state |= StatePendingPosition; popup->position_serial = 0; } } diff --git a/xdg_toplevel.c b/xdg_toplevel.c index e58111e..07b37f2 100644 --- a/xdg_toplevel.c +++ b/xdg_toplevel.c @@ -1520,6 +1520,21 @@ SetParent (struct wl_client *client, struct wl_resource *resource, UpdateParent (child, NULL); else UpdateParent (child, parent); + + /* Now, verify that no circular loop has formed in the window + hierarchy. */ + + parent = child->transient_for; + for (; parent; parent = parent->transient_for) + { + /* If parent becomes child again, then we know there is a + circular reference somewhere. In that case, post a fatal + protocol error. */ + + if (child == parent) + wl_resource_post_error (resource, XDG_TOPLEVEL_ERROR_INVALID_PARENT, + "trying to set parent in a circular fashion"); + } } static void