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
This commit is contained in:
Sebastian Krzyszkowiak 2019-09-14 06:41:54 +02:00 committed by Simon Ser
parent 8b0f1bc850
commit a14d650864
2 changed files with 11 additions and 1 deletions

View file

@ -64,6 +64,7 @@ struct wlr_touch_point {
struct wl_listener surface_destroy; struct wl_listener surface_destroy;
struct wl_listener focus_surface_destroy; struct wl_listener focus_surface_destroy;
struct wl_listener client_destroy;
struct { struct {
struct wl_signal destroy; struct wl_signal destroy;

View file

@ -101,6 +101,7 @@ static void touch_point_destroy(struct wlr_touch_point *point) {
touch_point_clear_focus(point); touch_point_clear_focus(point);
wl_list_remove(&point->surface_destroy.link); wl_list_remove(&point->surface_destroy.link);
wl_list_remove(&point->client_destroy.link);
wl_list_remove(&point->link); wl_list_remove(&point->link);
free(point); free(point);
} }
@ -115,6 +116,13 @@ static void touch_point_handle_surface_destroy(struct wl_listener *listener,
wl_list_init(&point->surface_destroy.link); 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( static struct wlr_touch_point *touch_point_create(
struct wlr_seat *seat, int32_t touch_id, struct wlr_seat *seat, int32_t touch_id,
struct wlr_surface *surface, double sx, double sy) { 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); wl_signal_add(&surface->events.destroy, &point->surface_destroy);
point->surface_destroy.notify = touch_point_handle_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); wl_list_insert(&seat->touch_state.touch_points, &point->link);
return point; return point;