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
This commit is contained in:
Rose Hudson 2023-03-17 15:58:47 +00:00 committed by Simon Ser
parent 1d64e12391
commit 37f42e2df2
2 changed files with 38 additions and 1 deletions

View File

@ -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,

View File

@ -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;