mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-12-22 09:59:48 +01:00
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:
parent
1d64e12391
commit
37f42e2df2
2 changed files with 38 additions and 1 deletions
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue