[gtk+] gesture: Replace gtk_gesture_attach/detach with event controller API



commit d05a9f9a7b2371b13bf9ec766482f1bb15a3853e
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon May 26 14:02:30 2014 +0200

    gesture: Replace gtk_gesture_attach/detach with event controller API
    
    Event controllers now auto-attach, and the GtkCapturePhase only determines
    when are events dispatched, but all controllers are managed by the widget wrt
    grabs.
    
    All callers have been updated.

 demos/gtk-demo/gestures.c            |   20 ++++---
 docs/reference/gtk/gtk3-sections.txt |    6 +-
 gtk/gtkbutton.c                      |    9 +--
 gtk/gtkcolorplane.c                  |    9 +--
 gtk/gtkcolorscale.c                  |    4 +-
 gtk/gtkcolorswatch.c                 |    9 +--
 gtk/gtkdnd.c                         |    2 -
 gtk/gtkentry.c                       |    9 ++-
 gtk/gtkeventcontroller.c             |  106 +++++++++++++++++++++++++++++++++-
 gtk/gtkeventcontroller.h             |    7 ++
 gtk/gtkgesture.c                     |   60 +------------------
 gtk/gtkgesture.h                     |    6 --
 gtk/gtkpaned.c                       |    4 +-
 gtk/gtkrange.c                       |   12 +---
 gtk/gtkscrolledwindow.c              |   26 ++++-----
 gtk/gtkspinbutton.c                  |    4 +-
 gtk/gtkswitch.c                      |    9 ++-
 gtk/gtktextview.c                    |    9 +--
 gtk/gtktreeview.c                    |    9 +--
 gtk/gtkwidget.c                      |   41 +++++++------
 gtk/gtkwidgetprivate.h               |    3 +-
 gtk/gtkwindow.c                      |    8 +--
 22 files changed, 209 insertions(+), 163 deletions(-)
---
diff --git a/demos/gtk-demo/gestures.c b/demos/gtk-demo/gestures.c
index dd27cdb..77da335 100644
--- a/demos/gtk-demo/gestures.c
+++ b/demos/gtk-demo/gestures.c
@@ -156,8 +156,9 @@ do_gestures (GtkWidget *do_widget)
       gesture = gtk_gesture_swipe_new (drawing_area);
       g_signal_connect (gesture, "swipe",
                         G_CALLBACK (swipe_gesture_swept), drawing_area);
-      gtk_gesture_attach (gesture, GTK_PHASE_BUBBLE);
-      g_object_unref (gesture);
+      gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
+                                                  GTK_PHASE_BUBBLE);
+      g_object_weak_ref (G_OBJECT (drawing_area), (GWeakNotify) g_object_unref, gesture);
 
       /* Long press */
       gesture = gtk_gesture_long_press_new (drawing_area);
@@ -165,22 +166,25 @@ do_gestures (GtkWidget *do_widget)
                         G_CALLBACK (long_press_gesture_pressed), drawing_area);
       g_signal_connect (gesture, "end",
                         G_CALLBACK (long_press_gesture_end), drawing_area);
-      gtk_gesture_attach (gesture, GTK_PHASE_BUBBLE);
-      g_object_unref (gesture);
+      gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
+                                                  GTK_PHASE_BUBBLE);
+      g_object_weak_ref (G_OBJECT (drawing_area), (GWeakNotify) g_object_unref, gesture);
 
       /* Rotate */
       rotate = gesture = gtk_gesture_rotate_new (drawing_area);
       g_signal_connect (gesture, "angle-changed",
                         G_CALLBACK (rotation_angle_changed), drawing_area);
-      gtk_gesture_attach (gesture, GTK_PHASE_BUBBLE);
-      g_object_unref (gesture);
+      gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
+                                                  GTK_PHASE_BUBBLE);
+      g_object_weak_ref (G_OBJECT (drawing_area), (GWeakNotify) g_object_unref, gesture);
 
       /* Zoom */
       zoom = gesture = gtk_gesture_zoom_new (drawing_area);
       g_signal_connect (gesture, "scale-changed",
                         G_CALLBACK (zoom_scale_changed), drawing_area);
-      gtk_gesture_attach (gesture, GTK_PHASE_BUBBLE);
-      g_object_unref (gesture);
+      gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
+                                                  GTK_PHASE_BUBBLE);
+      g_object_weak_ref (G_OBJECT (drawing_area), (GWeakNotify) g_object_unref, gesture);
     }
 
   if (!gtk_widget_get_visible (window))
diff --git a/docs/reference/gtk/gtk3-sections.txt b/docs/reference/gtk/gtk3-sections.txt
index f850feb..8a30cf5 100644
--- a/docs/reference/gtk/gtk3-sections.txt
+++ b/docs/reference/gtk/gtk3-sections.txt
@@ -7898,6 +7898,9 @@ gtk_popover_get_modal
 <FILE>gtkeventcontroller</FILE>
 <TITLE>GtkEventController</TITLE>
 GtkEventController
+GtkPropagationPhase
+gtk_event_controller_get_propagation_phase
+gtk_event_controller_set_propagation_phase
 gtk_event_controller_handle_event
 gtk_event_controller_get_widget
 gtk_event_controller_reset
@@ -7929,9 +7932,6 @@ gtk_gesture_set_sequence_state
 gtk_gesture_set_state
 gtk_gesture_get_sequences
 gtk_gesture_handles_sequence
-GtkPropagationPhase
-gtk_gesture_attach
-gtk_gesture_detach
 
 <SUBSECTION>
 gtk_gesture_get_last_updated_sequence
diff --git a/gtk/gtkbutton.c b/gtk/gtkbutton.c
index 589b0ec..3e10ec6 100644
--- a/gtk/gtkbutton.c
+++ b/gtk/gtkbutton.c
@@ -653,7 +653,7 @@ gtk_button_init (GtkButton *button)
   gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (priv->gesture), GDK_BUTTON_PRIMARY);
   g_signal_connect (priv->gesture, "pressed", G_CALLBACK (multipress_pressed_cb), button);
   g_signal_connect (priv->gesture, "released", G_CALLBACK (multipress_released_cb), button);
-  gtk_gesture_attach (priv->gesture, GTK_PHASE_TARGET);
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->gesture), GTK_PHASE_TARGET);
 }
 
 static void
@@ -668,12 +668,7 @@ gtk_button_destroy (GtkWidget *widget)
       priv->label_text = NULL;
     }
 
-  if (priv->gesture)
-    {
-      gtk_gesture_detach (priv->gesture);
-      g_object_unref (priv->gesture);
-      priv->gesture = NULL;
-    }
+  g_clear_object (&priv->gesture);
 
   GTK_WIDGET_CLASS (gtk_button_parent_class)->destroy (widget);
 }
diff --git a/gtk/gtkcolorplane.c b/gtk/gtkcolorplane.c
index 0b232f7..ddad1df 100644
--- a/gtk/gtkcolorplane.c
+++ b/gtk/gtkcolorplane.c
@@ -409,14 +409,16 @@ gtk_color_plane_init (GtkColorPlane *plane)
                    G_CALLBACK (plane_drag_gesture_update), plane);
   g_signal_connect (plane->priv->drag_gesture, "drag-end",
                    G_CALLBACK (plane_drag_gesture_end), plane);
-  gtk_gesture_attach (plane->priv->drag_gesture, GTK_PHASE_TARGET);
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (plane->priv->drag_gesture),
+                                              GTK_PHASE_TARGET);
   gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (plane->priv->drag_gesture),
                                      FALSE);
 
   plane->priv->long_press_gesture = gtk_gesture_long_press_new (GTK_WIDGET (plane));
   g_signal_connect (plane->priv->long_press_gesture, "pressed",
                     G_CALLBACK (hold_action), plane);
-  gtk_gesture_attach (plane->priv->long_press_gesture, GTK_PHASE_TARGET);
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (plane->priv->long_press_gesture),
+                                              GTK_PHASE_TARGET);
 }
 
 static void
@@ -431,10 +433,7 @@ plane_finalize (GObject *object)
   g_clear_object (&plane->priv->s_adj);
   g_clear_object (&plane->priv->v_adj);
 
-  gtk_gesture_detach (plane->priv->drag_gesture);
   g_clear_object (&plane->priv->drag_gesture);
-
-  gtk_gesture_detach (plane->priv->long_press_gesture);
   g_clear_object (&plane->priv->long_press_gesture);
 
   G_OBJECT_CLASS (gtk_color_plane_parent_class)->finalize (object);
diff --git a/gtk/gtkcolorscale.c b/gtk/gtkcolorscale.c
index 0331b04..9a60579 100644
--- a/gtk/gtkcolorscale.c
+++ b/gtk/gtkcolorscale.c
@@ -258,7 +258,8 @@ gtk_color_scale_init (GtkColorScale *scale)
   scale->priv->long_press_gesture = gtk_gesture_long_press_new (GTK_WIDGET (scale));
   g_signal_connect (scale->priv->long_press_gesture, "pressed",
                     G_CALLBACK (hold_action), scale);
-  gtk_gesture_attach (scale->priv->long_press_gesture, GTK_PHASE_BUBBLE);
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (scale->priv->long_press_gesture),
+                                              GTK_PHASE_BUBBLE);
 }
 
 static void
@@ -269,7 +270,6 @@ scale_finalize (GObject *object)
   if (scale->priv->surface)
     cairo_surface_destroy (scale->priv->surface);
 
-  gtk_gesture_detach (scale->priv->long_press_gesture);
   g_clear_object (&scale->priv->long_press_gesture);
 
   G_OBJECT_CLASS (gtk_color_scale_parent_class)->finalize (object);
diff --git a/gtk/gtkcolorswatch.c b/gtk/gtkcolorswatch.c
index f9ebbeb..e36f79c 100644
--- a/gtk/gtkcolorswatch.c
+++ b/gtk/gtkcolorswatch.c
@@ -90,13 +90,15 @@ gtk_color_swatch_init (GtkColorSwatch *swatch)
   swatch->priv->long_press_gesture = gtk_gesture_long_press_new (GTK_WIDGET (swatch));
   g_signal_connect (swatch->priv->long_press_gesture, "pressed",
                     G_CALLBACK (hold_action), swatch);
-  gtk_gesture_attach (swatch->priv->long_press_gesture, GTK_PHASE_TARGET);
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (swatch->priv->long_press_gesture),
+                                              GTK_PHASE_TARGET);
 
   swatch->priv->multipress_gesture = gtk_gesture_multi_press_new (GTK_WIDGET (swatch));
   gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (swatch->priv->multipress_gesture), FALSE);
   g_signal_connect (swatch->priv->multipress_gesture, "pressed",
                     G_CALLBACK (tap_action), swatch);
-  gtk_gesture_attach (swatch->priv->multipress_gesture, GTK_PHASE_TARGET);
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (swatch->priv->multipress_gesture),
+                                              GTK_PHASE_TARGET);
 }
 
 #define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
@@ -694,10 +696,7 @@ swatch_finalize (GObject *object)
 
   g_free (swatch->priv->icon);
 
-  gtk_gesture_detach (swatch->priv->long_press_gesture);
   g_object_unref (swatch->priv->long_press_gesture);
-
-  gtk_gesture_detach (swatch->priv->multipress_gesture);
   g_object_unref (swatch->priv->multipress_gesture);
 
   G_OBJECT_CLASS (gtk_color_swatch_parent_class)->finalize (object);
diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c
index 49e93c5..124ae74 100644
--- a/gtk/gtkdnd.c
+++ b/gtk/gtkdnd.c
@@ -2801,7 +2801,6 @@ gtk_drag_source_set (GtkWidget            *widget,
       site->drag_gesture = gtk_gesture_drag_new (widget);
       gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (site->drag_gesture),
                                          FALSE);
-      gtk_gesture_attach (site->drag_gesture, GTK_PHASE_NONE);
 
       g_signal_connect (widget, "button-press-event",
                        G_CALLBACK (gtk_drag_source_event_cb),
@@ -2844,7 +2843,6 @@ gtk_drag_source_unset (GtkWidget *widget)
       g_signal_handlers_disconnect_by_func (widget,
                                             gtk_drag_source_event_cb,
                                             site);
-      gtk_gesture_detach (site->drag_gesture);
       g_object_set_data (G_OBJECT (widget), I_("gtk-site-data"), NULL);
     }
 }
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index ed96871..b2c7390 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -2701,14 +2701,16 @@ gtk_entry_init (GtkEntry *entry)
                     G_CALLBACK (gtk_entry_drag_gesture_end), entry);
   gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (priv->drag_gesture), FALSE);
   gtk_gesture_single_set_exclusive (GTK_GESTURE_SINGLE (priv->drag_gesture), TRUE);
-  gtk_gesture_attach (priv->drag_gesture, GTK_PHASE_TARGET);
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->drag_gesture),
+                                              GTK_PHASE_TARGET);
 
   priv->multipress_gesture = gtk_gesture_multi_press_new (GTK_WIDGET (entry));
   g_signal_connect (priv->multipress_gesture, "pressed",
                     G_CALLBACK (gtk_entry_multipress_gesture_pressed), entry);
   gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (priv->multipress_gesture), FALSE);
   gtk_gesture_single_set_exclusive (GTK_GESTURE_SINGLE (priv->multipress_gesture), TRUE);
-  gtk_gesture_attach (priv->multipress_gesture, GTK_PHASE_TARGET);
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->multipress_gesture),
+                                              GTK_PHASE_TARGET);
 }
 
 static void
@@ -2988,6 +2990,9 @@ gtk_entry_finalize (GObject *object)
   g_free (priv->placeholder_text);
   g_free (priv->im_module);
 
+  g_clear_object (&priv->drag_gesture);
+  g_clear_object (&priv->multipress_gesture);
+
   if (priv->tabs)
     pango_tab_array_free (priv->tabs);
 
diff --git a/gtk/gtkeventcontroller.c b/gtk/gtkeventcontroller.c
index 84a2702..248d879 100644
--- a/gtk/gtkeventcontroller.c
+++ b/gtk/gtkeventcontroller.c
@@ -32,6 +32,7 @@
 #include "config.h"
 #include "gtkeventcontroller.h"
 #include "gtkeventcontrollerprivate.h"
+#include "gtkwidgetprivate.h"
 #include "gtktypebuiltins.h"
 #include "gtkmarshalers.h"
 #include "gtkprivate.h"
@@ -40,7 +41,8 @@
 typedef struct _GtkEventControllerPrivate GtkEventControllerPrivate;
 
 enum {
-  PROP_WIDGET = 1
+  PROP_WIDGET = 1,
+  PROP_PROPAGATION_PHASE
 };
 
 enum {
@@ -53,6 +55,7 @@ struct _GtkEventControllerPrivate
 {
   GtkWidget *widget;
   guint evmask;
+  GtkPropagationPhase phase;
 };
 
 guint signals[N_SIGNALS] = { 0 };
@@ -81,6 +84,10 @@ gtk_event_controller_set_property (GObject      *object,
     case PROP_WIDGET:
       priv->widget = g_value_get_object (value);
       break;
+    case PROP_PROPAGATION_PHASE:
+      gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (object),
+                                                  g_value_get_enum (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -101,11 +108,34 @@ gtk_event_controller_get_property (GObject    *object,
     case PROP_WIDGET:
       g_value_set_object (value, priv->widget);
       break;
+    case PROP_PROPAGATION_PHASE:
+      g_value_set_enum (value, priv->phase);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
 }
 
+static void
+gtk_event_controller_constructed (GObject *object)
+{
+  GtkEventController *controller = GTK_EVENT_CONTROLLER (object);
+  GtkEventControllerPrivate *priv;
+
+  priv = gtk_event_controller_get_instance_private (controller);
+  g_assert (priv->widget != NULL);
+  _gtk_widget_add_controller (priv->widget, controller);
+}
+
+static void
+gtk_event_controller_dispose (GObject *object)
+{
+  GtkEventController *controller = GTK_EVENT_CONTROLLER (object);
+  GtkEventControllerPrivate *priv;
+
+  priv = gtk_event_controller_get_instance_private (controller);
+  _gtk_widget_remove_controller (priv->widget, controller);
+}
 
 static void
 gtk_event_controller_class_init (GtkEventControllerClass *klass)
@@ -116,6 +146,8 @@ gtk_event_controller_class_init (GtkEventControllerClass *klass)
 
   object_class->set_property = gtk_event_controller_set_property;
   object_class->get_property = gtk_event_controller_get_property;
+  object_class->constructed = gtk_event_controller_constructed;
+  object_class->dispose = gtk_event_controller_dispose;
 
   /**
    * GtkEventController:widget:
@@ -133,6 +165,21 @@ gtk_event_controller_class_init (GtkEventControllerClass *klass)
                                                         GTK_PARAM_READWRITE |
                                                         G_PARAM_CONSTRUCT_ONLY));
   /**
+   * GtkEventController:propagation-phase:
+   *
+   * The propagation phase at which this controller will handle events.
+   *
+   * Since: 3.14
+   */
+  g_object_class_install_property (object_class,
+                                   PROP_PROPAGATION_PHASE,
+                                   g_param_spec_enum ("propagation-phase",
+                                                      P_("Propagation phase"),
+                                                      P_("Propagation phase at which this controller is 
run"),
+                                                      GTK_TYPE_PROPAGATION_PHASE,
+                                                      GTK_PHASE_NONE,
+                                                      GTK_PARAM_READWRITE));
+  /**
    * GtkEventController::handle-event:
    * @controller: the object which receives the signal
    * @event: the event to handle
@@ -269,3 +316,60 @@ gtk_event_controller_reset (GtkEventController *controller)
 
   g_signal_emit (controller, signals[RESET], 0);
 }
+
+/**
+ * gtk_event_controller_get_propagation_phase:
+ * @controller: a #GtkEventController
+ *
+ * Gets the propagation phase at which @controller handles events.
+ *
+ * Returns: the propagation phase
+ *
+ * Since: 3.14
+ **/
+GtkPropagationPhase
+gtk_event_controller_get_propagation_phase (GtkEventController *controller)
+{
+  GtkEventControllerPrivate *priv;
+
+  g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER (controller), GTK_PHASE_NONE);
+
+  priv = gtk_event_controller_get_instance_private (controller);
+
+  return priv->phase;
+}
+
+/**
+ * gtk_event_controller_set_propagation_phase:
+ * @controller: a #GtkEventController
+ * @phase: a propagation phase
+ *
+ * Sets the propagation phase at which a controller handles events.
+ *
+ * If @phase is %GTK_PHASE_NONE, no automatic event handling will be
+ * performed, but other additional gesture maintenance will. In that phase,
+ * the events can be managed by calling gtk_event_controller_handle_event().
+ *
+ * Since: 3.14
+ **/
+void
+gtk_event_controller_set_propagation_phase (GtkEventController  *controller,
+                                            GtkPropagationPhase  phase)
+{
+  GtkEventControllerPrivate *priv;
+
+  g_return_if_fail (GTK_IS_EVENT_CONTROLLER (controller));
+  g_return_if_fail (phase >= GTK_PHASE_NONE && phase <= GTK_PHASE_TARGET);
+
+  priv = gtk_event_controller_get_instance_private (controller);
+
+  if (priv->phase == phase)
+    return;
+
+  priv->phase = phase;
+
+  if (phase == GTK_PHASE_NONE)
+    gtk_event_controller_reset (controller);
+
+  g_object_notify (G_OBJECT (controller), "propagation-phase");
+}
diff --git a/gtk/gtkeventcontroller.h b/gtk/gtkeventcontroller.h
index 3069cef..d53844e 100644
--- a/gtk/gtkeventcontroller.h
+++ b/gtk/gtkeventcontroller.h
@@ -53,6 +53,13 @@ gboolean     gtk_event_controller_handle_event   (GtkEventController *controller
 GDK_AVAILABLE_IN_3_14
 void         gtk_event_controller_reset          (GtkEventController *controller);
 
+GDK_AVAILABLE_IN_3_14
+GtkPropagationPhase gtk_event_controller_get_propagation_phase (GtkEventController *controller);
+
+GDK_AVAILABLE_IN_3_14
+void                gtk_event_controller_set_propagation_phase (GtkEventController  *controller,
+                                                                GtkPropagationPhase  phase);
+
 G_END_DECLS
 
 #endif /* __GTK_EVENT_CONTROLLER_H__ */
diff --git a/gtk/gtkgesture.c b/gtk/gtkgesture.c
index d4b400d..315fffc 100644
--- a/gtk/gtkgesture.c
+++ b/gtk/gtkgesture.c
@@ -46,9 +46,9 @@
  *
  * ## Event propagation
  *
- * To receive events, a gesture needs to first be attached to its widget with
- * gtk_gesture_attach(). The phase passed to this call determines at which
- * point in the event processing a gesture operates.
+ * In order to receive events, a gesture needs to either set a propagation phase
+ * through gtk_event_controller_set_propagation_phase(), or feed those manually
+ * through gtk_event_controller_handle_event().
  *
  * In the capture phase, events are propagated from the toplevel down to the
  * target widget, and gestures that are attached to containers above the widget
@@ -56,17 +56,13 @@
  *
  * After the capture phase, GTK+ emits the traditional #GtkWidget::button-press,
  * #GtkWidget::button-release, #GtkWidget::touch-event, etc signals. Gestures 
- * with the target phase are fed events from the default #GtkWidget::event
+ * with the %GTK_PHASE_TARGET phase are fed events from the default #GtkWidget::event
  * handlers.
  *
  * In the bubble phase, events are propagated up from the target widget to the
  * toplevel, and gestures that are attached to containers above the widget get
  * a chance to interact with events that have not been handled yet.
  *
- * Gestures attached with the phase 'none' are not receiving any events
- * automatically, but events can be passed to them with
- * gtk_event_controller_handle_event().
- *
  * ## States of a sequence # {#touch-sequence-states}
  *
  * Whenever input interaction happens, a single event may trigger a cascade of
@@ -1547,51 +1543,3 @@ _gtk_gesture_get_pointer_emulating_sequence (GtkGesture        *gesture,
 
   return FALSE;
 }
-
-/**
- * gtk_gesture_attach:
- * @gesture: a #GtkGesture
- * @phase: phase at which events are handled
- *
- * Attaches @gesture to its widget, so @gesture is able to receive
- * and manage the events that are emitted on the #GtkWidget. This call
- * will also make sure that the gesture state is maintained properly
- * whenever input is grabbed elsewhere.
- *
- * If @phase is %GTK_PHASE_NONE, no automatical event handling will be
- * performed, but other additional gesture maintenance will. The events
- * can be managed by calling gtk_event_controller_handle_event().
- *
- * Since: 3.14
- **/
-void
-gtk_gesture_attach (GtkGesture          *gesture,
-                    GtkPropagationPhase  phase)
-{
-  GtkWidget *widget;
-
-  g_return_if_fail (GTK_IS_GESTURE (gesture));
-  g_return_if_fail (phase >= GTK_PHASE_NONE && phase <= GTK_PHASE_TARGET);
-
-  widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
-  _gtk_widget_add_controller (widget, GTK_EVENT_CONTROLLER (gesture), phase);
-}
-
-/**
- * gtk_gesture_detach:
- * @gesture: a #GtkGesture
- *
- * Detaches @gesture from its widget.
- *
- * Since: 3.14
- **/
-void
-gtk_gesture_detach (GtkGesture *gesture)
-{
-  GtkWidget *widget;
-
-  g_return_if_fail (GTK_IS_GESTURE (gesture));
-
-  widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
-  _gtk_widget_remove_controller (widget, GTK_EVENT_CONTROLLER (gesture));
-}
diff --git a/gtk/gtkgesture.h b/gtk/gtkgesture.h
index e3e4938..671f811 100644
--- a/gtk/gtkgesture.h
+++ b/gtk/gtkgesture.h
@@ -109,12 +109,6 @@ GDK_AVAILABLE_IN_3_14
 gboolean    gtk_gesture_is_grouped_with      (GtkGesture       *gesture,
                                               GtkGesture       *other);
 
-GDK_AVAILABLE_IN_3_14
-void        gtk_gesture_attach               (GtkGesture          *gesture,
-                                              GtkPropagationPhase  phase);
-GDK_AVAILABLE_IN_3_14
-void        gtk_gesture_detach               (GtkGesture          *gesture);
-
 G_END_DECLS
 
 #endif /* __GTK_GESTURE_H__ */
diff --git a/gtk/gtkpaned.c b/gtk/gtkpaned.c
index b10a7df..f848531 100644
--- a/gtk/gtkpaned.c
+++ b/gtk/gtkpaned.c
@@ -801,7 +801,8 @@ gtk_paned_init (GtkPaned *paned)
                     G_CALLBACK (pan_gesture_pan_cb), paned);
   g_signal_connect (gesture, "drag-end",
                     G_CALLBACK (pan_gesture_drag_end_cb), paned);
-  gtk_gesture_attach (gesture, GTK_PHASE_CAPTURE);
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
+                                              GTK_PHASE_CAPTURE);
   priv->pan_gesture = gesture;
 }
 
@@ -971,7 +972,6 @@ gtk_paned_finalize (GObject *object)
   gtk_paned_set_saved_focus (paned, NULL);
   gtk_paned_set_first_paned (paned, NULL);
 
-  gtk_gesture_detach (paned->priv->pan_gesture);
   g_clear_object (&paned->priv->pan_gesture);
 
   G_OBJECT_CLASS (gtk_paned_parent_class)->finalize (object);
diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c
index b8ab861..31e379d 100644
--- a/gtk/gtkrange.c
+++ b/gtk/gtkrange.c
@@ -1505,11 +1505,7 @@ gtk_range_destroy (GtkWidget *widget)
 
   gtk_range_remove_step_timer (range);
 
-  if (priv->long_press_gesture)
-    {
-      gtk_gesture_detach (priv->long_press_gesture);
-      g_clear_object (&priv->long_press_gesture);
-    }
+  g_clear_object (&priv->long_press_gesture);
 
   if (priv->adjustment)
     {
@@ -2368,10 +2364,7 @@ update_zoom_set (GtkRange *range,
                  gboolean  zoom_set)
 {
   if (zoom_set)
-    {
-      gtk_gesture_detach (range->priv->long_press_gesture);
-      g_clear_object (&range->priv->long_press_gesture);
-    }
+    g_clear_object (&range->priv->long_press_gesture);
 
   range->priv->zoom_set = zoom_set;
 }
@@ -2711,7 +2704,6 @@ gtk_range_button_press (GtkWidget      *widget,
                   gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (priv->long_press_gesture),
                                                      FALSE);
                   gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (priv->long_press_gesture), 1);
-                  gtk_gesture_attach (priv->long_press_gesture, GTK_PHASE_NONE);
 
                   g_signal_connect (priv->long_press_gesture, "pressed",
                                     G_CALLBACK (hold_action), range);
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
index 1b5c4df..f17d58f 100644
--- a/gtk/gtkscrolledwindow.c
+++ b/gtk/gtkscrolledwindow.c
@@ -724,6 +724,7 @@ scrolled_window_long_press_cancelled_cb (GtkScrolledWindow *scrolled_window,
 static void
 gtk_scrolled_window_check_attach_pan_gesture (GtkScrolledWindow *sw)
 {
+  GtkPropagationPhase phase = GTK_PHASE_NONE;
   GtkScrolledWindowPrivate *priv = sw->priv;
 
   if (priv->kinetic_scrolling &&
@@ -739,10 +740,10 @@ gtk_scrolled_window_check_attach_pan_gesture (GtkScrolledWindow *sw)
 
       gtk_gesture_pan_set_orientation (GTK_GESTURE_PAN (priv->pan_gesture),
                                        orientation);
-      gtk_gesture_attach (priv->pan_gesture, GTK_PHASE_CAPTURE);
+      phase = GTK_PHASE_CAPTURE;
     }
-  else
-    gtk_gesture_detach (priv->pan_gesture);
+
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->pan_gesture), phase);
 }
 
 static void
@@ -1267,6 +1268,7 @@ void
 gtk_scrolled_window_set_kinetic_scrolling (GtkScrolledWindow *scrolled_window,
                                            gboolean           kinetic_scrolling)
 {
+  GtkPropagationPhase phase = GTK_PHASE_NONE;
   GtkScrolledWindowPrivate *priv;
 
   g_return_if_fail (GTK_IS_SCROLLED_WINDOW (scrolled_window));
@@ -1279,19 +1281,15 @@ gtk_scrolled_window_set_kinetic_scrolling (GtkScrolledWindow *scrolled_window,
   gtk_scrolled_window_check_attach_pan_gesture (scrolled_window);
 
   if (priv->kinetic_scrolling)
-    {
-      gtk_gesture_attach (priv->drag_gesture, GTK_PHASE_CAPTURE);
-      gtk_gesture_attach (priv->swipe_gesture, GTK_PHASE_CAPTURE);
-      gtk_gesture_attach (priv->long_press_gesture, GTK_PHASE_CAPTURE);
-    }
+    phase = GTK_PHASE_CAPTURE;
   else
-    {
-      gtk_gesture_detach (priv->drag_gesture);
-      gtk_gesture_detach (priv->swipe_gesture);
-      gtk_gesture_detach (priv->long_press_gesture);
+    gtk_scrolled_window_cancel_deceleration (scrolled_window);
+
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->drag_gesture), phase);
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->swipe_gesture), phase);
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->long_press_gesture), phase);
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->pan_gesture), phase);
 
-      gtk_scrolled_window_cancel_deceleration (scrolled_window);
-    }
   g_object_notify (G_OBJECT (scrolled_window), "kinetic-scrolling");
 }
 
diff --git a/gtk/gtkspinbutton.c b/gtk/gtkspinbutton.c
index 90857af..26b0d14 100644
--- a/gtk/gtkspinbutton.c
+++ b/gtk/gtkspinbutton.c
@@ -710,7 +710,8 @@ gtk_spin_button_init (GtkSpinButton *spin_button)
   gtk_widget_add_events (GTK_WIDGET (spin_button), GDK_SCROLL_MASK);
 
   priv->swipe_gesture = gtk_gesture_swipe_new (GTK_WIDGET (spin_button));
-  gtk_gesture_attach (priv->swipe_gesture, GTK_PHASE_CAPTURE);
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->swipe_gesture),
+                                              GTK_PHASE_CAPTURE);
   g_signal_connect (priv->swipe_gesture, "begin",
                     G_CALLBACK (swipe_gesture_begin), spin_button);
   g_signal_connect (priv->swipe_gesture, "update",
@@ -731,7 +732,6 @@ gtk_spin_button_finalize (GObject *object)
   if (priv->up_panel_context)
     g_object_unref (priv->up_panel_context);
 
-  gtk_gesture_detach (priv->swipe_gesture);
   g_object_unref (priv->swipe_gesture);
 
   G_OBJECT_CLASS (gtk_spin_button_parent_class)->finalize (object);
diff --git a/gtk/gtkswitch.c b/gtk/gtkswitch.c
index 7038d09..ed305b0 100644
--- a/gtk/gtkswitch.c
+++ b/gtk/gtkswitch.c
@@ -749,6 +749,9 @@ gtk_switch_dispose (GObject *object)
       priv->action = NULL;
     }
 
+  g_clear_object (&priv->pan_gesture);
+  g_clear_object (&priv->multipress_gesture);
+
   G_OBJECT_CLASS (gtk_switch_parent_class)->dispose (object);
 }
 
@@ -924,7 +927,8 @@ gtk_switch_init (GtkSwitch *self)
                     G_CALLBACK (gtk_switch_multipress_gesture_pressed), self);
   g_signal_connect (gesture, "released",
                     G_CALLBACK (gtk_switch_multipress_gesture_released), self);
-  gtk_gesture_attach (gesture, GTK_PHASE_TARGET);
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
+                                              GTK_PHASE_TARGET);
   self->priv->multipress_gesture = gesture;
 
   gesture = gtk_gesture_pan_new (GTK_WIDGET (self),
@@ -935,7 +939,8 @@ gtk_switch_init (GtkSwitch *self)
                     G_CALLBACK (gtk_switch_pan_gesture_pan), self);
   g_signal_connect (gesture, "drag-end",
                     G_CALLBACK (gtk_switch_pan_gesture_drag_end), self);
-  gtk_gesture_attach (gesture, GTK_PHASE_TARGET);
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
+                                              GTK_PHASE_TARGET);
   self->priv->pan_gesture = gesture;
 }
 
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c
index d793952..6552af2 100644
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@ -1555,7 +1555,8 @@ gtk_text_view_init (GtkTextView *text_view)
   priv->multipress_gesture = gtk_gesture_multi_press_new (widget);
   gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (priv->multipress_gesture),
                                      FALSE);
-  gtk_gesture_attach (priv->multipress_gesture, GTK_PHASE_TARGET);
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->multipress_gesture),
+                                              GTK_PHASE_TARGET);
   g_signal_connect (priv->multipress_gesture, "pressed",
                     G_CALLBACK (gtk_text_view_multipress_gesture_pressed),
                     widget);
@@ -1563,7 +1564,8 @@ gtk_text_view_init (GtkTextView *text_view)
   priv->drag_gesture = gtk_gesture_drag_new (widget);
   gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (priv->drag_gesture),
                                      FALSE);
-  gtk_gesture_attach (priv->drag_gesture, GTK_PHASE_TARGET);
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->drag_gesture),
+                                              GTK_PHASE_TARGET);
   g_signal_connect (priv->drag_gesture, "drag-update",
                     G_CALLBACK (gtk_text_view_drag_gesture_update),
                     widget);
@@ -3258,10 +3260,7 @@ gtk_text_view_finalize (GObject *object)
   
   cancel_pending_scroll (text_view);
 
-  gtk_gesture_detach (priv->multipress_gesture);
   g_object_unref (priv->multipress_gesture);
-
-  gtk_gesture_detach (priv->drag_gesture);
   g_object_unref (priv->drag_gesture);
 
   if (priv->tabs)
diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c
index 1d24a5c..a029b1a 100644
--- a/gtk/gtktreeview.c
+++ b/gtk/gtktreeview.c
@@ -1841,7 +1841,8 @@ gtk_tree_view_init (GtkTreeView *tree_view)
   gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (tree_view->priv->multipress_gesture), FALSE);
   g_signal_connect (tree_view->priv->multipress_gesture, "pressed",
                     G_CALLBACK (_tree_view_multipress_pressed), tree_view);
-  gtk_gesture_attach (tree_view->priv->multipress_gesture, GTK_PHASE_BUBBLE);
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (tree_view->priv->multipress_gesture),
+                                              GTK_PHASE_BUBBLE);
 }
 
 
@@ -2206,11 +2207,7 @@ gtk_tree_view_destroy (GtkWidget *widget)
     _gtk_pixel_cache_free (tree_view->priv->pixel_cache);
   tree_view->priv->pixel_cache = NULL;
 
-  if (tree_view->priv->multipress_gesture)
-    {
-      gtk_gesture_detach (tree_view->priv->multipress_gesture);
-      g_clear_object (&tree_view->priv->multipress_gesture);
-    }
+  g_clear_object (&tree_view->priv->multipress_gesture);
 
   GTK_WIDGET_CLASS (gtk_tree_view_parent_class)->destroy (widget);
 }
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 81ed556..5895f49 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -400,7 +400,6 @@ typedef struct {
 
 typedef struct {
   GtkEventController *controller;
-  GtkPropagationPhase phase;
   guint evmask_notify_id;
   guint grab_notify_id;
   guint sequence_state_changed_id;
@@ -4206,11 +4205,13 @@ gtk_widget_needs_press_emulation (GtkWidget        *widget,
   for (l = priv->event_controllers; l; l = l->next)
     {
       EventControllerData *data;
+      GtkPropagationPhase phase;
       GtkGesture *gesture;
 
       data = l->data;
+      phase = gtk_event_controller_get_propagation_phase (data->controller);
 
-      if (data->phase != GTK_PHASE_CAPTURE)
+      if (phase != GTK_PHASE_CAPTURE)
         continue;
       if (!GTK_IS_GESTURE (data->controller))
         continue;
@@ -7332,6 +7333,7 @@ _gtk_widget_run_controllers (GtkWidget           *widget,
   while (l != NULL)
     {
       GList *next = l->next;
+
       data = l->data;
 
       if (data->controller == NULL)
@@ -7339,8 +7341,15 @@ _gtk_widget_run_controllers (GtkWidget           *widget,
           priv->event_controllers = g_list_delete_link (priv->event_controllers, l);
           g_free (data);
         }
-      else if (data->phase == phase)
-        handled |= gtk_event_controller_handle_event (data->controller, event);
+      else
+        {
+          GtkPropagationPhase controller_phase;
+
+          controller_phase = gtk_event_controller_get_propagation_phase (data->controller);
+
+          if (controller_phase == phase)
+            handled |= gtk_event_controller_handle_event (data->controller, event);
+        }
 
       l = next;
     }
@@ -16874,10 +16883,12 @@ event_controller_grab_notify (GtkWidget           *widget,
                               EventControllerData *data)
 {
   GtkWidget *grab_widget, *toplevel;
+  GtkPropagationPhase phase;
   GtkWindowGroup *group;
   GdkDevice *device;
 
   device = gtk_gesture_get_device (GTK_GESTURE (data->controller));
+  phase = gtk_event_controller_get_propagation_phase (data->controller);
 
   if (!device)
     return;
@@ -16897,9 +16908,9 @@ event_controller_grab_notify (GtkWidget           *widget,
   if (!grab_widget || grab_widget == widget)
     return;
 
-  if ((data->phase != GTK_PHASE_CAPTURE &&
+  if ((phase != GTK_PHASE_CAPTURE &&
        !gtk_widget_is_ancestor (widget, grab_widget)) ||
-      (data->phase == GTK_PHASE_CAPTURE &&
+      (phase == GTK_PHASE_CAPTURE &&
        !gtk_widget_is_ancestor (widget, grab_widget) &&
        !gtk_widget_is_ancestor (grab_widget, widget)))
     {
@@ -16988,8 +16999,7 @@ _gtk_widget_has_controller (GtkWidget          *widget,
 
 void
 _gtk_widget_add_controller (GtkWidget           *widget,
-                            GtkEventController  *controller,
-                            GtkPropagationPhase  phase)
+                            GtkEventController  *controller)
 {
   EventControllerData *data;
   GtkWidgetPrivate *priv;
@@ -16997,20 +17007,15 @@ _gtk_widget_add_controller (GtkWidget           *widget,
   g_return_if_fail (GTK_IS_WIDGET (widget));
   g_return_if_fail (GTK_IS_EVENT_CONTROLLER (controller));
   g_return_if_fail (widget == gtk_event_controller_get_widget (controller));
-  g_return_if_fail (phase >= GTK_PHASE_NONE && phase <= GTK_PHASE_TARGET);
 
   priv = widget->priv;
   data = _gtk_widget_has_controller (widget, controller);
 
   if (data)
-    {
-      data->phase = phase;
-      return;
-    }
+    return;
 
   data = g_new0 (EventControllerData, 1);
-  data->controller = g_object_ref (controller);
-  data->phase = phase;
+  data->controller = controller;
   data->evmask_notify_id =
     g_signal_connect (controller, "notify::event-mask",
                       G_CALLBACK (event_controller_notify_event_mask), widget);
@@ -17049,8 +17054,6 @@ _gtk_widget_remove_controller (GtkWidget          *widget,
 
   g_signal_handler_disconnect (data->controller, data->evmask_notify_id);
   g_signal_handler_disconnect (data->controller, data->sequence_state_changed_id);
-  gtk_event_controller_reset (GTK_EVENT_CONTROLLER (data->controller));
-  g_object_unref (data->controller);
   data->controller = NULL;
 }
 
@@ -17069,7 +17072,9 @@ _gtk_widget_list_controllers (GtkWidget           *widget,
   for (l = priv->event_controllers; l; l = l->next)
     {
       data = l->data;
-      if (data->phase == phase && data->controller != NULL)
+
+      if (data->controller != NULL &&
+          phase == gtk_event_controller_get_propagation_phase (data->controller))
         retval = g_list_prepend (retval, data->controller);
     }
 
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index ebb0609..9b8fae5 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -156,8 +156,7 @@ GActionGroup *    _gtk_widget_get_action_group             (GtkWidget    *widget
                                                             const gchar  *prefix);
 
 void              _gtk_widget_add_controller               (GtkWidget           *widget,
-                                                            GtkEventController  *controller,
-                                                            GtkPropagationPhase  phase);
+                                                            GtkEventController  *controller);
 void              _gtk_widget_remove_controller            (GtkWidget           *widget,
                                                             GtkEventController  *controller);
 GList *           _gtk_widget_list_controllers             (GtkWidget           *widget,
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index f17f738..cdd67bc 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -1595,7 +1595,8 @@ gtk_window_constructor (GType                  type,
                         G_CALLBACK (multipress_gesture_pressed_cb), object);
       g_signal_connect (priv->multipress_gesture, "stopped",
                         G_CALLBACK (multipress_gesture_stopped_cb), object);
-      gtk_gesture_attach (priv->multipress_gesture, GTK_PHASE_CAPTURE);
+      gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->multipress_gesture),
+                                                  GTK_PHASE_CAPTURE);
     }
 
   return object;
@@ -5482,10 +5483,7 @@ gtk_window_finalize (GObject *object)
     }
 
   if (priv->multipress_gesture)
-    {
-      gtk_gesture_detach (priv->multipress_gesture);
-      g_object_unref (priv->multipress_gesture);
-    }
+    g_object_unref (priv->multipress_gesture);
 
   G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
 }



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