[gtk+/wip/garnacho/touchpad-gestures: 62/71] gtkgesture: Handle touchpad events



commit 1abeb4babe7efa22bc8a1552ff88f5a3c8899e62
Author: Carlos Garnacho <carlosg gnome org>
Date:   Thu Jul 9 19:18:09 2015 +0200

    gtkgesture: Handle touchpad events
    
    These will be mutually exclusive with touch events, so it won't
    be possible to trigger gestures through mixed input and whatnot.
    
    The accounting of touchpad events is slightly different, there
    will be a single internal PointData struct, stored in the hashtable
    with the NULL event sequence/key (same than pointer events in
    this regard), just that the events stored will be GdkEventTouchpad*,
    so will hold information about all fingers at once.
    
    But this difference is just internal, the GtkGesture API doesn't
    make explicit assumptions about the number of points (the closest
    to a per-point query API is gtk_gesture_get_sequences()). All
    signals emitted just contain the last changed GdkEventSequence,
    and API takes GdkEventSequences, so everything is consistent with
    sequence=NULL for touchpad events.

 gtk/gtkgesture.c |   81 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 78 insertions(+), 3 deletions(-)
---
diff --git a/gtk/gtkgesture.c b/gtk/gtkgesture.c
index f44dcc8..f651cf8 100644
--- a/gtk/gtkgesture.c
+++ b/gtk/gtkgesture.c
@@ -152,12 +152,20 @@ struct _GtkGesturePrivate
   GList *group_link;
   guint n_points;
   guint recognized : 1;
+  guint touchpad : 1;
 };
 
 static guint signals[N_SIGNALS] = { 0 };
 
 #define BUTTONS_MASK (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)
 
+#define EVENT_IS_TOUCHPAD_GESTURE(e) ((e)->type == GDK_TOUCHPAD_SWIPE_BEGIN || \
+                                      (e)->type == GDK_TOUCHPAD_SWIPE_UPDATE || \
+                                      (e)->type == GDK_TOUCHPAD_SWIPE_END || \
+                                      (e)->type == GDK_TOUCHPAD_PINCH_BEGIN || \
+                                      (e)->type == GDK_TOUCHPAD_PINCH_UPDATE || \
+                                      (e)->type == GDK_TOUCHPAD_PINCH_END)
+
 GList * _gtk_gesture_get_group_link (GtkGesture *gesture);
 
 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GtkGesture, gtk_gesture, GTK_TYPE_EVENT_CONTROLLER)
@@ -220,6 +228,44 @@ gtk_gesture_finalize (GObject *object)
 }
 
 static guint
+_gtk_gesture_get_n_touchpad_points (GtkGesture *gesture,
+                                    gboolean    only_active)
+{
+  GtkGesturePrivate *priv;
+  PointData *data;
+
+  priv = gtk_gesture_get_instance_private (gesture);
+
+  if (!priv->touchpad)
+    return 0;
+
+  data = g_hash_table_lookup (priv->points, NULL);
+
+  if (!data)
+    return 0;
+
+  if (only_active &&
+      (data->state == GTK_EVENT_SEQUENCE_DENIED ||
+       data->event->type == GDK_TOUCHPAD_SWIPE_END ||
+       data->event->type == GDK_TOUCHPAD_PINCH_END))
+    return 0;
+
+  switch (data->event->type)
+    {
+    case GDK_TOUCHPAD_SWIPE_BEGIN:
+    case GDK_TOUCHPAD_SWIPE_UPDATE:
+    case GDK_TOUCHPAD_SWIPE_END:
+      return data->event->touchpad_swipe.n_fingers;
+    case GDK_TOUCHPAD_PINCH_BEGIN:
+    case GDK_TOUCHPAD_PINCH_UPDATE:
+    case GDK_TOUCHPAD_PINCH_END:
+      return data->event->touchpad_pinch.n_fingers;
+    default:
+      return 0;
+    }
+}
+
+static guint
 _gtk_gesture_get_n_touch_points (GtkGesture *gesture,
                                  gboolean    only_active)
 {
@@ -249,7 +295,14 @@ static guint
 _gtk_gesture_get_n_physical_points (GtkGesture *gesture,
                                     gboolean    only_active)
 {
-  return _gtk_gesture_get_n_touch_points (gesture, only_active);
+  GtkGesturePrivate *priv;
+
+  priv = gtk_gesture_get_instance_private (gesture);
+
+  if (priv->touchpad)
+    return _gtk_gesture_get_n_touchpad_points (gesture, only_active);
+  else
+    return _gtk_gesture_get_n_touch_points (gesture, only_active);
 }
 
 static gboolean
@@ -425,7 +478,7 @@ _gtk_gesture_update_point (GtkGesture     *gesture,
   GdkWindow *widget_window;
   GtkGesturePrivate *priv;
   GdkDevice *device;
-  gboolean existed;
+  gboolean existed, touchpad;
   PointData *data;
 
   if (!gdk_event_get_coords (event, NULL, NULL))
@@ -442,6 +495,8 @@ _gtk_gesture_update_point (GtkGesture     *gesture,
   if (!widget_window)
     return FALSE;
 
+  touchpad = EVENT_IS_TOUCHPAD_GESTURE (event);
+
   if (add)
     {
       /* If the event happens with the wrong device, or
@@ -453,6 +508,12 @@ _gtk_gesture_update_point (GtkGesture     *gesture,
         return FALSE;
       if (priv->user_window && priv->user_window != widget_window)
         return FALSE;
+
+      /* Make touchpad and touchscreen gestures mutually exclusive */
+      if (touchpad && g_hash_table_size (priv->points) > 0)
+        return FALSE;
+      else if (!touchpad && priv->touchpad)
+        return FALSE;
     }
   else if (!priv->device || !priv->window)
     return FALSE;
@@ -471,6 +532,7 @@ _gtk_gesture_update_point (GtkGesture     *gesture,
         {
           priv->window = widget_window;
           priv->device = device;
+          priv->touchpad = touchpad;
         }
 
       data = g_new0 (PointData, 1);
@@ -508,6 +570,7 @@ _gtk_gesture_check_empty (GtkGesture *gesture)
     {
       priv->window = NULL;
       priv->device = NULL;
+      priv->touchpad = FALSE;
     }
 }
 
@@ -609,6 +672,8 @@ gtk_gesture_handle_event (GtkEventController *controller,
     {
     case GDK_BUTTON_PRESS:
     case GDK_TOUCH_BEGIN:
+    case GDK_TOUCHPAD_SWIPE_BEGIN:
+    case GDK_TOUCHPAD_PINCH_BEGIN:
       if (_gtk_gesture_update_point (gesture, event, TRUE))
         {
           gboolean triggered_recognition;
@@ -639,6 +704,8 @@ gtk_gesture_handle_event (GtkEventController *controller,
       break;
     case GDK_BUTTON_RELEASE:
     case GDK_TOUCH_END:
+    case GDK_TOUCHPAD_SWIPE_END:
+    case GDK_TOUCHPAD_PINCH_END:
       if (_gtk_gesture_update_point (gesture, event, FALSE))
         {
           if (was_recognized &&
@@ -657,12 +724,20 @@ gtk_gesture_handle_event (GtkEventController *controller,
 
       /* Fall through */
     case GDK_TOUCH_UPDATE:
+    case GDK_TOUCHPAD_SWIPE_UPDATE:
+    case GDK_TOUCHPAD_PINCH_UPDATE:
       if (_gtk_gesture_update_point (gesture, event, FALSE) &&
           _gtk_gesture_check_recognized (gesture, sequence))
         g_signal_emit (gesture, signals[UPDATE], 0, sequence);
       break;
     case GDK_TOUCH_CANCEL:
-      _gtk_gesture_cancel_sequence (gesture, sequence);
+      if (!priv->touchpad)
+        _gtk_gesture_cancel_sequence (gesture, sequence);
+      break;
+    case GDK_TOUCHPAD_SWIPE_CANCEL:
+    case GDK_TOUCHPAD_PINCH_CANCEL:
+      if (priv->touchpad)
+        _gtk_gesture_cancel_sequence (gesture, sequence);
       break;
     case GDK_GRAB_BROKEN:
       if (!event->grab_broken.grab_window ||


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]