From 8d34b50918262e32ba0b58be510892624fa60447 Mon Sep 17 00:00:00 2001 From: JoseExposito Date: Sun, 18 Apr 2021 20:24:52 +0200 Subject: [PATCH] wayland/pointer-gestures: Implement hold gesture Update the pointer gestures protocol to version 3 and implement the new hold gesture. Part-of: --- src/meson.build | 2 + .../meta-wayland-pointer-gesture-hold.c | 135 ++++++++++++++++++ .../meta-wayland-pointer-gesture-hold.h | 37 +++++ src/wayland/meta-wayland-pointer-gestures.c | 14 +- src/wayland/meta-wayland-pointer.c | 11 ++ src/wayland/meta-wayland-pointer.h | 2 + src/wayland/meta-wayland-seat.c | 1 + src/wayland/meta-wayland-versions.h | 2 +- 8 files changed, 202 insertions(+), 2 deletions(-) create mode 100644 src/wayland/meta-wayland-pointer-gesture-hold.c create mode 100644 src/wayland/meta-wayland-pointer-gesture-hold.h diff --git a/src/meson.build b/src/meson.build index ecf441324..7dba903d7 100644 --- a/src/meson.build +++ b/src/meson.build @@ -584,6 +584,8 @@ if have_wayland 'wayland/meta-wayland-pointer.c', 'wayland/meta-wayland-pointer-constraints.c', 'wayland/meta-wayland-pointer-constraints.h', + 'wayland/meta-wayland-pointer-gesture-hold.c', + 'wayland/meta-wayland-pointer-gesture-hold.h', 'wayland/meta-wayland-pointer-gesture-pinch.c', 'wayland/meta-wayland-pointer-gesture-pinch.h', 'wayland/meta-wayland-pointer-gestures.c', diff --git a/src/wayland/meta-wayland-pointer-gesture-hold.c b/src/wayland/meta-wayland-pointer-gesture-hold.c new file mode 100644 index 000000000..904b0654b --- /dev/null +++ b/src/wayland/meta-wayland-pointer-gesture-hold.c @@ -0,0 +1,135 @@ +/* + * Wayland Support + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Author: José Expósito + */ + +#include "config.h" + +#include "wayland/meta-wayland-pointer-gesture-hold.h" + +#include + +#include "wayland/meta-wayland-pointer.h" +#include "wayland/meta-wayland-seat.h" +#include "wayland/meta-wayland-surface.h" + +#include "pointer-gestures-unstable-v1-server-protocol.h" + +static void +handle_hold_begin (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + MetaWaylandPointerClient *pointer_client; + MetaWaylandSeat *seat; + struct wl_resource *resource; + uint32_t serial, fingers; + + pointer_client = pointer->focus_client; + seat = meta_wayland_pointer_get_seat (pointer); + serial = wl_display_next_serial (seat->wl_display); + fingers = clutter_event_get_touchpad_gesture_finger_count (event); + + wl_resource_for_each (resource, &pointer_client->hold_gesture_resources) + { + zwp_pointer_gesture_hold_v1_send_begin (resource, serial, + clutter_event_get_time (event), + pointer->focus_surface->resource, + fingers); + } +} + +static void +handle_hold_end (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + MetaWaylandPointerClient *pointer_client; + MetaWaylandSeat *seat; + struct wl_resource *resource; + gboolean cancelled = FALSE; + uint32_t serial; + + pointer_client = pointer->focus_client; + seat = meta_wayland_pointer_get_seat (pointer); + serial = wl_display_next_serial (seat->wl_display); + + if (event->touchpad_hold.phase == CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL) + cancelled = TRUE; + + wl_resource_for_each (resource, &pointer_client->hold_gesture_resources) + { + zwp_pointer_gesture_hold_v1_send_end (resource, serial, + clutter_event_get_time (event), + cancelled); + } +} + +gboolean +meta_wayland_pointer_gesture_hold_handle_event (MetaWaylandPointer *pointer, + const ClutterEvent *event) +{ + if (event->type != CLUTTER_TOUCHPAD_HOLD) + return FALSE; + + if (!pointer->focus_client) + return FALSE; + + switch (event->touchpad_hold.phase) + { + case CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN: + handle_hold_begin (pointer, event); + break; + case CLUTTER_TOUCHPAD_GESTURE_PHASE_END: + case CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL: + handle_hold_end (pointer, event); + break; + default: + return FALSE; + } + + return TRUE; +} + +static void +pointer_gesture_hold_release (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct zwp_pointer_gesture_hold_v1_interface pointer_gesture_hold_interface = { + pointer_gesture_hold_release +}; + +void +meta_wayland_pointer_gesture_hold_create_new_resource (MetaWaylandPointer *pointer, + struct wl_client *client, + struct wl_resource *pointer_resource, + uint32_t id) +{ + MetaWaylandPointerClient *pointer_client; + struct wl_resource *res; + + pointer_client = meta_wayland_pointer_get_pointer_client (pointer, client); + g_return_if_fail (pointer_client != NULL); + + res = wl_resource_create (client, &zwp_pointer_gesture_hold_v1_interface, + wl_resource_get_version (pointer_resource), id); + wl_resource_set_implementation (res, &pointer_gesture_hold_interface, pointer, + meta_wayland_pointer_unbind_pointer_client_resource); + wl_list_insert (&pointer_client->hold_gesture_resources, + wl_resource_get_link (res)); +} diff --git a/src/wayland/meta-wayland-pointer-gesture-hold.h b/src/wayland/meta-wayland-pointer-gesture-hold.h new file mode 100644 index 000000000..55846bff6 --- /dev/null +++ b/src/wayland/meta-wayland-pointer-gesture-hold.h @@ -0,0 +1,37 @@ +/* + * Wayland Support + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Author: José Expósito + */ + +#ifndef META_WAYLAND_POINTER_GESTURE_HOLD_H +#define META_WAYLAND_POINTER_GESTURE_HOLD_H + +#include +#include + +#include "clutter/clutter.h" +#include "wayland/meta-wayland-types.h" + +gboolean meta_wayland_pointer_gesture_hold_handle_event (MetaWaylandPointer *pointer, + const ClutterEvent *event); + +void meta_wayland_pointer_gesture_hold_create_new_resource (MetaWaylandPointer *pointer, + struct wl_client *client, + struct wl_resource *gestures_resource, + uint32_t id); + +#endif /* META_WAYLAND_POINTER_GESTURE_HOLD_H */ diff --git a/src/wayland/meta-wayland-pointer-gestures.c b/src/wayland/meta-wayland-pointer-gestures.c index a83d86004..559531d34 100644 --- a/src/wayland/meta-wayland-pointer-gestures.c +++ b/src/wayland/meta-wayland-pointer-gestures.c @@ -54,6 +54,17 @@ gestures_get_pinch (struct wl_client *client, meta_wayland_pointer_gesture_pinch_create_new_resource (pointer, client, resource, id); } +static void +gestures_get_hold (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *pointer_resource) +{ + MetaWaylandPointer *pointer = wl_resource_get_user_data (pointer_resource); + + meta_wayland_pointer_gesture_hold_create_new_resource (pointer, client, resource, id); +} + static void gestures_release (struct wl_client *client, struct wl_resource *resource) @@ -64,7 +75,8 @@ gestures_release (struct wl_client *client, static const struct zwp_pointer_gestures_v1_interface pointer_gestures_interface = { gestures_get_swipe, gestures_get_pinch, - gestures_release + gestures_release, + gestures_get_hold }; static void diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index abd779ad7..e513ee258 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -103,6 +103,7 @@ meta_wayland_pointer_client_new (void) wl_list_init (&pointer_client->pointer_resources); wl_list_init (&pointer_client->swipe_gesture_resources); wl_list_init (&pointer_client->pinch_gesture_resources); + wl_list_init (&pointer_client->hold_gesture_resources); wl_list_init (&pointer_client->relative_pointer_resources); return pointer_client; @@ -135,6 +136,11 @@ meta_wayland_pointer_make_resources_inert (MetaWaylandPointerClient *pointer_cli wl_list_init (wl_resource_get_link (resource)); wl_resource_set_user_data (resource, NULL); } + wl_resource_for_each_safe (resource, next, &pointer_client->hold_gesture_resources) + { + wl_list_remove (wl_resource_get_link (resource)); + wl_list_init (wl_resource_get_link (resource)); + } wl_resource_for_each_safe (resource, next, &pointer_client->relative_pointer_resources) { wl_list_remove (wl_resource_get_link (resource)); @@ -166,6 +172,7 @@ meta_wayland_pointer_client_is_empty (MetaWaylandPointerClient *pointer_client) return (wl_list_empty (&pointer_client->pointer_resources) && wl_list_empty (&pointer_client->swipe_gesture_resources) && wl_list_empty (&pointer_client->pinch_gesture_resources) && + wl_list_empty (&pointer_client->hold_gesture_resources) && wl_list_empty (&pointer_client->relative_pointer_resources)); } @@ -822,6 +829,10 @@ meta_wayland_pointer_handle_event (MetaWaylandPointer *pointer, meta_wayland_pointer_gesture_pinch_handle_event (pointer, event); break; + case CLUTTER_TOUCHPAD_HOLD: + meta_wayland_pointer_gesture_hold_handle_event (pointer, event); + break; + default: break; } diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h index 5eda5276f..86810ebac 100644 --- a/src/wayland/meta-wayland-pointer.h +++ b/src/wayland/meta-wayland-pointer.h @@ -25,6 +25,7 @@ #include "meta/meta-cursor-tracker.h" #include "wayland/meta-wayland-pointer-constraints.h" +#include "wayland/meta-wayland-pointer-gesture-hold.h" #include "wayland/meta-wayland-pointer-gesture-pinch.h" #include "wayland/meta-wayland-pointer-gesture-swipe.h" #include "wayland/meta-wayland-seat.h" @@ -58,6 +59,7 @@ struct _MetaWaylandPointerClient struct wl_list pointer_resources; struct wl_list swipe_gesture_resources; struct wl_list pinch_gesture_resources; + struct wl_list hold_gesture_resources; struct wl_list relative_pointer_resources; }; diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index efce6d6d6..8f0f992f6 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -400,6 +400,7 @@ meta_wayland_seat_handle_event (MetaWaylandSeat *seat, case CLUTTER_SCROLL: case CLUTTER_TOUCHPAD_SWIPE: case CLUTTER_TOUCHPAD_PINCH: + case CLUTTER_TOUCHPAD_HOLD: if (meta_wayland_seat_has_pointer (seat)) return meta_wayland_pointer_handle_event (seat->pointer, event); diff --git a/src/wayland/meta-wayland-versions.h b/src/wayland/meta-wayland-versions.h index 6f26aa6be..5e40b4aa2 100644 --- a/src/wayland/meta-wayland-versions.h +++ b/src/wayland/meta-wayland-versions.h @@ -45,7 +45,7 @@ #define META_XSERVER_VERSION 1 #define META_GTK_SHELL1_VERSION 5 #define META_WL_SUBCOMPOSITOR_VERSION 1 -#define META_ZWP_POINTER_GESTURES_V1_VERSION 2 +#define META_ZWP_POINTER_GESTURES_V1_VERSION 3 #define META_ZXDG_EXPORTER_V1_VERSION 1 #define META_ZXDG_IMPORTER_V1_VERSION 1 #define META_ZWP_LINUX_DMABUF_V1_VERSION 3