widget: Expose gtk_widget_add_controller()
authorBenjamin Otte <otte@redhat.com>
Thu, 8 Mar 2018 22:14:06 +0000 (23:14 +0100)
committerCarlos Garnacho <carlosg@gnome.org>
Thu, 26 Apr 2018 15:59:41 +0000 (17:59 +0200)
.. and gtk_widget_remove_controller().

docs/reference/gtk/gtk4-sections.txt
gtk/gtkeventcontroller.c
gtk/gtkwidget.c
gtk/gtkwidget.h
gtk/gtkwidgetprivate.h

index 90d886cbc6db200380b3b31818057e4330d989f3..83313d7c9f9f7ebb8f130d482df6d458abdbd661 100644 (file)
@@ -4273,6 +4273,8 @@ gtk_widget_get_toplevel
 gtk_widget_get_ancestor
 gtk_widget_is_ancestor
 gtk_widget_translate_coordinates
+gtk_widget_add_controller
+gtk_widget_remove_controller
 gtk_widget_set_direction
 GtkTextDirection
 gtk_widget_get_direction
index 31301b61063d15649229de772cdc95298292e6dc..d00f09ce3628a8040f063ea8da2c52c1fcdc100a 100644 (file)
@@ -87,7 +87,6 @@ gtk_event_controller_set_property (GObject      *object,
                                    GParamSpec   *pspec)
 {
   GtkEventController *self = GTK_EVENT_CONTROLLER (object);
-  GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self);
   GtkWidget *widget;
 
   switch (prop_id)
@@ -96,8 +95,7 @@ gtk_event_controller_set_property (GObject      *object,
       widget = g_value_get_object (value);
       if (widget)
         {
-          _gtk_widget_add_controller (widget, self);
-          g_object_add_weak_pointer (G_OBJECT (widget), (gpointer *) &priv->widget);
+          _gtk_widget_add_controller (widget, self, FALSE);
         }
       break;
     case PROP_PROPAGATION_PHASE:
@@ -140,8 +138,7 @@ gtk_event_controller_dispose (GObject *object)
   priv = gtk_event_controller_get_instance_private (controller);
   if (priv->widget)
     {
-      g_object_remove_weak_pointer (G_OBJECT (priv->widget), (gpointer *) &priv->widget);
-      _gtk_widget_remove_controller (priv->widget, controller);
+      gtk_widget_remove_controller (priv->widget, controller);
     }
 
   G_OBJECT_CLASS (gtk_event_controller_parent_class)->dispose (object);
index 09cabb6bac9d70c086e5fbd48fb3e2e846802919..b4361c65f7ba300adf899c45cb06bc510a1fbbb9 100644 (file)
@@ -459,6 +459,7 @@ typedef struct {
   GtkEventController *controller;
   guint grab_notify_id;
   guint sequence_state_changed_id;
+  gboolean have_ref;
 } EventControllerData;
 
 struct _GtkWidgetClassPrivate
@@ -8583,7 +8584,9 @@ gtk_widget_finalize (GObject *object)
     {
       EventControllerData *data = l->data;
       if (data->controller)
-        _gtk_widget_remove_controller (widget, data->controller);
+        {
+          gtk_widget_remove_controller (widget, data->controller);
+        }
     }
   g_list_free_full (priv->event_controllers, g_free);
   priv->event_controllers = NULL;
@@ -12866,44 +12869,20 @@ event_controller_sequence_state_changed (GtkGesture            *gesture,
   cancel_event_sequence_on_hierarchy (widget, event_widget, sequence);
 }
 
-static EventControllerData *
-_gtk_widget_has_controller (GtkWidget          *widget,
-                            GtkEventController *controller)
-{
-  GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
-  EventControllerData *data;
-  GList *l;
-
-  for (l = priv->event_controllers; l; l = l->next)
-    {
-      data = l->data;
-
-      if (data->controller == controller)
-        return data;
-    }
-
-  return NULL;
-}
-
 void
 _gtk_widget_add_controller (GtkWidget          *widget,
-                            GtkEventController *controller)
+                            GtkEventController *controller,
+                            gboolean            have_ref)
 {
   GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
   EventControllerData *data;
 
-  g_return_if_fail (GTK_IS_WIDGET (widget));
-  g_return_if_fail (GTK_IS_EVENT_CONTROLLER (controller));
-  g_return_if_fail (gtk_event_controller_get_widget (controller) == NULL);
-
-  data = _gtk_widget_has_controller (widget, controller);
-
-  if (data)
-    return;
+  priv = widget->priv;
 
   GTK_EVENT_CONTROLLER_GET_CLASS (controller)->set_widget (controller, widget);
 
   data = g_new0 (EventControllerData, 1);
+  data->have_ref = have_ref;
   data->controller = controller;
   data->grab_notify_id =
     g_signal_connect (widget, "grab-notify",
@@ -12922,19 +12901,61 @@ _gtk_widget_add_controller (GtkWidget          *widget,
   priv->event_controllers = g_list_prepend (priv->event_controllers, data);
 }
 
+/**
+ * gtk_widget_add_controller:
+ * @widget: a #GtkWidget
+ * @controller: (transfer full): a #GtkEventController that hasn't been
+ *     added to a widget yet
+ *
+ * Adds @controller to @widget so that it will receive events. You will
+ * usually want to call this function right after creating any kind of
+ * #GtkEventController.
+ **/
 void
-_gtk_widget_remove_controller (GtkWidget          *widget,
-                               GtkEventController *controller)
+gtk_widget_add_controller (GtkWidget          *widget,
+                           GtkEventController *controller)
 {
-  EventControllerData *data;
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+  g_return_if_fail (GTK_IS_EVENT_CONTROLLER (controller));
+  g_return_if_fail (gtk_event_controller_get_widget (controller) == NULL);
+
+  _gtk_widget_add_controller (widget, controller, TRUE);
+}
+
+/**
+ * gtk_widget_remove_controller:
+ * @widget: a #GtkWidget
+ * @controller: (transfer none): a #GtkEventController
+ *
+ * Removes @controller from @widget, so that it doesn't process
+ * events anymore. It should not be used again.
+ *
+ * Widgets will remove all event controllers automatically when they
+ * are destroyed, there is normally no need to call this function.
+ **/
+void
+gtk_widget_remove_controller (GtkWidget          *widget,
+                              GtkEventController *controller)
+{
+  EventControllerData *data = NULL;
+  GtkWidgetPrivate *priv;
+  GList *l;
 
   g_return_if_fail (GTK_IS_WIDGET (widget));
   g_return_if_fail (GTK_IS_EVENT_CONTROLLER (controller));
+  g_return_if_fail (gtk_event_controller_get_widget (controller) == widget);
 
-  data = _gtk_widget_has_controller (widget, controller);
+  priv = widget->priv;
 
-  if (!data)
-    return;
+  for (l = priv->event_controllers; l; l = l->next)
+    {
+      data = l->data;
+
+      if (data->controller == controller)
+        break;
+    }
+
+  g_assert (data);
 
   GTK_EVENT_CONTROLLER_GET_CLASS (controller)->unset_widget (controller);
 
@@ -12947,6 +12968,8 @@ _gtk_widget_remove_controller (GtkWidget          *widget,
     g_signal_handler_disconnect (data->controller, data->sequence_state_changed_id);
 
   data->controller = NULL;
+  if (data->have_ref)
+    g_object_unref (controller);
 }
 
 GList *
index dc2770327c0f69a77fa877ea115838894a4687b9..172ef445306ef0e0645dd4b254cde52192b58593 100644 (file)
@@ -770,6 +770,12 @@ GtkWidget *  gtk_widget_pick                  (GtkWidget  *widget,
                                                gdouble     y);
 
 GDK_AVAILABLE_IN_ALL
+void         gtk_widget_add_controller        (GtkWidget          *widget,
+                                               GtkEventController *controller);
+GDK_AVAILABLE_IN_ALL
+void         gtk_widget_remove_controller     (GtkWidget          *widget,
+                                               GtkEventController *controller);
+GDK_AVAILABLE_IN_ALL
 void       gtk_widget_reset_style       (GtkWidget      *widget);
 
 GDK_AVAILABLE_IN_ALL
index f53b7659dc98154a8b07e41498ddca0e491a193d..2a3df8177bb36bf9917ccf1717e67c387988506a 100644 (file)
@@ -259,9 +259,8 @@ GtkActionMuxer *  _gtk_widget_get_action_muxer             (GtkWidget    *widget
                                                             gboolean      create);
 
 void              _gtk_widget_add_controller               (GtkWidget           *widget,
-                                                            GtkEventController  *controller);
-void              _gtk_widget_remove_controller            (GtkWidget           *widget,
-                                                            GtkEventController  *controller);
+                                                            GtkEventController  *controller,
+                                                            gboolean             take_ref);
 GList *           _gtk_widget_list_controllers             (GtkWidget           *widget,
                                                             GtkPropagationPhase  phase);
 gboolean          _gtk_widget_consumes_motion              (GtkWidget           *widget,