[gtk: 11/15] gtkgesture: Handle hold gestures
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk: 11/15] gtkgesture: Handle hold gestures
- Date: Wed, 26 Jan 2022 23:37:29 +0000 (UTC)
commit 3bfcc12ec01c68f2c5b6af0ed80e3ee9bd13f000
Author: José Expósito <jose exposito89 gmail com>
Date: Mon Jun 28 17:49:35 2021 +0200
gtkgesture: Handle hold gestures
Hold gestures are used to bring existing gestures on touchpad
semantically closer to touchscreen gestures.
Touchpad gestures observe hold gestures with a matching amount of
fingers and emit their begin and end signals when fingers are detected
or removed on/from the touchpad.
When a hold cancel event is detected, it is required to wait a few
milliseconds until the next event(s) are received to avoid emitting
multiple begin signals.
Part-of: <!3454>
gtk/gtkgesture.c | 44 ++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 42 insertions(+), 2 deletions(-)
---
diff --git a/gtk/gtkgesture.c b/gtk/gtkgesture.c
index 19929bc1fc..59fee6bcbf 100644
--- a/gtk/gtkgesture.c
+++ b/gtk/gtkgesture.c
@@ -162,6 +162,7 @@ struct _GtkGesturePrivate
GdkDevice *device;
GList *group_link;
guint n_points;
+ guint hold_timeout_id;
guint recognized : 1;
guint touchpad : 1;
};
@@ -174,6 +175,8 @@ static guint signals[N_SIGNALS] = { 0 };
gdk_event_get_event_type (e) == GDK_TOUCHPAD_PINCH || \
gdk_event_get_event_type (e) == GDK_TOUCHPAD_HOLD)
+#define HOLD_TIMEOUT_MS 50
+
GList * _gtk_gesture_get_group_link (GtkGesture *gesture);
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GtkGesture, gtk_gesture, GTK_TYPE_EVENT_CONTROLLER)
@@ -222,6 +225,7 @@ gtk_gesture_finalize (GObject *object)
gtk_gesture_ungroup (gesture);
g_list_free (priv->group_link);
+ g_clear_handle_id (&priv->hold_timeout_id, g_source_remove);
g_hash_table_destroy (priv->points);
@@ -579,6 +583,22 @@ _gtk_gesture_cancel_all (GtkGesture *gesture)
_gtk_gesture_check_empty (gesture);
}
+static gboolean
+gtk_gesture_hold_timeout (gpointer user_data)
+{
+ GtkGesture *gesture;
+ GtkGesturePrivate *priv;
+
+ gesture = user_data;
+ priv = gtk_gesture_get_instance_private (gesture);
+
+ if (priv->touchpad)
+ _gtk_gesture_cancel_sequence (gesture, priv->last_sequence);
+
+ priv->hold_timeout_id = 0;
+ return G_SOURCE_REMOVE;
+}
+
static gboolean
gesture_within_surface (GtkGesture *gesture,
GdkSurface *surface)
@@ -641,8 +661,13 @@ gtk_gesture_handle_event (GtkEventController *controller,
if (event_type == GDK_BUTTON_PRESS ||
event_type == GDK_TOUCH_BEGIN ||
(event_type == GDK_TOUCHPAD_SWIPE && phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN) ||
- (event_type == GDK_TOUCHPAD_PINCH && phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN))
+ (event_type == GDK_TOUCHPAD_PINCH && phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN) ||
+ (event_type == GDK_TOUCHPAD_HOLD && phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN))
{
+ if ((event_type == GDK_TOUCHPAD_PINCH || event_type == GDK_TOUCHPAD_SWIPE) &&
+ _gtk_gesture_has_matching_touchpoints (gesture))
+ g_clear_handle_id (&priv->hold_timeout_id, g_source_remove);
+
if (_gtk_gesture_update_point (gesture, event, target, x, y, TRUE))
{
gboolean triggered_recognition;
@@ -673,7 +698,8 @@ gtk_gesture_handle_event (GtkEventController *controller,
else if (event_type == GDK_BUTTON_RELEASE ||
event_type == GDK_TOUCH_END ||
(event_type == GDK_TOUCHPAD_SWIPE && phase == GDK_TOUCHPAD_GESTURE_PHASE_END) ||
- (event_type == GDK_TOUCHPAD_PINCH && phase == GDK_TOUCHPAD_GESTURE_PHASE_END))
+ (event_type == GDK_TOUCHPAD_PINCH && phase == GDK_TOUCHPAD_GESTURE_PHASE_END) ||
+ (event_type == GDK_TOUCHPAD_HOLD && phase == GDK_TOUCHPAD_GESTURE_PHASE_END))
{
gboolean was_claimed = FALSE;
@@ -717,6 +743,15 @@ gtk_gesture_handle_event (GtkEventController *controller,
if (priv->touchpad)
_gtk_gesture_cancel_sequence (gesture, sequence);
}
+ else if (event_type == GDK_TOUCHPAD_HOLD && phase == GDK_TOUCHPAD_GESTURE_PHASE_CANCEL)
+ {
+ if (priv->hold_timeout_id == 0)
+ {
+ priv->hold_timeout_id = g_timeout_add (HOLD_TIMEOUT_MS,
+ gtk_gesture_hold_timeout,
+ gesture);
+ }
+ }
else if (event_type == GDK_GRAB_BROKEN)
{
GdkSurface *surface;
@@ -742,6 +777,10 @@ gtk_gesture_handle_event (GtkEventController *controller,
static void
gtk_gesture_reset (GtkEventController *controller)
{
+ GtkGesture *gesture = GTK_GESTURE (controller);
+ GtkGesturePrivate *priv = gtk_gesture_get_instance_private (gesture);
+
+ g_clear_handle_id (&priv->hold_timeout_id, g_source_remove);
_gtk_gesture_cancel_all (GTK_GESTURE (controller));
}
@@ -913,6 +952,7 @@ gtk_gesture_init (GtkGesture *gesture)
priv->points = g_hash_table_new_full (NULL, NULL, NULL,
(GDestroyNotify) free_point_data);
priv->group_link = g_list_prepend (NULL, gesture);
+ priv->hold_timeout_id = 0;
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]