[gtk: 7/15] gtkeventcontrollerscroll: Handle hold gestures
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk: 7/15] gtkeventcontrollerscroll: Handle hold gestures
- Date: Wed, 26 Jan 2022 23:37:29 +0000 (UTC)
commit f09338c8ded26ecb620937b4a10e59614460a065
Author: José Expósito <jose exposito89 gmail com>
Date: Mon Jun 28 17:48:04 2021 +0200
gtkeventcontrollerscroll: Handle hold gestures
Handle hold events:
- GDK_TOUCHPAD_GESTURE_PHASE_BEGIN: scroll-begin is emitted.
- GDK_TOUCHPAD_GESTURE_PHASE_END: A hold gesture ends only when all
fingers are lifted from the touchpad without movement, so
scroll-end is emitted right away.
- GDK_TOUCHPAD_GESTURE_PHASE_CANCEL: A hold gesture is cancelled when
some fingers are lifted/put down or movement is detected. In this
case, scroll-end is emitted after a small timeout only if
GDK_SCROLL wasn't detected.
Part-of: <!3454>
gtk/gtkeventcontrollerscroll.c | 78 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 77 insertions(+), 1 deletion(-)
---
diff --git a/gtk/gtkeventcontrollerscroll.c b/gtk/gtkeventcontrollerscroll.c
index e0acee7a2e..67dafb73ed 100644
--- a/gtk/gtkeventcontrollerscroll.c
+++ b/gtk/gtkeventcontrollerscroll.c
@@ -66,6 +66,7 @@
#include "gtkprivate.h"
#define SCROLL_CAPTURE_THRESHOLD_MS 150
+#define HOLD_TIMEOUT_MS 50
typedef struct
{
@@ -84,6 +85,7 @@ struct _GtkEventControllerScroll
double cur_dx;
double cur_dy;
+ guint hold_timeout_id;
guint active : 1;
};
@@ -193,6 +195,7 @@ gtk_event_controller_scroll_finalize (GObject *object)
GtkEventControllerScroll *scroll = GTK_EVENT_CONTROLLER_SCROLL (object);
g_array_unref (scroll->scroll_history);
+ g_clear_handle_id (&scroll->hold_timeout_id, g_source_remove);
G_OBJECT_CLASS (gtk_event_controller_scroll_parent_class)->finalize (object);
}
@@ -272,6 +275,70 @@ gtk_event_controller_scroll_end (GtkEventController *controller)
return TRUE;
}
+static gboolean
+gtk_event_controller_scroll_hold_timeout (gpointer user_data)
+{
+ GtkEventController *controller;
+ GtkEventControllerScroll *scroll;
+
+ controller = user_data;
+ scroll = GTK_EVENT_CONTROLLER_SCROLL (controller);
+
+ gtk_event_controller_scroll_end (controller);
+ scroll->hold_timeout_id = 0;
+
+ return G_SOURCE_REMOVE;
+}
+
+static gboolean
+gtk_event_controller_scroll_handle_hold_event (GtkEventController *controller,
+ GdkEvent *event)
+{
+ GtkEventControllerScroll *scroll = GTK_EVENT_CONTROLLER_SCROLL (controller);
+ gboolean handled = GDK_EVENT_PROPAGATE;
+ GdkTouchpadGesturePhase phase;
+ guint n_fingers = 0;
+
+ if (gdk_event_get_event_type (event) != GDK_TOUCHPAD_HOLD)
+ return handled;
+
+ n_fingers = gdk_touchpad_event_get_n_fingers (event);
+ if (n_fingers != 1 && n_fingers != 2)
+ return handled;
+
+ if (scroll->hold_timeout_id != 0)
+ return handled;
+
+ phase = gdk_touchpad_event_get_gesture_phase (event);
+
+ switch (phase)
+ {
+ case GDK_TOUCHPAD_GESTURE_PHASE_BEGIN:
+ handled = gtk_event_controller_scroll_begin (controller);
+ break;
+
+ case GDK_TOUCHPAD_GESTURE_PHASE_END:
+ handled = gtk_event_controller_scroll_end (controller);
+ break;
+
+ case GDK_TOUCHPAD_GESTURE_PHASE_CANCEL:
+ if (scroll->hold_timeout_id == 0)
+ {
+ scroll->hold_timeout_id =
+ g_timeout_add (HOLD_TIMEOUT_MS,
+ gtk_event_controller_scroll_hold_timeout,
+ controller);
+ }
+ break;
+
+ case GDK_TOUCHPAD_GESTURE_PHASE_UPDATE:
+ default:
+ break;
+ }
+
+ return handled;
+}
+
static gboolean
gtk_event_controller_scroll_handle_event (GtkEventController *controller,
GdkEvent *event,
@@ -282,14 +349,22 @@ gtk_event_controller_scroll_handle_event (GtkEventController *controller,
GdkScrollDirection direction = GDK_SCROLL_SMOOTH;
double dx = 0, dy = 0;
gboolean handled = GDK_EVENT_PROPAGATE;
+ GdkEventType event_type;
+
+ event_type = gdk_event_get_event_type (event);
- if (gdk_event_get_event_type (event) != GDK_SCROLL)
+ if (event_type == GDK_TOUCHPAD_HOLD)
+ return gtk_event_controller_scroll_handle_hold_event (controller, event);
+
+ if (event_type != GDK_SCROLL)
return FALSE;
if ((scroll->flags & (GTK_EVENT_CONTROLLER_SCROLL_VERTICAL |
GTK_EVENT_CONTROLLER_SCROLL_HORIZONTAL)) == 0)
return FALSE;
+ g_clear_handle_id (&scroll->hold_timeout_id, g_source_remove);
+
/* FIXME: Handle device changes */
direction = gdk_scroll_event_get_direction (event);
if (direction == GDK_SCROLL_SMOOTH)
@@ -484,6 +559,7 @@ gtk_event_controller_scroll_init (GtkEventControllerScroll *scroll)
{
scroll->scroll_history = g_array_new (FALSE, FALSE,
sizeof (ScrollHistoryElem));
+ scroll->hold_timeout_id = 0;
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]