eventcontroller: Add vfuncs to (un)set widget
authorBenjamin Otte <otte@redhat.com>
Thu, 8 Mar 2018 02:30:44 +0000 (03:30 +0100)
committerCarlos Garnacho <carlosg@gnome.org>
Thu, 26 Apr 2018 15:59:41 +0000 (17:59 +0200)
This is the first step towards refactoring how widgets deal with event
controllers.

In the future, the widget will treat controllers the same way it treats
child widgets:
1. The controllers will be created without a widget.
2. There will be gtk_widget_add/remove_controller() functions to add
   or remove controllers.
3. The widget will hold a reference to all its controllers.

This way we will ultimately be able to automate controllers with ui
files.

gtk/gtkeventcontroller.c
gtk/gtkeventcontrollerprivate.h
gtk/gtkwidget.c

index 31afdc032e15d45b1bef39173b49b7423d066bff..31301b61063d15649229de772cdc95298292e6dc 100644 (file)
@@ -56,8 +56,25 @@ struct _GtkEventControllerPrivate
 
 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GtkEventController, gtk_event_controller, G_TYPE_OBJECT)
 
+static void
+gtk_event_controller_set_widget (GtkEventController *self,
+                                 GtkWidget          *widget)
+{
+  GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self);
+
+  priv->widget = widget;
+}
+
+static void
+gtk_event_controller_unset_widget (GtkEventController *self)
+{
+  GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self);
+
+  priv->widget = NULL;
+}
+
 static gboolean
-gtk_event_controller_handle_event_default (GtkEventController *controller,
+gtk_event_controller_handle_event_default (GtkEventController *self,
                                            const GdkEvent     *event)
 {
   return FALSE;
@@ -71,15 +88,16 @@ gtk_event_controller_set_property (GObject      *object,
 {
   GtkEventController *self = GTK_EVENT_CONTROLLER (object);
   GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self);
+  GtkWidget *widget;
 
   switch (prop_id)
     {
     case PROP_WIDGET:
-      priv->widget = g_value_get_object (value);
-      if (priv->widget)
+      widget = g_value_get_object (value);
+      if (widget)
         {
-          g_object_add_weak_pointer (G_OBJECT (priv->widget), (gpointer *) &priv->widget);
-          _gtk_widget_add_controller (priv->widget, self);
+          _gtk_widget_add_controller (widget, self);
+          g_object_add_weak_pointer (G_OBJECT (widget), (gpointer *) &priv->widget);
         }
       break;
     case PROP_PROPAGATION_PHASE:
@@ -122,9 +140,8 @@ gtk_event_controller_dispose (GObject *object)
   priv = gtk_event_controller_get_instance_private (controller);
   if (priv->widget)
     {
-      _gtk_widget_remove_controller (priv->widget, controller);
       g_object_remove_weak_pointer (G_OBJECT (priv->widget), (gpointer *) &priv->widget);
-      priv->widget = NULL;
+      _gtk_widget_remove_controller (priv->widget, controller);
     }
 
   G_OBJECT_CLASS (gtk_event_controller_parent_class)->dispose (object);
@@ -135,6 +152,8 @@ gtk_event_controller_class_init (GtkEventControllerClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
+  klass->set_widget = gtk_event_controller_set_widget;
+  klass->unset_widget = gtk_event_controller_unset_widget;
   klass->filter_event = gtk_event_controller_handle_event_default;
   klass->handle_event = gtk_event_controller_handle_event_default;
 
index 40462c1804cc6c3a0a987ac39964e744c8cfa768..4d0efbb29733ab76559173abbf433ed312ee2918 100644 (file)
@@ -31,6 +31,9 @@ struct _GtkEventControllerClass
 {
   GObjectClass parent_class;
 
+  void     (* set_widget)   (GtkEventController *controller,
+                             GtkWidget          *widget);
+  void     (* unset_widget) (GtkEventController *controller);
   gboolean (* handle_event) (GtkEventController *controller,
                              const GdkEvent     *event);
   void     (* reset)        (GtkEventController *controller);
index 08c5db9beddf88a0870490b1bf8c7232dc0c30ac..09cabb6bac9d70c086e5fbd48fb3e2e846802919 100644 (file)
@@ -12894,13 +12894,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 (gtk_event_controller_get_widget (controller) == NULL);
 
   data = _gtk_widget_has_controller (widget, controller);
 
   if (data)
     return;
 
+  GTK_EVENT_CONTROLLER_GET_CLASS (controller)->set_widget (controller, widget);
+
   data = g_new0 (EventControllerData, 1);
   data->controller = controller;
   data->grab_notify_id =
@@ -12934,6 +12936,8 @@ _gtk_widget_remove_controller (GtkWidget          *widget,
   if (!data)
     return;
 
+  GTK_EVENT_CONTROLLER_GET_CLASS (controller)->unset_widget (controller);
+
   g_object_remove_weak_pointer (G_OBJECT (data->controller), (gpointer *) &data->controller);
 
   if (g_signal_handler_is_connected (widget, data->grab_notify_id))