|  |  |  | @ -11,6 +11,66 @@ | 
			
		
	
		
			
				
					|  |  |  |  | #include "sway/input/input-manager.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "log.h" | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static const struct sway_view_child_impl popup_impl; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void popup_destroy(struct sway_view_child *child) { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!sway_assert(child->impl == &popup_impl, | 
			
		
	
		
			
				
					|  |  |  |  | 			"Expected an xdg_shell_v6 popup")) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_xdg_popup_v6 *popup = (struct sway_xdg_popup_v6 *)child; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_remove(&popup->new_popup.link); | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_remove(&popup->unmap.link); | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_remove(&popup->destroy.link); | 
			
		
	
		
			
				
					|  |  |  |  | 	free(popup); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static const struct sway_view_child_impl popup_impl = { | 
			
		
	
		
			
				
					|  |  |  |  | 	.destroy = popup_destroy, | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static struct sway_xdg_popup_v6 *popup_create( | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_xdg_popup_v6 *wlr_popup, struct sway_view *view); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void popup_handle_new_popup(struct wl_listener *listener, void *data) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_xdg_popup_v6 *popup = | 
			
		
	
		
			
				
					|  |  |  |  | 		wl_container_of(listener, popup, new_popup); | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_xdg_popup_v6 *wlr_popup = data; | 
			
		
	
		
			
				
					|  |  |  |  | 	popup_create(wlr_popup, popup->child.view); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void popup_handle_unmap(struct wl_listener *listener, void *data) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_xdg_popup_v6 *popup = wl_container_of(listener, popup, unmap); | 
			
		
	
		
			
				
					|  |  |  |  | 	view_child_destroy(&popup->child); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void popup_handle_destroy(struct wl_listener *listener, void *data) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_xdg_popup_v6 *popup = wl_container_of(listener, popup, destroy); | 
			
		
	
		
			
				
					|  |  |  |  | 	view_child_destroy(&popup->child); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static struct sway_xdg_popup_v6 *popup_create( | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_xdg_popup_v6 *wlr_popup, struct sway_view *view) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_xdg_surface_v6 *xdg_surface = wlr_popup->base; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_xdg_popup_v6 *popup = | 
			
		
	
		
			
				
					|  |  |  |  | 		calloc(1, sizeof(struct sway_xdg_popup_v6)); | 
			
		
	
		
			
				
					|  |  |  |  | 	if (popup == NULL) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	view_child_init(&popup->child, &popup_impl, view, xdg_surface->surface); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_signal_add(&xdg_surface->events.new_popup, &popup->new_popup); | 
			
		
	
		
			
				
					|  |  |  |  | 	popup->new_popup.notify = popup_handle_new_popup; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_signal_add(&xdg_surface->events.unmap, &popup->unmap); | 
			
		
	
		
			
				
					|  |  |  |  | 	popup->unmap.notify = popup_handle_unmap; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_signal_add(&xdg_surface->events.destroy, &popup->destroy); | 
			
		
	
		
			
				
					|  |  |  |  | 	popup->destroy.notify = popup_handle_destroy; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	return popup; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static struct sway_xdg_shell_v6_view *xdg_shell_v6_view_from_view( | 
			
		
	
		
			
				
					|  |  |  |  | 		struct sway_view *view) { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!sway_assert(view->type == SWAY_VIEW_XDG_SHELL_V6, | 
			
		
	
	
		
			
				
					|  |  |  | @ -76,6 +136,7 @@ static void destroy(struct sway_view *view) { | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_remove(&xdg_shell_v6_view->commit.link); | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_remove(&xdg_shell_v6_view->destroy.link); | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_remove(&xdg_shell_v6_view->new_popup.link); | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_remove(&xdg_shell_v6_view->map.link); | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_remove(&xdg_shell_v6_view->unmap.link); | 
			
		
	
		
			
				
					|  |  |  |  | 	free(xdg_shell_v6_view); | 
			
		
	
	
		
			
				
					|  |  |  | @ -100,6 +161,13 @@ static void handle_commit(struct wl_listener *listener, void *data) { | 
			
		
	
		
			
				
					|  |  |  |  | 	view_damage_from(view); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void handle_new_popup(struct wl_listener *listener, void *data) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_xdg_shell_v6_view *xdg_shell_v6_view = | 
			
		
	
		
			
				
					|  |  |  |  | 		wl_container_of(listener, xdg_shell_v6_view, new_popup); | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_xdg_popup_v6 *wlr_popup = data; | 
			
		
	
		
			
				
					|  |  |  |  | 	popup_create(wlr_popup, &xdg_shell_v6_view->view); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void handle_unmap(struct wl_listener *listener, void *data) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_xdg_shell_v6_view *xdg_shell_v6_view = | 
			
		
	
		
			
				
					|  |  |  |  | 		wl_container_of(listener, xdg_shell_v6_view, unmap); | 
			
		
	
	
		
			
				
					|  |  |  | @ -151,6 +219,10 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_signal_add(&xdg_surface->surface->events.commit, | 
			
		
	
		
			
				
					|  |  |  |  | 		&xdg_shell_v6_view->commit); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	xdg_shell_v6_view->new_popup.notify = handle_new_popup; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_signal_add(&xdg_surface->events.new_popup, | 
			
		
	
		
			
				
					|  |  |  |  | 		&xdg_shell_v6_view->new_popup); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	xdg_shell_v6_view->map.notify = handle_map; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_signal_add(&xdg_surface->events.map, &xdg_shell_v6_view->map); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | 
 |