mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05: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,8 +418,10 @@ 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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue