mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-10-29 05:40:12 -04:00 
			
		
		
		
	xdg-{shell,decoration}: improve events
This commit changes the behavior of `new_*` signals to better match their names (see https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3608). wlr_xdg_shell.events.new_surface is now emitted when an xdg_surface is created, and wlr_xdg_shell.events.new_{toplevel,popup} events are introduced to get notified when an xdg_{toplevel,popup} is created. Same applies to `wlr_xdg_decoration_manager_v1.events.new_toplevel_decoration`. As a result, wlr_xdg_surface.added and wlr_xdg_toplevel_decoration_v1.added are removed, as we no longer need to track whether the corresponding event was emitted. Additionally, this commit changes the behavior of wlr_xdg_surface.events.destroy: it is now emitted when the xdg_surface is destroyed, as the name suggests. wlr_xdg_{toplevel,popup}.events.destroy events are added to get notified when an xdg_{toplevel,popup} is destroyed.
This commit is contained in:
		
							parent
							
								
									d61ec694b3
								
							
						
					
					
						commit
						c85838892d
					
				
					 12 changed files with 107 additions and 134 deletions
				
			
		|  | @ -45,8 +45,6 @@ struct wlr_xdg_toplevel_decoration_v1 { | ||||||
| 	enum wlr_xdg_toplevel_decoration_v1_mode scheduled_mode; | 	enum wlr_xdg_toplevel_decoration_v1_mode scheduled_mode; | ||||||
| 	enum wlr_xdg_toplevel_decoration_v1_mode requested_mode; | 	enum wlr_xdg_toplevel_decoration_v1_mode requested_mode; | ||||||
| 
 | 
 | ||||||
| 	bool added; |  | ||||||
| 
 |  | ||||||
| 	struct wl_list configure_list; // wlr_xdg_toplevel_decoration_v1_configure.link
 | 	struct wl_list configure_list; // wlr_xdg_toplevel_decoration_v1_configure.link
 | ||||||
| 
 | 
 | ||||||
| 	struct { | 	struct { | ||||||
|  | @ -54,7 +52,7 @@ struct wlr_xdg_toplevel_decoration_v1 { | ||||||
| 		struct wl_signal request_mode; | 		struct wl_signal request_mode; | ||||||
| 	} events; | 	} events; | ||||||
| 
 | 
 | ||||||
| 	struct wl_listener surface_destroy; | 	struct wl_listener toplevel_destroy; | ||||||
| 	struct wl_listener surface_configure; | 	struct wl_listener surface_configure; | ||||||
| 	struct wl_listener surface_ack_configure; | 	struct wl_listener surface_ack_configure; | ||||||
| 	struct wl_listener surface_commit; | 	struct wl_listener surface_commit; | ||||||
|  |  | ||||||
|  | @ -34,7 +34,7 @@ struct wlr_xdg_exported_v1 { | ||||||
| 	struct wlr_xdg_foreign_exported base; | 	struct wlr_xdg_foreign_exported base; | ||||||
| 
 | 
 | ||||||
| 	struct wl_resource *resource; | 	struct wl_resource *resource; | ||||||
| 	struct wl_listener xdg_surface_destroy; | 	struct wl_listener xdg_toplevel_destroy; | ||||||
| 
 | 
 | ||||||
| 	struct wl_list link; // wlr_xdg_foreign_v1.exporter.objects
 | 	struct wl_list link; // wlr_xdg_foreign_v1.exporter.objects
 | ||||||
| }; | }; | ||||||
|  | @ -54,7 +54,7 @@ struct wlr_xdg_imported_child_v1 { | ||||||
| 
 | 
 | ||||||
| 	struct wl_list link; // wlr_xdg_imported_v1.children
 | 	struct wl_list link; // wlr_xdg_imported_v1.children
 | ||||||
| 
 | 
 | ||||||
| 	struct wl_listener xdg_surface_destroy; | 	struct wl_listener xdg_toplevel_destroy; | ||||||
| 	struct wl_listener xdg_toplevel_set_parent; | 	struct wl_listener xdg_toplevel_set_parent; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -34,7 +34,7 @@ struct wlr_xdg_exported_v2 { | ||||||
| 	struct wlr_xdg_foreign_exported base; | 	struct wlr_xdg_foreign_exported base; | ||||||
| 
 | 
 | ||||||
| 	struct wl_resource *resource; | 	struct wl_resource *resource; | ||||||
| 	struct wl_listener xdg_surface_destroy; | 	struct wl_listener xdg_toplevel_destroy; | ||||||
| 
 | 
 | ||||||
| 	struct wl_list link; // wlr_xdg_foreign_v2.exporter.objects
 | 	struct wl_list link; // wlr_xdg_foreign_v2.exporter.objects
 | ||||||
| }; | }; | ||||||
|  | @ -54,7 +54,7 @@ struct wlr_xdg_imported_child_v2 { | ||||||
| 
 | 
 | ||||||
| 	struct wl_list link; // wlr_xdg_imported_v2.children
 | 	struct wl_list link; // wlr_xdg_imported_v2.children
 | ||||||
| 
 | 
 | ||||||
| 	struct wl_listener xdg_surface_destroy; | 	struct wl_listener xdg_toplevel_destroy; | ||||||
| 	struct wl_listener xdg_toplevel_set_parent; | 	struct wl_listener xdg_toplevel_set_parent; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -26,6 +26,8 @@ struct wlr_xdg_shell { | ||||||
| 
 | 
 | ||||||
| 	struct { | 	struct { | ||||||
| 		struct wl_signal new_surface; // struct wlr_xdg_surface
 | 		struct wl_signal new_surface; // struct wlr_xdg_surface
 | ||||||
|  | 		struct wl_signal new_toplevel; // struct wlr_xdg_toplevel
 | ||||||
|  | 		struct wl_signal new_popup; // struct wlr_xdg_popup
 | ||||||
| 		struct wl_signal destroy; | 		struct wl_signal destroy; | ||||||
| 	} events; | 	} events; | ||||||
| 
 | 
 | ||||||
|  | @ -102,6 +104,8 @@ struct wlr_xdg_popup { | ||||||
| 	struct wlr_xdg_popup_state current, pending; | 	struct wlr_xdg_popup_state current, pending; | ||||||
| 
 | 
 | ||||||
| 	struct { | 	struct { | ||||||
|  | 		struct wl_signal destroy; | ||||||
|  | 
 | ||||||
| 		struct wl_signal reposition; | 		struct wl_signal reposition; | ||||||
| 	} events; | 	} events; | ||||||
| 
 | 
 | ||||||
|  | @ -184,6 +188,8 @@ struct wlr_xdg_toplevel { | ||||||
| 	char *app_id; | 	char *app_id; | ||||||
| 
 | 
 | ||||||
| 	struct { | 	struct { | ||||||
|  | 		struct wl_signal destroy; | ||||||
|  | 
 | ||||||
| 		// Note: as per xdg-shell protocol, the compositor has to
 | 		// Note: as per xdg-shell protocol, the compositor has to
 | ||||||
| 		// handle state requests by sending a configure event,
 | 		// handle state requests by sending a configure event,
 | ||||||
| 		// even if it didn't actually change the state. Therefore,
 | 		// even if it didn't actually change the state. Therefore,
 | ||||||
|  | @ -249,7 +255,7 @@ struct wlr_xdg_surface { | ||||||
| 
 | 
 | ||||||
| 	struct wl_list popups; // wlr_xdg_popup.link
 | 	struct wl_list popups; // wlr_xdg_popup.link
 | ||||||
| 
 | 
 | ||||||
| 	bool added, configured; | 	bool configured; | ||||||
| 	struct wl_event_source *configure_idle; | 	struct wl_event_source *configure_idle; | ||||||
| 	uint32_t scheduled_serial; | 	uint32_t scheduled_serial; | ||||||
| 	struct wl_list configure_list; | 	struct wl_list configure_list; | ||||||
|  |  | ||||||
|  | @ -42,7 +42,8 @@ struct tinywl_server { | ||||||
| 	struct wlr_scene_output_layout *scene_layout; | 	struct wlr_scene_output_layout *scene_layout; | ||||||
| 
 | 
 | ||||||
| 	struct wlr_xdg_shell *xdg_shell; | 	struct wlr_xdg_shell *xdg_shell; | ||||||
| 	struct wl_listener new_xdg_surface; | 	struct wl_listener new_xdg_toplevel; | ||||||
|  | 	struct wl_listener new_xdg_popup; | ||||||
| 	struct wl_list toplevels; | 	struct wl_list toplevels; | ||||||
| 
 | 
 | ||||||
| 	struct wlr_cursor *cursor; | 	struct wlr_cursor *cursor; | ||||||
|  | @ -767,58 +768,53 @@ static void xdg_toplevel_request_fullscreen( | ||||||
| 	wlr_xdg_surface_schedule_configure(toplevel->xdg_toplevel->base); | 	wlr_xdg_surface_schedule_configure(toplevel->xdg_toplevel->base); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void server_new_xdg_surface(struct wl_listener *listener, void *data) { | static void server_new_xdg_toplevel(struct wl_listener *listener, void *data) { | ||||||
| 	/* This event is raised when wlr_xdg_shell receives a new xdg surface from a
 | 	/* This event is raised when a client creates a new toplevel (application window). */ | ||||||
| 	 * client, either a toplevel (application window) or popup. */ | 	struct tinywl_server *server = wl_container_of(listener, server, new_xdg_toplevel); | ||||||
| 	struct tinywl_server *server = | 	struct wlr_xdg_toplevel *xdg_toplevel = data; | ||||||
| 		wl_container_of(listener, server, new_xdg_surface); | 
 | ||||||
| 	struct wlr_xdg_surface *xdg_surface = data; | 	/* Allocate a tinywl_toplevel for this surface */ | ||||||
|  | 	struct tinywl_toplevel *toplevel = calloc(1, sizeof(*toplevel)); | ||||||
|  | 	toplevel->server = server; | ||||||
|  | 	toplevel->xdg_toplevel = xdg_toplevel; | ||||||
|  | 	toplevel->scene_tree = | ||||||
|  | 		wlr_scene_xdg_surface_create(&toplevel->server->scene->tree, xdg_toplevel->base); | ||||||
|  | 	toplevel->scene_tree->node.data = toplevel; | ||||||
|  | 	xdg_toplevel->base->data = toplevel->scene_tree; | ||||||
|  | 
 | ||||||
|  | 	/* Listen to the various events it can emit */ | ||||||
|  | 	toplevel->map.notify = xdg_toplevel_map; | ||||||
|  | 	wl_signal_add(&xdg_toplevel->base->surface->events.map, &toplevel->map); | ||||||
|  | 	toplevel->unmap.notify = xdg_toplevel_unmap; | ||||||
|  | 	wl_signal_add(&xdg_toplevel->base->surface->events.unmap, &toplevel->unmap); | ||||||
|  | 
 | ||||||
|  | 	toplevel->destroy.notify = xdg_toplevel_destroy; | ||||||
|  | 	wl_signal_add(&xdg_toplevel->events.destroy, &toplevel->destroy); | ||||||
|  | 
 | ||||||
|  | 	/* cotd */ | ||||||
|  | 	toplevel->request_move.notify = xdg_toplevel_request_move; | ||||||
|  | 	wl_signal_add(&xdg_toplevel->events.request_move, &toplevel->request_move); | ||||||
|  | 	toplevel->request_resize.notify = xdg_toplevel_request_resize; | ||||||
|  | 	wl_signal_add(&xdg_toplevel->events.request_resize, &toplevel->request_resize); | ||||||
|  | 	toplevel->request_maximize.notify = xdg_toplevel_request_maximize; | ||||||
|  | 	wl_signal_add(&xdg_toplevel->events.request_maximize, &toplevel->request_maximize); | ||||||
|  | 	toplevel->request_fullscreen.notify = xdg_toplevel_request_fullscreen; | ||||||
|  | 	wl_signal_add(&xdg_toplevel->events.request_fullscreen, &toplevel->request_fullscreen); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void server_new_xdg_popup(struct wl_listener *listener, void *data) { | ||||||
|  | 	/* This event is raised when a client creates a new popup. */ | ||||||
|  | 	struct wlr_xdg_popup *xdg_popup = data; | ||||||
| 
 | 
 | ||||||
| 	/* We must add xdg popups to the scene graph so they get rendered. The
 | 	/* We must add xdg popups to the scene graph so they get rendered. The
 | ||||||
| 	 * wlroots scene graph provides a helper for this, but to use it we must | 	 * wlroots scene graph provides a helper for this, but to use it we must | ||||||
| 	 * provide the proper parent scene node of the xdg popup. To enable this, | 	 * provide the proper parent scene node of the xdg popup. To enable this, | ||||||
| 	 * we always set the user data field of xdg_surfaces to the corresponding | 	 * we always set the user data field of xdg_surfaces to the corresponding | ||||||
| 	 * scene node. */ | 	 * scene node. */ | ||||||
| 	if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { | 	struct wlr_xdg_surface *parent = wlr_xdg_surface_try_from_wlr_surface(xdg_popup->parent); | ||||||
| 		struct wlr_xdg_surface *parent = | 	assert(parent != NULL); | ||||||
| 			wlr_xdg_surface_try_from_wlr_surface(xdg_surface->popup->parent); | 	struct wlr_scene_tree *parent_tree = parent->data; | ||||||
| 		assert(parent != NULL); | 	xdg_popup->base->data = wlr_scene_xdg_surface_create(parent_tree, xdg_popup->base); | ||||||
| 		struct wlr_scene_tree *parent_tree = parent->data; |  | ||||||
| 		xdg_surface->data = wlr_scene_xdg_surface_create( |  | ||||||
| 			parent_tree, xdg_surface); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
| 	assert(xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL); |  | ||||||
| 
 |  | ||||||
| 	/* Allocate a tinywl_toplevel for this surface */ |  | ||||||
| 	struct tinywl_toplevel *toplevel = calloc(1, sizeof(*toplevel)); |  | ||||||
| 	toplevel->server = server; |  | ||||||
| 	toplevel->xdg_toplevel = xdg_surface->toplevel; |  | ||||||
| 	toplevel->scene_tree = wlr_scene_xdg_surface_create( |  | ||||||
| 			&toplevel->server->scene->tree, toplevel->xdg_toplevel->base); |  | ||||||
| 	toplevel->scene_tree->node.data = toplevel; |  | ||||||
| 	xdg_surface->data = toplevel->scene_tree; |  | ||||||
| 
 |  | ||||||
| 	/* Listen to the various events it can emit */ |  | ||||||
| 	toplevel->map.notify = xdg_toplevel_map; |  | ||||||
| 	wl_signal_add(&xdg_surface->surface->events.map, &toplevel->map); |  | ||||||
| 	toplevel->unmap.notify = xdg_toplevel_unmap; |  | ||||||
| 	wl_signal_add(&xdg_surface->surface->events.unmap, &toplevel->unmap); |  | ||||||
| 	toplevel->destroy.notify = xdg_toplevel_destroy; |  | ||||||
| 	wl_signal_add(&xdg_surface->events.destroy, &toplevel->destroy); |  | ||||||
| 
 |  | ||||||
| 	/* cotd */ |  | ||||||
| 	struct wlr_xdg_toplevel *xdg_toplevel = xdg_surface->toplevel; |  | ||||||
| 	toplevel->request_move.notify = xdg_toplevel_request_move; |  | ||||||
| 	wl_signal_add(&xdg_toplevel->events.request_move, &toplevel->request_move); |  | ||||||
| 	toplevel->request_resize.notify = xdg_toplevel_request_resize; |  | ||||||
| 	wl_signal_add(&xdg_toplevel->events.request_resize, &toplevel->request_resize); |  | ||||||
| 	toplevel->request_maximize.notify = xdg_toplevel_request_maximize; |  | ||||||
| 	wl_signal_add(&xdg_toplevel->events.request_maximize, |  | ||||||
| 		&toplevel->request_maximize); |  | ||||||
| 	toplevel->request_fullscreen.notify = xdg_toplevel_request_fullscreen; |  | ||||||
| 	wl_signal_add(&xdg_toplevel->events.request_fullscreen, |  | ||||||
| 		&toplevel->request_fullscreen); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int main(int argc, char *argv[]) { | int main(int argc, char *argv[]) { | ||||||
|  | @ -914,9 +910,10 @@ int main(int argc, char *argv[]) { | ||||||
| 	 */ | 	 */ | ||||||
| 	wl_list_init(&server.toplevels); | 	wl_list_init(&server.toplevels); | ||||||
| 	server.xdg_shell = wlr_xdg_shell_create(server.wl_display, 3); | 	server.xdg_shell = wlr_xdg_shell_create(server.wl_display, 3); | ||||||
| 	server.new_xdg_surface.notify = server_new_xdg_surface; | 	server.new_xdg_toplevel.notify = server_new_xdg_toplevel; | ||||||
| 	wl_signal_add(&server.xdg_shell->events.new_surface, | 	wl_signal_add(&server.xdg_shell->events.new_toplevel, &server.new_xdg_toplevel); | ||||||
| 			&server.new_xdg_surface); | 	server.new_xdg_popup.notify = server_new_xdg_popup; | ||||||
|  | 	wl_signal_add(&server.xdg_shell->events.new_popup, &server.new_xdg_popup); | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Creates a cursor, which is a wlroots utility for tracking the cursor | 	 * Creates a cursor, which is a wlroots utility for tracking the cursor | ||||||
|  |  | ||||||
|  | @ -63,7 +63,7 @@ static void toplevel_decoration_handle_resource_destroy( | ||||||
| 		toplevel_decoration_from_resource(resource); | 		toplevel_decoration_from_resource(resource); | ||||||
| 	wl_signal_emit_mutable(&decoration->events.destroy, decoration); | 	wl_signal_emit_mutable(&decoration->events.destroy, decoration); | ||||||
| 	wl_list_remove(&decoration->surface_commit.link); | 	wl_list_remove(&decoration->surface_commit.link); | ||||||
| 	wl_list_remove(&decoration->surface_destroy.link); | 	wl_list_remove(&decoration->toplevel_destroy.link); | ||||||
| 	wl_list_remove(&decoration->surface_configure.link); | 	wl_list_remove(&decoration->surface_configure.link); | ||||||
| 	wl_list_remove(&decoration->surface_ack_configure.link); | 	wl_list_remove(&decoration->surface_ack_configure.link); | ||||||
| 	struct wlr_xdg_toplevel_decoration_v1_configure *configure, *tmp; | 	struct wlr_xdg_toplevel_decoration_v1_configure *configure, *tmp; | ||||||
|  | @ -74,10 +74,10 @@ static void toplevel_decoration_handle_resource_destroy( | ||||||
| 	free(decoration); | 	free(decoration); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void toplevel_decoration_handle_surface_destroy( | static void toplevel_decoration_handle_toplevel_destroy( | ||||||
| 		struct wl_listener *listener, void *data) { | 		struct wl_listener *listener, void *data) { | ||||||
| 	struct wlr_xdg_toplevel_decoration_v1 *decoration = | 	struct wlr_xdg_toplevel_decoration_v1 *decoration = | ||||||
| 		wl_container_of(listener, decoration, surface_destroy); | 		wl_container_of(listener, decoration, toplevel_destroy); | ||||||
| 
 | 
 | ||||||
| 	wl_resource_post_error(decoration->resource, | 	wl_resource_post_error(decoration->resource, | ||||||
| 		ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ORPHANED, | 		ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ORPHANED, | ||||||
|  | @ -145,15 +145,8 @@ static void toplevel_decoration_handle_surface_commit( | ||||||
| 		struct wl_listener *listener, void *data) { | 		struct wl_listener *listener, void *data) { | ||||||
| 	struct wlr_xdg_toplevel_decoration_v1 *decoration = | 	struct wlr_xdg_toplevel_decoration_v1 *decoration = | ||||||
| 		wl_container_of(listener, decoration, surface_commit); | 		wl_container_of(listener, decoration, surface_commit); | ||||||
| 	struct wlr_xdg_decoration_manager_v1 *manager = decoration->manager; |  | ||||||
| 
 | 
 | ||||||
| 	decoration->current = decoration->pending; | 	decoration->current = decoration->pending; | ||||||
| 
 |  | ||||||
| 	if (decoration->toplevel->base->added && !decoration->added) { |  | ||||||
| 		decoration->added = true; |  | ||||||
| 		wl_signal_emit_mutable(&manager->events.new_toplevel_decoration, |  | ||||||
| 			decoration); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const struct zxdg_decoration_manager_v1_interface decoration_manager_impl; | static const struct zxdg_decoration_manager_v1_interface decoration_manager_impl; | ||||||
|  | @ -223,30 +216,18 @@ static void decoration_manager_handle_get_toplevel_decoration( | ||||||
| 	wl_signal_init(&decoration->events.destroy); | 	wl_signal_init(&decoration->events.destroy); | ||||||
| 	wl_signal_init(&decoration->events.request_mode); | 	wl_signal_init(&decoration->events.request_mode); | ||||||
| 
 | 
 | ||||||
| 	wl_signal_add(&toplevel->base->events.destroy, | 	wl_signal_add(&toplevel->events.destroy, &decoration->toplevel_destroy); | ||||||
| 		&decoration->surface_destroy); | 	decoration->toplevel_destroy.notify = toplevel_decoration_handle_toplevel_destroy; | ||||||
| 	decoration->surface_destroy.notify = | 	wl_signal_add(&toplevel->base->events.configure, &decoration->surface_configure); | ||||||
| 		toplevel_decoration_handle_surface_destroy; | 	decoration->surface_configure.notify = toplevel_decoration_handle_surface_configure; | ||||||
| 	wl_signal_add(&toplevel->base->events.configure, | 	wl_signal_add(&toplevel->base->events.ack_configure, &decoration->surface_ack_configure); | ||||||
| 		&decoration->surface_configure); | 	decoration->surface_ack_configure.notify = toplevel_decoration_handle_surface_ack_configure; | ||||||
| 	decoration->surface_configure.notify = | 	wl_signal_add(&toplevel->base->surface->events.commit, &decoration->surface_commit); | ||||||
| 		toplevel_decoration_handle_surface_configure; | 	decoration->surface_commit.notify = toplevel_decoration_handle_surface_commit; | ||||||
| 	wl_signal_add(&toplevel->base->events.ack_configure, |  | ||||||
| 		&decoration->surface_ack_configure); |  | ||||||
| 	decoration->surface_ack_configure.notify = |  | ||||||
| 		toplevel_decoration_handle_surface_ack_configure; |  | ||||||
| 	wl_signal_add(&toplevel->base->surface->events.commit, |  | ||||||
| 		&decoration->surface_commit); |  | ||||||
| 	decoration->surface_commit.notify = |  | ||||||
| 		toplevel_decoration_handle_surface_commit; |  | ||||||
| 
 | 
 | ||||||
| 	wl_list_insert(&manager->decorations, &decoration->link); | 	wl_list_insert(&manager->decorations, &decoration->link); | ||||||
| 
 | 
 | ||||||
| 	if (toplevel->base->added) { | 	wl_signal_emit_mutable(&manager->events.new_toplevel_decoration, decoration); | ||||||
| 		decoration->added = true; |  | ||||||
| 		wl_signal_emit_mutable(&manager->events.new_toplevel_decoration, |  | ||||||
| 			decoration); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const struct zxdg_decoration_manager_v1_interface | static const struct zxdg_decoration_manager_v1_interface | ||||||
|  |  | ||||||
|  | @ -40,15 +40,15 @@ static struct wlr_xdg_toplevel *verify_is_toplevel(struct wl_resource *resource, | ||||||
| 
 | 
 | ||||||
| static void destroy_imported_child(struct wlr_xdg_imported_child_v1 *child) { | static void destroy_imported_child(struct wlr_xdg_imported_child_v1 *child) { | ||||||
| 	wl_list_remove(&child->xdg_toplevel_set_parent.link); | 	wl_list_remove(&child->xdg_toplevel_set_parent.link); | ||||||
| 	wl_list_remove(&child->xdg_surface_destroy.link); | 	wl_list_remove(&child->xdg_toplevel_destroy.link); | ||||||
| 	wl_list_remove(&child->link); | 	wl_list_remove(&child->link); | ||||||
| 	free(child); | 	free(child); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void handle_child_xdg_surface_destroy( | static void handle_child_xdg_toplevel_destroy( | ||||||
| 		struct wl_listener *listener, void *data) { | 		struct wl_listener *listener, void *data) { | ||||||
| 	struct wlr_xdg_imported_child_v1 *child = | 	struct wlr_xdg_imported_child_v1 *child = | ||||||
| 		wl_container_of(listener, child, xdg_surface_destroy); | 		wl_container_of(listener, child, xdg_toplevel_destroy); | ||||||
| 	destroy_imported_child(child); | 	destroy_imported_child(child); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -98,7 +98,7 @@ static void xdg_imported_handle_set_parent_of(struct wl_client *client, | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 	child->surface = wlr_surface_child; | 	child->surface = wlr_surface_child; | ||||||
| 	child->xdg_surface_destroy.notify = handle_child_xdg_surface_destroy; | 	child->xdg_toplevel_destroy.notify = handle_child_xdg_toplevel_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)) { | 	if (!wlr_xdg_toplevel_set_parent(child_toplevel, surface->toplevel)) { | ||||||
|  | @ -110,10 +110,8 @@ static void xdg_imported_handle_set_parent_of(struct wl_client *client, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	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->events.destroy, &child->xdg_toplevel_destroy); | ||||||
| 			&child->xdg_surface_destroy); | 	wl_signal_add(&child_toplevel->events.set_parent, &child->xdg_toplevel_set_parent); | ||||||
| 	wl_signal_add(&child_toplevel->events.set_parent, |  | ||||||
| 			&child->xdg_toplevel_set_parent); |  | ||||||
| 
 | 
 | ||||||
| 	wl_list_insert(&imported->children, &child->link); | 	wl_list_insert(&imported->children, &child->link); | ||||||
| } | } | ||||||
|  | @ -173,7 +171,7 @@ static void destroy_imported(struct wlr_xdg_imported_v1 *imported) { | ||||||
| static void destroy_exported(struct wlr_xdg_exported_v1 *exported) { | static void destroy_exported(struct wlr_xdg_exported_v1 *exported) { | ||||||
| 	wlr_xdg_foreign_exported_finish(&exported->base); | 	wlr_xdg_foreign_exported_finish(&exported->base); | ||||||
| 
 | 
 | ||||||
| 	wl_list_remove(&exported->xdg_surface_destroy.link); | 	wl_list_remove(&exported->xdg_toplevel_destroy.link); | ||||||
| 	wl_list_remove(&exported->link); | 	wl_list_remove(&exported->link); | ||||||
| 	wl_resource_set_user_data(exported->resource, NULL); | 	wl_resource_set_user_data(exported->resource, NULL); | ||||||
| 	free(exported); | 	free(exported); | ||||||
|  | @ -189,10 +187,9 @@ static void xdg_exported_handle_resource_destroy( | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void handle_xdg_surface_destroy( | static void handle_xdg_toplevel_destroy(struct wl_listener *listener, void *data) { | ||||||
| 		struct wl_listener *listener, void *data) { |  | ||||||
| 	struct wlr_xdg_exported_v1 *exported = | 	struct wlr_xdg_exported_v1 *exported = | ||||||
| 		wl_container_of(listener, exported, xdg_surface_destroy); | 		wl_container_of(listener, exported, xdg_toplevel_destroy); | ||||||
| 
 | 
 | ||||||
| 	destroy_exported(exported); | 	destroy_exported(exported); | ||||||
| } | } | ||||||
|  | @ -240,8 +237,8 @@ static void xdg_exporter_handle_export(struct wl_client *wl_client, | ||||||
| 
 | 
 | ||||||
| 	zxdg_exported_v1_send_handle(exported->resource, exported->base.handle); | 	zxdg_exported_v1_send_handle(exported->resource, exported->base.handle); | ||||||
| 
 | 
 | ||||||
| 	exported->xdg_surface_destroy.notify = handle_xdg_surface_destroy; | 	exported->xdg_toplevel_destroy.notify = handle_xdg_toplevel_destroy; | ||||||
| 	wl_signal_add(&xdg_toplevel->base->events.destroy, &exported->xdg_surface_destroy); | 	wl_signal_add(&xdg_toplevel->base->events.destroy, &exported->xdg_toplevel_destroy); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const struct zxdg_exporter_v1_interface xdg_exporter_impl = { | static const struct zxdg_exporter_v1_interface xdg_exporter_impl = { | ||||||
|  |  | ||||||
|  | @ -45,15 +45,15 @@ static struct wlr_xdg_toplevel *verify_is_toplevel(struct wl_resource *resource, | ||||||
| 
 | 
 | ||||||
| static void destroy_imported_child(struct wlr_xdg_imported_child_v2 *child) { | static void destroy_imported_child(struct wlr_xdg_imported_child_v2 *child) { | ||||||
| 	wl_list_remove(&child->xdg_toplevel_set_parent.link); | 	wl_list_remove(&child->xdg_toplevel_set_parent.link); | ||||||
| 	wl_list_remove(&child->xdg_surface_destroy.link); | 	wl_list_remove(&child->xdg_toplevel_destroy.link); | ||||||
| 	wl_list_remove(&child->link); | 	wl_list_remove(&child->link); | ||||||
| 	free(child); | 	free(child); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void handle_child_xdg_surface_destroy( | static void handle_child_xdg_toplevel_destroy( | ||||||
| 		struct wl_listener *listener, void *data) { | 		struct wl_listener *listener, void *data) { | ||||||
| 	struct wlr_xdg_imported_child_v2 *child = | 	struct wlr_xdg_imported_child_v2 *child = | ||||||
| 		wl_container_of(listener, child, xdg_surface_destroy); | 		wl_container_of(listener, child, xdg_toplevel_destroy); | ||||||
| 	destroy_imported_child(child); | 	destroy_imported_child(child); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -101,7 +101,7 @@ static void xdg_imported_handle_set_parent_of(struct wl_client *client, | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 	child->surface = wlr_surface_child; | 	child->surface = wlr_surface_child; | ||||||
| 	child->xdg_surface_destroy.notify = handle_child_xdg_surface_destroy; | 	child->xdg_toplevel_destroy.notify = handle_child_xdg_toplevel_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)) { | 	if (!wlr_xdg_toplevel_set_parent(child_toplevel, surface->toplevel)) { | ||||||
|  | @ -113,10 +113,8 @@ static void xdg_imported_handle_set_parent_of(struct wl_client *client, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	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->events.destroy, &child->xdg_toplevel_destroy); | ||||||
| 			&child->xdg_surface_destroy); | 	wl_signal_add(&child_toplevel->events.set_parent, &child->xdg_toplevel_set_parent); | ||||||
| 	wl_signal_add(&child_toplevel->events.set_parent, |  | ||||||
| 			&child->xdg_toplevel_set_parent); |  | ||||||
| 
 | 
 | ||||||
| 	wl_list_insert(&imported->children, &child->link); | 	wl_list_insert(&imported->children, &child->link); | ||||||
| } | } | ||||||
|  | @ -176,7 +174,7 @@ static void destroy_imported(struct wlr_xdg_imported_v2 *imported) { | ||||||
| static void destroy_exported(struct wlr_xdg_exported_v2 *exported) { | static void destroy_exported(struct wlr_xdg_exported_v2 *exported) { | ||||||
| 	wlr_xdg_foreign_exported_finish(&exported->base); | 	wlr_xdg_foreign_exported_finish(&exported->base); | ||||||
| 
 | 
 | ||||||
| 	wl_list_remove(&exported->xdg_surface_destroy.link); | 	wl_list_remove(&exported->xdg_toplevel_destroy.link); | ||||||
| 	wl_list_remove(&exported->link); | 	wl_list_remove(&exported->link); | ||||||
| 	wl_resource_set_user_data(exported->resource, NULL); | 	wl_resource_set_user_data(exported->resource, NULL); | ||||||
| 	free(exported); | 	free(exported); | ||||||
|  | @ -192,10 +190,9 @@ static void xdg_exported_handle_resource_destroy( | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void handle_xdg_surface_destroy( | static void handle_xdg_toplevel_destroy(struct wl_listener *listener, void *data) { | ||||||
| 		struct wl_listener *listener, void *data) { |  | ||||||
| 	struct wlr_xdg_exported_v2 *exported = | 	struct wlr_xdg_exported_v2 *exported = | ||||||
| 		wl_container_of(listener, exported, xdg_surface_destroy); | 		wl_container_of(listener, exported, xdg_toplevel_destroy); | ||||||
| 
 | 
 | ||||||
| 	destroy_exported(exported); | 	destroy_exported(exported); | ||||||
| } | } | ||||||
|  | @ -243,8 +240,8 @@ static void xdg_exporter_handle_export(struct wl_client *wl_client, | ||||||
| 
 | 
 | ||||||
| 	zxdg_exported_v2_send_handle(exported->resource, exported->base.handle); | 	zxdg_exported_v2_send_handle(exported->resource, exported->base.handle); | ||||||
| 
 | 
 | ||||||
| 	exported->xdg_surface_destroy.notify = handle_xdg_surface_destroy; | 	exported->xdg_toplevel_destroy.notify = handle_xdg_toplevel_destroy; | ||||||
| 	wl_signal_add(&xdg_toplevel->base->events.destroy, &exported->xdg_surface_destroy); | 	wl_signal_add(&xdg_toplevel->base->events.destroy, &exported->xdg_toplevel_destroy); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const struct zxdg_exporter_v2_interface xdg_exporter_impl = { | static const struct zxdg_exporter_v2_interface xdg_exporter_impl = { | ||||||
|  |  | ||||||
|  | @ -415,6 +415,7 @@ void create_xdg_popup(struct wlr_xdg_surface *surface, | ||||||
| 		&positioner->rules, &surface->popup->scheduled.geometry); | 		&positioner->rules, &surface->popup->scheduled.geometry); | ||||||
| 	surface->popup->scheduled.rules = positioner->rules; | 	surface->popup->scheduled.rules = positioner->rules; | ||||||
| 
 | 
 | ||||||
|  | 	wl_signal_init(&surface->popup->events.destroy); | ||||||
| 	wl_signal_init(&surface->popup->events.reposition); | 	wl_signal_init(&surface->popup->events.reposition); | ||||||
| 
 | 
 | ||||||
| 	if (parent) { | 	if (parent) { | ||||||
|  | @ -426,6 +427,8 @@ void create_xdg_popup(struct wlr_xdg_surface *surface, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	set_xdg_surface_role_object(surface, surface->popup->resource); | 	set_xdg_surface_role_object(surface, surface->popup->resource); | ||||||
|  | 
 | ||||||
|  | 	wl_signal_emit_mutable(&surface->client->shell->events.new_popup, surface->popup); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void reset_xdg_popup(struct wlr_xdg_popup *popup) { | void reset_xdg_popup(struct wlr_xdg_popup *popup) { | ||||||
|  | @ -460,14 +463,9 @@ void destroy_xdg_popup(struct wlr_xdg_popup *popup) { | ||||||
| 	wlr_surface_unmap(popup->base->surface); | 	wlr_surface_unmap(popup->base->surface); | ||||||
| 	reset_xdg_popup(popup); | 	reset_xdg_popup(popup); | ||||||
| 
 | 
 | ||||||
| 	// TODO: improve events
 | 	wl_signal_emit_mutable(&popup->events.destroy, NULL); | ||||||
| 	if (popup->base->added) { |  | ||||||
| 		wl_signal_emit_mutable(&popup->base->events.destroy, NULL); |  | ||||||
| 		popup->base->added = false; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	popup->base->popup = NULL; | 	popup->base->popup = NULL; | ||||||
| 
 |  | ||||||
| 	wl_list_remove(&popup->link); | 	wl_list_remove(&popup->link); | ||||||
| 	wl_resource_set_user_data(popup->resource, NULL); | 	wl_resource_set_user_data(popup->resource, NULL); | ||||||
| 	free(popup); | 	free(popup); | ||||||
|  |  | ||||||
|  | @ -158,6 +158,8 @@ struct wlr_xdg_shell *wlr_xdg_shell_create(struct wl_display *display, | ||||||
| 	xdg_shell->global = global; | 	xdg_shell->global = global; | ||||||
| 
 | 
 | ||||||
| 	wl_signal_init(&xdg_shell->events.new_surface); | 	wl_signal_init(&xdg_shell->events.new_surface); | ||||||
|  | 	wl_signal_init(&xdg_shell->events.new_toplevel); | ||||||
|  | 	wl_signal_init(&xdg_shell->events.new_popup); | ||||||
| 	wl_signal_init(&xdg_shell->events.destroy); | 	wl_signal_init(&xdg_shell->events.destroy); | ||||||
| 
 | 
 | ||||||
| 	xdg_shell->display_destroy.notify = handle_display_destroy; | 	xdg_shell->display_destroy.notify = handle_display_destroy; | ||||||
|  |  | ||||||
|  | @ -307,12 +307,6 @@ static void xdg_surface_role_commit(struct wlr_surface *wlr_surface) { | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (!surface->added) { |  | ||||||
| 		surface->added = true; |  | ||||||
| 		wl_signal_emit_mutable(&surface->client->shell->events.new_surface, |  | ||||||
| 			surface); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (wlr_surface_has_buffer(wlr_surface)) { | 	if (wlr_surface_has_buffer(wlr_surface)) { | ||||||
| 		wlr_surface_map(wlr_surface); | 		wlr_surface_map(wlr_surface); | ||||||
| 	} | 	} | ||||||
|  | @ -392,6 +386,8 @@ void create_xdg_surface(struct wlr_xdg_client *client, struct wlr_surface *wlr_s | ||||||
| 	wl_list_insert(&client->surfaces, &surface->link); | 	wl_list_insert(&client->surfaces, &surface->link); | ||||||
| 
 | 
 | ||||||
| 	wlr_surface_set_role_object(wlr_surface, surface->resource); | 	wlr_surface_set_role_object(wlr_surface, surface->resource); | ||||||
|  | 
 | ||||||
|  | 	wl_signal_emit_mutable(&surface->client->shell->events.new_surface, surface); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool set_xdg_surface_role(struct wlr_xdg_surface *surface, enum wlr_xdg_surface_role role) { | bool set_xdg_surface_role(struct wlr_xdg_surface *surface, enum wlr_xdg_surface_role role) { | ||||||
|  | @ -466,6 +462,8 @@ void destroy_xdg_surface(struct wlr_xdg_surface *surface) { | ||||||
| 	destroy_xdg_surface_role_object(surface); | 	destroy_xdg_surface_role_object(surface); | ||||||
| 	reset_xdg_surface(surface); | 	reset_xdg_surface(surface); | ||||||
| 
 | 
 | ||||||
|  | 	wl_signal_emit_mutable(&surface->events.destroy, NULL); | ||||||
|  | 
 | ||||||
| 	wl_list_remove(&surface->link); | 	wl_list_remove(&surface->link); | ||||||
| 
 | 
 | ||||||
| 	wl_resource_set_user_data(surface->resource, NULL); | 	wl_resource_set_user_data(surface->resource, NULL); | ||||||
|  |  | ||||||
|  | @ -476,6 +476,7 @@ void create_xdg_toplevel(struct wlr_xdg_surface *surface, | ||||||
| 	} | 	} | ||||||
| 	surface->toplevel->base = surface; | 	surface->toplevel->base = surface; | ||||||
| 
 | 
 | ||||||
|  | 	wl_signal_init(&surface->toplevel->events.destroy); | ||||||
| 	wl_signal_init(&surface->toplevel->events.request_maximize); | 	wl_signal_init(&surface->toplevel->events.request_maximize); | ||||||
| 	wl_signal_init(&surface->toplevel->events.request_fullscreen); | 	wl_signal_init(&surface->toplevel->events.request_fullscreen); | ||||||
| 	wl_signal_init(&surface->toplevel->events.request_minimize); | 	wl_signal_init(&surface->toplevel->events.request_minimize); | ||||||
|  | @ -499,6 +500,8 @@ void create_xdg_toplevel(struct wlr_xdg_surface *surface, | ||||||
| 		&xdg_toplevel_implementation, surface->toplevel, NULL); | 		&xdg_toplevel_implementation, surface->toplevel, NULL); | ||||||
| 
 | 
 | ||||||
| 	set_xdg_surface_role_object(surface, surface->toplevel->resource); | 	set_xdg_surface_role_object(surface, surface->toplevel->resource); | ||||||
|  | 
 | ||||||
|  | 	wl_signal_emit_mutable(&surface->client->shell->events.new_toplevel, surface->toplevel); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void reset_xdg_toplevel(struct wlr_xdg_toplevel *toplevel) { | void reset_xdg_toplevel(struct wlr_xdg_toplevel *toplevel) { | ||||||
|  | @ -524,11 +527,7 @@ void destroy_xdg_toplevel(struct wlr_xdg_toplevel *toplevel) { | ||||||
| 	wlr_surface_unmap(toplevel->base->surface); | 	wlr_surface_unmap(toplevel->base->surface); | ||||||
| 	reset_xdg_toplevel(toplevel); | 	reset_xdg_toplevel(toplevel); | ||||||
| 
 | 
 | ||||||
| 	// TODO: improve events
 | 	wl_signal_emit_mutable(&toplevel->events.destroy, NULL); | ||||||
| 	if (toplevel->base->added) { |  | ||||||
| 		wl_signal_emit_mutable(&toplevel->base->events.destroy, NULL); |  | ||||||
| 		toplevel->base->added = false; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	toplevel->base->toplevel = NULL; | 	toplevel->base->toplevel = NULL; | ||||||
| 	wl_resource_set_user_data(toplevel->resource, NULL); | 	wl_resource_set_user_data(toplevel->resource, NULL); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Kirill Primak
						Kirill Primak