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.
This commit is contained in:
oldosfan 2022-09-24 00:44:24 +00:00
parent ab30a03d24
commit 1ab2633f35
3 changed files with 26 additions and 6 deletions

View file

@ -608,6 +608,8 @@
<enum name="error">
<entry name="invalid_resize_edge" value="0" summary="provided value is
not a valid variant of the resize_edge enum"/>
<entry name="invalid_parent" value="1"
summary="invalid parent toplevel"/>
</enum>
<request name="set_parent">
@ -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.
</description>
<arg name="parent" type="object" interface="xdg_toplevel" allow-null="true"/>
</request>

View file

@ -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;
}
}

View file

@ -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