From 20d9448257f4871d3a57deab2f105d7335a64fb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= Date: Mon, 12 Jul 2021 19:53:34 +0200 Subject: [PATCH] wlr_pointer_gestures: hold gestures (protocol v3) Update the pointer gestures protocol to version 3 allowing to send hold gestures to clients. --- include/wlr/types/wlr_pointer_gestures_v1.h | 12 +++ types/wlr_pointer_gestures_v1.c | 96 ++++++++++++++++++++- 2 files changed, 106 insertions(+), 2 deletions(-) diff --git a/include/wlr/types/wlr_pointer_gestures_v1.h b/include/wlr/types/wlr_pointer_gestures_v1.h index bb250389..0d91a517 100644 --- a/include/wlr/types/wlr_pointer_gestures_v1.h +++ b/include/wlr/types/wlr_pointer_gestures_v1.h @@ -17,6 +17,7 @@ struct wlr_pointer_gestures_v1 { struct wl_global *global; struct wl_list swipes; // wl_resource_get_link struct wl_list pinches; // wl_resource_get_link + struct wl_list holds; // wl_resource_get_link struct wl_listener display_destroy; @@ -66,4 +67,15 @@ void wlr_pointer_gestures_v1_send_pinch_end( uint32_t time_msec, bool cancelled); +void wlr_pointer_gestures_v1_send_hold_begin( + struct wlr_pointer_gestures_v1 *gestures, + struct wlr_seat *seat, + uint32_t time_msec, + uint32_t fingers); +void wlr_pointer_gestures_v1_send_hold_end( + struct wlr_pointer_gestures_v1 *gestures, + struct wlr_seat *seat, + uint32_t time_msec, + bool cancelled); + #endif diff --git a/types/wlr_pointer_gestures_v1.c b/types/wlr_pointer_gestures_v1.c index a0328704..6b09a764 100644 --- a/types/wlr_pointer_gestures_v1.c +++ b/types/wlr_pointer_gestures_v1.c @@ -11,7 +11,7 @@ #include "util/signal.h" #include "pointer-gestures-unstable-v1-protocol.h" -#define POINTER_GESTURES_VERSION 2 +#define POINTER_GESTURES_VERSION 3 static void resource_handle_destroy(struct wl_client *client, struct wl_resource *resource) { @@ -25,6 +25,7 @@ static void resource_remove_from_list(struct wl_resource *resource) { static const struct zwp_pointer_gestures_v1_interface gestures_impl; static const struct zwp_pointer_gesture_swipe_v1_interface swipe_impl; static const struct zwp_pointer_gesture_pinch_v1_interface pinch_impl; +static const struct zwp_pointer_gesture_hold_v1_interface hold_impl; static struct wlr_pointer_gestures_v1 *pointer_gestures_from_resource( struct wl_resource *resource) { @@ -38,7 +39,9 @@ static struct wlr_seat *seat_from_pointer_resource( assert(wl_resource_instance_of(resource, &zwp_pointer_gesture_swipe_v1_interface, &swipe_impl) || wl_resource_instance_of(resource, - &zwp_pointer_gesture_pinch_v1_interface, &pinch_impl)); + &zwp_pointer_gesture_pinch_v1_interface, &pinch_impl) || + wl_resource_instance_of(resource, + &zwp_pointer_gesture_hold_v1_interface, &hold_impl)); return wl_resource_get_user_data(resource); } @@ -275,10 +278,98 @@ static void pointer_gestures_release(struct wl_client *client, wl_resource_destroy(resource); } +void wlr_pointer_gestures_v1_send_hold_begin( + struct wlr_pointer_gestures_v1 *gestures, + struct wlr_seat *seat, + uint32_t time_msec, + uint32_t fingers) { + struct wlr_surface *focus = seat->pointer_state.focused_surface; + if (focus == NULL) { + return; + } + + struct wl_client *focus_client = wl_resource_get_client(focus->resource); + uint32_t serial = wlr_seat_client_next_serial( + seat->pointer_state.focused_client); + + struct wl_resource *gesture; + wl_resource_for_each(gesture, &gestures->holds) { + struct wlr_seat *gesture_seat = seat_from_pointer_resource(gesture); + struct wl_client *gesture_client = wl_resource_get_client(gesture); + if (gesture_seat != seat || gesture_client != focus_client) { + continue; + } + zwp_pointer_gesture_hold_v1_send_begin(gesture, serial, + time_msec, focus->resource, fingers); + } +} + +void wlr_pointer_gestures_v1_send_hold_end( + struct wlr_pointer_gestures_v1 *gestures, + struct wlr_seat *seat, + uint32_t time_msec, + bool cancelled) { + struct wlr_surface *focus = seat->pointer_state.focused_surface; + if (focus == NULL) { + return; + } + + struct wl_client *focus_client = wl_resource_get_client(focus->resource); + uint32_t serial = wlr_seat_client_next_serial( + seat->pointer_state.focused_client); + + struct wl_resource *gesture; + wl_resource_for_each(gesture, &gestures->holds) { + struct wlr_seat *gesture_seat = seat_from_pointer_resource(gesture); + struct wl_client *gesture_client = wl_resource_get_client(gesture); + if (gesture_seat != seat || gesture_client != focus_client) { + continue; + } + zwp_pointer_gesture_hold_v1_send_end(gesture, serial, + time_msec, cancelled); + } +} + +static const struct zwp_pointer_gesture_hold_v1_interface hold_impl = { + .destroy = resource_handle_destroy, +}; + +static void get_hold_gesture(struct wl_client *client, + struct wl_resource *gestures_resource, + uint32_t id, + struct wl_resource *pointer_resource) { + struct wlr_seat_client *seat_client = + wlr_seat_client_from_pointer_resource(pointer_resource); + struct wlr_seat *seat = NULL; + + if (seat_client != NULL) { + seat = seat_client->seat; + } + // Otherwise, the resource will be inert + // (NULL seat, so all seat comparisons will fail) + + struct wlr_pointer_gestures_v1 *gestures = + pointer_gestures_from_resource(gestures_resource); + + struct wl_resource *gesture = wl_resource_create(client, + &zwp_pointer_gesture_hold_v1_interface, + wl_resource_get_version(gestures_resource), + id); + if (gesture == NULL) { + wl_client_post_no_memory(client); + return; + } + + wl_resource_set_implementation(gesture, &hold_impl, seat, + resource_remove_from_list); + wl_list_insert(&gestures->holds, wl_resource_get_link(gesture)); +} + static const struct zwp_pointer_gestures_v1_interface gestures_impl = { .get_swipe_gesture = get_swipe_gesture, .get_pinch_gesture = get_pinch_gesture, .release = pointer_gestures_release, + .get_hold_gesture = get_hold_gesture, }; static void pointer_gestures_v1_bind(struct wl_client *wl_client, void *data, @@ -314,6 +405,7 @@ struct wlr_pointer_gestures_v1 *wlr_pointer_gestures_v1_create( wl_list_init(&gestures->swipes); wl_list_init(&gestures->pinches); + wl_list_init(&gestures->holds); gestures->global = wl_global_create(display, &zwp_pointer_gestures_v1_interface, POINTER_GESTURES_VERSION,