diff --git a/backend/wayland/seat.c b/backend/wayland/seat.c index a64795a8..46c6958b 100644 --- a/backend/wayland/seat.c +++ b/backend/wayland/seat.c @@ -141,6 +141,10 @@ static void touch_handle_down(void *data, struct wl_touch *wl_touch, struct wlr_wl_seat *seat = data; struct wlr_touch *touch = &seat->wlr_touch; + struct wlr_wl_touch_points *points = &seat->touch_points; + assert(points->len != sizeof(points->ids) / sizeof(points->ids[0])); + points->ids[points->len++] = id; + struct wlr_touch_down_event event = { .touch = touch, .time_msec = time, @@ -150,11 +154,26 @@ static void touch_handle_down(void *data, struct wl_touch *wl_touch, wl_signal_emit_mutable(&touch->events.down, &event); } +static bool remove_touch_point(struct wlr_wl_touch_points *points, int32_t id) { + size_t i = 0; + for (; i < points->len; i++) { + if (points->ids[i] == id) { + size_t remaining = points->len - i - 1; + memmove(&points->ids[i], &points->ids[i + 1], remaining * sizeof(id)); + points->len--; + return true; + } + } + return false; +} + static void touch_handle_up(void *data, struct wl_touch *wl_touch, uint32_t serial, uint32_t time, int32_t id) { struct wlr_wl_seat *seat = data; struct wlr_touch *touch = &seat->wlr_touch; + remove_touch_point(&seat->touch_points, id); + struct wlr_touch_up_event event = { .touch = touch, .time_msec = time, @@ -184,7 +203,19 @@ static void touch_handle_frame(void *data, struct wl_touch *wl_touch) { } static void touch_handle_cancel(void *data, struct wl_touch *wl_touch) { - // no-op + struct wlr_wl_seat *seat = data; + struct wlr_touch *touch = &seat->wlr_touch; + + // wayland's cancel event applies to all active touch points + for (size_t i = 0; i < seat->touch_points.len; i++) { + struct wlr_touch_cancel_event event = { + .touch = touch, + .time_msec = 0, + .touch_id = seat->touch_points.ids[i], + }; + wl_signal_emit_mutable(&touch->events.cancel, &event); + } + seat->touch_points.len = 0; } static void touch_handle_shape(void *data, struct wl_touch *wl_touch, diff --git a/include/backend/wayland.h b/include/backend/wayland.h index a1ed4414..75e85879 100644 --- a/include/backend/wayland.h +++ b/include/backend/wayland.h @@ -110,6 +110,11 @@ struct wlr_wl_pointer { struct wl_list link; }; +struct wlr_wl_touch_points { + int32_t ids[64]; + size_t len; +}; + struct wlr_wl_seat { char *name; struct wl_seat *wl_seat; @@ -131,6 +136,7 @@ struct wlr_wl_seat { struct wl_touch *wl_touch; struct wlr_touch wlr_touch; + struct wlr_wl_touch_points touch_points; struct zwp_tablet_seat_v2 *zwp_tablet_seat_v2; struct zwp_tablet_v2 *zwp_tablet_v2;