[gtk+/gestures: 20/20] scrolledwindow: Use gesture button/touch press synthesization



commit 23643e2863751e262064d70c00c12ebe3e72010c
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon Mar 3 21:40:19 2014 +0100

    scrolledwindow: Use gesture button/touch press synthesization
    
    This makes scrolled window fully compatible again wrt the
    GtkScrolledWindow::capture-button-press property.

 gtk/gtkscrolledwindow.c |   70 +++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 61 insertions(+), 9 deletions(-)
---
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
index 56ce960..c77dce2 100644
--- a/gtk/gtkscrolledwindow.c
+++ b/gtk/gtkscrolledwindow.c
@@ -158,6 +158,7 @@ struct _GtkScrolledWindowPrivate
   GdkDevice             *drag_device;
   guint                  kinetic_scrolling         : 1;
   guint                  capture_button_press      : 1;
+  guint                  in_drag                   : 1;
 
   guint                  deceleration_id;
 
@@ -567,18 +568,24 @@ scrolled_window_drag_begin_cb (GtkScrolledWindow *scrolled_window,
                                GtkGesture        *gesture)
 {
   GtkScrolledWindowPrivate *priv = scrolled_window->priv;
+  GtkEventSequenceState state;
   GdkEventSequence *sequence;
 
+  priv->in_drag = FALSE;
   priv->drag_start_x = priv->unclamped_hadj_value;
   priv->drag_start_y = priv->unclamped_vadj_value;
   gtk_scrolled_window_cancel_deceleration (scrolled_window);
 
   if (!priv->hscrollbar_visible && !priv->vscrollbar_visible)
-    {
-      sequence = gtk_gesture_get_last_updated_sequence (gesture);
-      gtk_widget_set_sequence_state (GTK_WIDGET (scrolled_window),
-                                     sequence, GTK_EVENT_SEQUENCE_DENIED);
-    }
+    state = GTK_EVENT_SEQUENCE_DENIED;
+  else if (priv->capture_button_press)
+    state = GTK_EVENT_SEQUENCE_CLAIMED;
+  else
+    return;
+
+  sequence = gtk_gesture_get_last_updated_sequence (gesture);
+  gtk_widget_set_sequence_state (GTK_WIDGET (scrolled_window),
+                                 sequence, state);
 }
 
 static void
@@ -592,12 +599,16 @@ scrolled_window_drag_update_cb (GtkScrolledWindow *scrolled_window,
   gint new_overshoot_x, new_overshoot_y;
   GtkAdjustment *hadjustment;
   GtkAdjustment *vadjustment;
-  GdkEventSequence *sequence;
   gdouble dx, dy;
 
-  sequence = gtk_gesture_get_last_updated_sequence (gesture);
-  gtk_widget_set_sequence_state (GTK_WIDGET (scrolled_window),
-                                 sequence, GTK_EVENT_SEQUENCE_CLAIMED);
+  if (!priv->capture_button_press)
+    {
+      GdkEventSequence *sequence;
+
+      sequence = gtk_gesture_get_last_updated_sequence (gesture);
+      gtk_widget_set_sequence_state (GTK_WIDGET (scrolled_window),
+                                     sequence, GTK_EVENT_SEQUENCE_CLAIMED);
+    }
 
   _gtk_scrolled_window_get_overshoot (scrolled_window,
                                       &old_overshoot_x, &old_overshoot_y);
@@ -638,6 +649,24 @@ scrolled_window_drag_update_cb (GtkScrolledWindow *scrolled_window,
 }
 
 static void
+scrolled_window_drag_end_cb (GtkScrolledWindow *scrolled_window,
+                             gdouble            offset_x,
+                             gdouble            offset_y,
+                             GtkGesture        *gesture)
+{
+  GtkScrolledWindowPrivate *priv = scrolled_window->priv;
+
+  if (!priv->in_drag)
+    {
+      GdkEventSequence *sequence;
+
+      sequence = gtk_gesture_get_last_updated_sequence (gesture);
+      gtk_widget_set_sequence_state (GTK_WIDGET (scrolled_window),
+                                     sequence, GTK_EVENT_SEQUENCE_DENIED);
+    }
+}
+
+static void
 scrolled_window_swipe_cb (GtkScrolledWindow *scrolled_window,
                           gdouble            x_velocity,
                           gdouble            y_velocity)
@@ -676,6 +705,22 @@ scrolled_window_long_press_cb (GtkScrolledWindow *scrolled_window,
 }
 
 static void
+scrolled_window_long_press_cancelled_cb (GtkScrolledWindow *scrolled_window,
+                                         GtkGesture        *gesture)
+{
+  GtkScrolledWindowPrivate *priv = scrolled_window->priv;
+  GdkEventSequence *sequence;
+  const GdkEvent *event;
+
+  sequence = gtk_gesture_get_last_updated_sequence (gesture);
+  event = gtk_gesture_get_last_event (gesture, sequence);
+
+  if (event->type != GDK_TOUCH_END &&
+      event->type != GDK_BUTTON_RELEASE)
+    priv->in_drag = TRUE;
+}
+
+static void
 gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window)
 {
   GtkWidget *widget = GTK_WIDGET (scrolled_window);
@@ -705,15 +750,22 @@ gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window)
   g_signal_connect_swapped (priv->drag_gesture, "drag-update",
                             G_CALLBACK (scrolled_window_drag_update_cb),
                             scrolled_window);
+  g_signal_connect_swapped (priv->drag_gesture, "drag-end",
+                            G_CALLBACK (scrolled_window_drag_end_cb),
+                            scrolled_window);
 
   priv->swipe_gesture = gtk_gesture_swipe_new (widget);
   g_signal_connect_swapped (priv->swipe_gesture, "swipe",
                             G_CALLBACK (scrolled_window_swipe_cb),
                             scrolled_window);
   priv->long_press_gesture = gtk_gesture_long_press_new (widget);
+  gtk_gesture_long_press_set_button (GTK_GESTURE_LONG_PRESS (priv->long_press_gesture), 1);
   g_signal_connect_swapped (priv->long_press_gesture, "pressed",
                             G_CALLBACK (scrolled_window_long_press_cb),
                             scrolled_window);
+  g_signal_connect_swapped (priv->long_press_gesture, "cancelled",
+                            G_CALLBACK (scrolled_window_long_press_cancelled_cb),
+                            scrolled_window);
 
   gtk_scrolled_window_set_kinetic_scrolling (scrolled_window, TRUE);
   gtk_scrolled_window_set_capture_button_press (scrolled_window, TRUE);


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