diff options
| -rw-r--r-- | include/wlr/types/wlr_xdg_shell.h | 1 | ||||
| -rw-r--r-- | include/wlr/types/wlr_xdg_shell_v6.h | 1 | ||||
| -rw-r--r-- | types/wlr_xdg_shell.c | 21 | ||||
| -rw-r--r-- | types/wlr_xdg_shell_v6.c | 21 | 
4 files changed, 44 insertions, 0 deletions
diff --git a/include/wlr/types/wlr_xdg_shell.h b/include/wlr/types/wlr_xdg_shell.h index ad0a626f..a5fa093b 100644 --- a/include/wlr/types/wlr_xdg_shell.h +++ b/include/wlr/types/wlr_xdg_shell.h @@ -53,6 +53,7 @@ struct wlr_xdg_popup_grab {  	struct wlr_seat *seat;  	struct wl_list popups;  	struct wl_list link; // wlr_xdg_shell::popup_grabs +	struct wl_listener seat_destroy;  };  enum wlr_xdg_surface_role { diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index d8503d28..a1bdac1b 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -53,6 +53,7 @@ struct wlr_xdg_popup_grab_v6 {  	struct wlr_seat *seat;  	struct wl_list popups;  	struct wl_list link; // wlr_xdg_shell_v6::popup_grabs +	struct wl_listener seat_destroy;  };  enum wlr_xdg_surface_v6_role { diff --git a/types/wlr_xdg_shell.c b/types/wlr_xdg_shell.c index 5b02088d..f01d81a5 100644 --- a/types/wlr_xdg_shell.c +++ b/types/wlr_xdg_shell.c @@ -131,6 +131,24 @@ static const struct wlr_keyboard_grab_interface xdg_keyboard_grab_impl = {  	.cancel = xdg_keyboard_grab_cancel,  }; +static void xdg_surface_destroy(struct wlr_xdg_surface *surface); + +static void wlr_xdg_popup_grab_handle_seat_destroy( +		struct wl_listener *listener, void *data) { +	struct wlr_xdg_popup_grab *xdg_grab = +		wl_container_of(listener, xdg_grab, seat_destroy); + +	wl_list_remove(&xdg_grab->seat_destroy.link); + +	struct wlr_xdg_popup *popup, *next; +	wl_list_for_each_safe(popup, next, &xdg_grab->popups, grab_link) { +		xdg_surface_destroy(popup->base); +	} + +	wl_list_remove(&xdg_grab->link); +	free(xdg_grab); +} +  static struct wlr_xdg_popup_grab *xdg_shell_popup_grab_from_seat(  		struct wlr_xdg_shell *shell, struct wlr_seat *seat) {  	struct wlr_xdg_popup_grab *xdg_grab; @@ -155,6 +173,9 @@ static struct wlr_xdg_popup_grab *xdg_shell_popup_grab_from_seat(  	wl_list_insert(&shell->popup_grabs, &xdg_grab->link);  	xdg_grab->seat = seat; +	xdg_grab->seat_destroy.notify = wlr_xdg_popup_grab_handle_seat_destroy; +	wl_signal_add(&seat->events.destroy, &xdg_grab->seat_destroy); +  	return xdg_grab;  } diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index a0c74e6f..2aaa607b 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -131,6 +131,24 @@ static const struct wlr_keyboard_grab_interface xdg_keyboard_grab_impl = {  	.cancel = xdg_keyboard_grab_cancel,  }; +static void xdg_surface_destroy(struct wlr_xdg_surface_v6 *surface); + +static void wlr_xdg_popup_grab_handle_seat_destroy( +		struct wl_listener *listener, void *data) { +	struct wlr_xdg_popup_grab_v6 *xdg_grab = +		wl_container_of(listener, xdg_grab, seat_destroy); + +	wl_list_remove(&xdg_grab->seat_destroy.link); + +	struct wlr_xdg_popup_v6 *popup, *next; +	wl_list_for_each_safe(popup, next, &xdg_grab->popups, grab_link) { +		xdg_surface_destroy(popup->base); +	} + +	wl_list_remove(&xdg_grab->link); +	free(xdg_grab); +} +  static struct wlr_xdg_popup_grab_v6 *xdg_shell_popup_grab_from_seat(  		struct wlr_xdg_shell_v6 *shell, struct wlr_seat *seat) {  	struct wlr_xdg_popup_grab_v6 *xdg_grab; @@ -155,6 +173,9 @@ static struct wlr_xdg_popup_grab_v6 *xdg_shell_popup_grab_from_seat(  	wl_list_insert(&shell->popup_grabs, &xdg_grab->link);  	xdg_grab->seat = seat; +	xdg_grab->seat_destroy.notify = wlr_xdg_popup_grab_handle_seat_destroy; +	wl_signal_add(&seat->events.destroy, &xdg_grab->seat_destroy); +  	return xdg_grab;  }  | 
