aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wlr/types/wlr_xdg_shell.h1
-rw-r--r--include/wlr/types/wlr_xdg_shell_v6.h1
-rw-r--r--types/wlr_xdg_shell.c21
-rw-r--r--types/wlr_xdg_shell_v6.c21
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;
}