From a14d65086480652520d20622cbc92df2319158f0 Mon Sep 17 00:00:00 2001 From: Sebastian Krzyszkowiak Date: Sat, 14 Sep 2019 06:41:54 +0200 Subject: [PATCH] wlr_seat_touch: Destroy the touchpoint on client destroy Since e26217c51e3a5e1d7dfc95a8a76299e056497981, touchpoints can outlive surfaces. This works fine as long as the client stays around, but fails horribly otherwise; therefore we have to make sure that touchpoints don't outlive their clients. Fixes #1788 --- include/wlr/types/wlr_seat.h | 1 + types/seat/wlr_seat_touch.c | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index 69fe1359..352483ed 100644 --- a/include/wlr/types/wlr_seat.h +++ b/include/wlr/types/wlr_seat.h @@ -64,6 +64,7 @@ struct wlr_touch_point { struct wl_listener surface_destroy; struct wl_listener focus_surface_destroy; + struct wl_listener client_destroy; struct { struct wl_signal destroy; diff --git a/types/seat/wlr_seat_touch.c b/types/seat/wlr_seat_touch.c index dd57b55a..b0228976 100644 --- a/types/seat/wlr_seat_touch.c +++ b/types/seat/wlr_seat_touch.c @@ -101,6 +101,7 @@ static void touch_point_destroy(struct wlr_touch_point *point) { touch_point_clear_focus(point); wl_list_remove(&point->surface_destroy.link); + wl_list_remove(&point->client_destroy.link); wl_list_remove(&point->link); free(point); } @@ -115,6 +116,13 @@ static void touch_point_handle_surface_destroy(struct wl_listener *listener, wl_list_init(&point->surface_destroy.link); } +static void touch_point_handle_client_destroy(struct wl_listener *listener, + void *data) { + struct wlr_touch_point *point = + wl_container_of(listener, point, client_destroy); + touch_point_destroy(point); +} + static struct wlr_touch_point *touch_point_create( struct wlr_seat *seat, int32_t touch_id, struct wlr_surface *surface, double sx, double sy) { @@ -143,7 +151,8 @@ static struct wlr_touch_point *touch_point_create( wl_signal_add(&surface->events.destroy, &point->surface_destroy); point->surface_destroy.notify = touch_point_handle_surface_destroy; - + wl_signal_add(&client->events.destroy, &point->client_destroy); + point->client_destroy.notify = touch_point_handle_client_destroy; wl_list_insert(&seat->touch_state.touch_points, &point->link); return point;