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