mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-22 12:55:58 +01:00
xdg-toplevel: send invalid_parent error
This commit is contained in:
parent
5ba6cf517b
commit
a049d66dd7
5 changed files with 41 additions and 8 deletions
|
@ -418,9 +418,11 @@ void wlr_xdg_toplevel_send_close(struct wlr_xdg_toplevel *toplevel);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the parent of this toplevel. Parent can be NULL.
|
* Sets the parent of this toplevel. Parent can be NULL.
|
||||||
|
*
|
||||||
|
* Returns true on success, false if setting the parent would create a loop.
|
||||||
*/
|
*/
|
||||||
void wlr_xdg_toplevel_set_parent(struct wlr_xdg_toplevel *toplevel,
|
bool wlr_xdg_toplevel_set_parent(struct wlr_xdg_toplevel *toplevel,
|
||||||
struct wlr_xdg_toplevel *parent);
|
struct wlr_xdg_toplevel *parent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request that this popup closes.
|
* Request that this popup closes.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
wayland_protos = dependency('wayland-protocols',
|
wayland_protos = dependency('wayland-protocols',
|
||||||
version: '>=1.26',
|
version: '>=1.27',
|
||||||
fallback: 'wayland-protocols',
|
fallback: 'wayland-protocols',
|
||||||
default_options: ['tests=false'],
|
default_options: ['tests=false'],
|
||||||
)
|
)
|
||||||
|
|
|
@ -107,6 +107,14 @@ static void xdg_imported_handle_set_parent_of(struct wl_client *client,
|
||||||
child->xdg_surface_destroy.notify = handle_child_xdg_surface_destroy;
|
child->xdg_surface_destroy.notify = handle_child_xdg_surface_destroy;
|
||||||
child->xdg_toplevel_set_parent.notify = handle_xdg_toplevel_set_parent;
|
child->xdg_toplevel_set_parent.notify = handle_xdg_toplevel_set_parent;
|
||||||
|
|
||||||
|
if (!wlr_xdg_toplevel_set_parent(child_toplevel, surface->toplevel)) {
|
||||||
|
wl_resource_post_error(surface->toplevel->resource,
|
||||||
|
XDG_TOPLEVEL_ERROR_INVALID_PARENT,
|
||||||
|
"a toplevel cannot be a parent of itself or its ancestor");
|
||||||
|
free(child);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
wlr_xdg_toplevel_set_parent(child_toplevel, surface->toplevel);
|
wlr_xdg_toplevel_set_parent(child_toplevel, surface->toplevel);
|
||||||
wl_signal_add(&child_toplevel->base->events.destroy,
|
wl_signal_add(&child_toplevel->base->events.destroy,
|
||||||
&child->xdg_surface_destroy);
|
&child->xdg_surface_destroy);
|
||||||
|
|
|
@ -113,6 +113,14 @@ static void xdg_imported_handle_set_parent_of(struct wl_client *client,
|
||||||
child->xdg_surface_destroy.notify = handle_child_xdg_surface_destroy;
|
child->xdg_surface_destroy.notify = handle_child_xdg_surface_destroy;
|
||||||
child->xdg_toplevel_set_parent.notify = handle_xdg_toplevel_set_parent;
|
child->xdg_toplevel_set_parent.notify = handle_xdg_toplevel_set_parent;
|
||||||
|
|
||||||
|
if (!wlr_xdg_toplevel_set_parent(child_toplevel, surface->toplevel)) {
|
||||||
|
wl_resource_post_error(surface->toplevel->resource,
|
||||||
|
XDG_TOPLEVEL_ERROR_INVALID_PARENT,
|
||||||
|
"a toplevel cannot be a parent of itself or its ancestor");
|
||||||
|
free(child);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
wlr_xdg_toplevel_set_parent(child_toplevel, surface->toplevel);
|
wlr_xdg_toplevel_set_parent(child_toplevel, surface->toplevel);
|
||||||
wl_signal_add(&child_toplevel->base->events.destroy,
|
wl_signal_add(&child_toplevel->base->events.destroy,
|
||||||
&child->xdg_surface_destroy);
|
&child->xdg_surface_destroy);
|
||||||
|
|
|
@ -149,16 +149,27 @@ struct wlr_xdg_toplevel *wlr_xdg_toplevel_from_resource(
|
||||||
static void handle_parent_unmap(struct wl_listener *listener, void *data) {
|
static void handle_parent_unmap(struct wl_listener *listener, void *data) {
|
||||||
struct wlr_xdg_toplevel *toplevel =
|
struct wlr_xdg_toplevel *toplevel =
|
||||||
wl_container_of(listener, toplevel, parent_unmap);
|
wl_container_of(listener, toplevel, parent_unmap);
|
||||||
wlr_xdg_toplevel_set_parent(toplevel, toplevel->parent->parent);
|
if (!wlr_xdg_toplevel_set_parent(toplevel, toplevel->parent->parent)) {
|
||||||
|
assert(0 && "Unreachable");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wlr_xdg_toplevel_set_parent(struct wlr_xdg_toplevel *toplevel,
|
bool wlr_xdg_toplevel_set_parent(struct wlr_xdg_toplevel *toplevel,
|
||||||
struct wlr_xdg_toplevel *parent) {
|
struct wlr_xdg_toplevel *parent) {
|
||||||
if (toplevel->parent) {
|
// Check for a loop
|
||||||
|
struct wlr_xdg_toplevel *iter = parent;
|
||||||
|
while (iter != NULL) {
|
||||||
|
if (iter == toplevel) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
iter = iter->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toplevel->parent != NULL) {
|
||||||
wl_list_remove(&toplevel->parent_unmap.link);
|
wl_list_remove(&toplevel->parent_unmap.link);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent && parent->base->mapped) {
|
if (parent != NULL && parent->base->mapped) {
|
||||||
toplevel->parent = parent;
|
toplevel->parent = parent;
|
||||||
toplevel->parent_unmap.notify = handle_parent_unmap;
|
toplevel->parent_unmap.notify = handle_parent_unmap;
|
||||||
wl_signal_add(&toplevel->parent->base->events.unmap,
|
wl_signal_add(&toplevel->parent->base->events.unmap,
|
||||||
|
@ -168,6 +179,7 @@ void wlr_xdg_toplevel_set_parent(struct wlr_xdg_toplevel *toplevel,
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_signal_emit_mutable(&toplevel->events.set_parent, NULL);
|
wl_signal_emit_mutable(&toplevel->events.set_parent, NULL);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xdg_toplevel_handle_set_parent(struct wl_client *client,
|
static void xdg_toplevel_handle_set_parent(struct wl_client *client,
|
||||||
|
@ -180,7 +192,10 @@ static void xdg_toplevel_handle_set_parent(struct wl_client *client,
|
||||||
parent = wlr_xdg_toplevel_from_resource(parent_resource);
|
parent = wlr_xdg_toplevel_from_resource(parent_resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_xdg_toplevel_set_parent(toplevel, parent);
|
if (!wlr_xdg_toplevel_set_parent(toplevel, parent)) {
|
||||||
|
wl_resource_post_error(resource, XDG_TOPLEVEL_ERROR_INVALID_PARENT,
|
||||||
|
"a toplevel cannot be a parent of itself or its ancestor");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xdg_toplevel_handle_set_title(struct wl_client *client,
|
static void xdg_toplevel_handle_set_title(struct wl_client *client,
|
||||||
|
|
Loading…
Reference in a new issue