[gtk+] GtkRange: Fix an event propagation issue



commit e586dd2571a0ba6b97cd5667b9fbcd2ef0deb68e
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Sep 26 22:21:11 2014 -0400

    GtkRange: Fix an event propagation issue
    
    The scale in the selectable listbox in page 2 of gtk3-widget-factory
    has the flaw that the row is getting selected even when one only
    interacts with the scale - unlike e.g. the checkbutton and button
    further down in the listbox.
    
    The problem is that GtkRange is trying to claim the sequence for
    the drag gesture from the ::pressed handler of a multipress
    gesture. Since the drag gesture hasn't seen the sequence at this
    point, that is ineffective.
    
    The fix here is to rearrange the gestures so that the multipress
    gesture sees the sequence before the drag gesture, and then
    claim the sequence from the ::drag-begin handler.

 gtk/gtkrange.c |   38 ++++++++++++++++++++++++++++++--------
 1 files changed, 30 insertions(+), 8 deletions(-)
---
diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c
index 5d0c84d..bdf67cb 100644
--- a/gtk/gtkrange.c
+++ b/gtk/gtkrange.c
@@ -226,6 +226,10 @@ static void gtk_range_multipress_gesture_released (GtkGestureMultiPress *gesture
                                                    gdouble               x,
                                                    gdouble               y,
                                                    GtkRange             *range);
+static void gtk_range_drag_gesture_begin          (GtkGestureDrag       *gesture,
+                                                   gdouble               offset_x,
+                                                   gdouble               offset_y,
+                                                   GtkRange             *range);
 static void gtk_range_drag_gesture_update         (GtkGestureDrag       *gesture,
                                                    gdouble               offset_x,
                                                    gdouble               offset_y,
@@ -756,6 +760,20 @@ gtk_range_init (GtkRange *range)
 
   _gtk_orientable_set_style_classes (GTK_ORIENTABLE (range));
 
+  /* Note: Order is important here.
+   * The ::drag-begin handler relies on the state set up by the
+   * multipress ::pressed handler. Gestures are handling events
+   * in the oppposite order in which they are added to their
+   * widget.
+   */
+  priv->drag_gesture = gtk_gesture_drag_new (GTK_WIDGET (range));
+  g_signal_connect (priv->drag_gesture, "drag-begin",
+                    G_CALLBACK (gtk_range_drag_gesture_begin), range);
+  g_signal_connect (priv->drag_gesture, "drag-update",
+                    G_CALLBACK (gtk_range_drag_gesture_update), range);
+  g_signal_connect (priv->drag_gesture, "drag-end",
+                    G_CALLBACK (gtk_range_drag_gesture_end), range);
+
   priv->multipress_gesture = gtk_gesture_multi_press_new (GTK_WIDGET (range));
   gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (priv->multipress_gesture), 0);
   g_signal_connect (priv->multipress_gesture, "pressed",
@@ -763,12 +781,6 @@ gtk_range_init (GtkRange *range)
   g_signal_connect (priv->multipress_gesture, "released",
                     G_CALLBACK (gtk_range_multipress_gesture_released), range);
 
-  priv->drag_gesture = gtk_gesture_drag_new (GTK_WIDGET (range));
-  g_signal_connect (priv->drag_gesture, "drag-update",
-                    G_CALLBACK (gtk_range_drag_gesture_update), range);
-  g_signal_connect (priv->drag_gesture, "drag-end",
-                    G_CALLBACK (gtk_range_drag_gesture_end), range);
-
   priv->long_press_gesture = gtk_gesture_long_press_new (GTK_WIDGET (range));
   gtk_gesture_group (priv->drag_gesture, priv->long_press_gesture);
   g_signal_connect (priv->long_press_gesture, "pressed",
@@ -2621,8 +2633,8 @@ gtk_range_multipress_gesture_pressed (GtkGestureMultiPress *gesture,
         update_slider_position (range, x, y);
     }
 
-  if (priv->grab_location == MOUSE_SLIDER)
-    gtk_gesture_set_state (priv->drag_gesture, GTK_EVENT_SEQUENCE_CLAIMED);
+  if (priv->grab_location == MOUSE_SLIDER);
+    /* leave it to grab-begin to claim the sequence */
   else if (priv->grab_location != MOUSE_OUTSIDE)
     gtk_gesture_set_state (priv->multipress_gesture, GTK_EVENT_SEQUENCE_CLAIMED);
 }
@@ -2910,6 +2922,16 @@ gtk_range_drag_gesture_update (GtkGestureDrag *gesture,
 }
 
 static void
+gtk_range_drag_gesture_begin (GtkGestureDrag *gesture,
+                              gdouble         offset_x,
+                              gdouble         offset_y,
+                              GtkRange       *range)
+{
+  if (range->priv->grab_location == MOUSE_SLIDER)
+    gtk_gesture_set_state (range->priv->drag_gesture, GTK_EVENT_SEQUENCE_CLAIMED);
+}
+
+static void
 gtk_range_drag_gesture_end (GtkGestureDrag       *gesture,
                             gdouble               offset_x,
                             gdouble               offset_y,


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