aboutsummaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
authorRose Hudson <rose@krx.sh>2023-03-17 15:58:47 +0000
committerSimon Ser <contact@emersion.fr>2023-03-24 11:47:08 +0000
commit37f42e2df26ff694801e3b6593462f303c83b0fa (patch)
tree5867abecf59f913ce7a43dd2d0d86dedc19cacbd /backend
parent1d64e12391a638201c679e71d4e22bb45e5faa8e (diff)
backend/wayland: support touch cancel events
since wayland doesn't provide a touch id in cancel events, track what points are active so we can cancel all of them timestamp is also not provided - use 0 because no one's paying attention to that anyway Closes #3000
Diffstat (limited to 'backend')
-rw-r--r--backend/wayland/seat.c33
1 files changed, 32 insertions, 1 deletions
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,