[gtk/wip/chergert/fix-action-muxer-part-12: 2/2] actions: give actionmuxer access to final GType



commit c962854f7e25e5f8fd71548fe13525aeabec84ec
Author: Christian Hergert <chergert redhat com>
Date:   Tue Apr 28 14:53:41 2020 -0700

    actions: give actionmuxer access to final GType
    
    The GType of the widget may not be the final GType of the widget if the
    muxer is created in an instance init before the final subclass instance
    init has been called.
    
    This fixes action support for things like "Show Text" in the
    GtkPasswordEntry.

 gtk/gtkactionmuxer.c        | 46 ++++++++++++++++++++++++++++++++++++++++-----
 gtk/gtkactionmuxerprivate.h |  3 ++-
 gtk/gtkapplication.c        |  2 +-
 gtk/gtkwidget.c             |  4 ++--
 4 files changed, 46 insertions(+), 9 deletions(-)
---
diff --git a/gtk/gtkactionmuxer.c b/gtk/gtkactionmuxer.c
index 26ca311efc..f5fdb97fca 100644
--- a/gtk/gtkactionmuxer.c
+++ b/gtk/gtkactionmuxer.c
@@ -74,6 +74,7 @@ struct _GtkActionMuxer
   GtkActionMuxer *parent;
 
   GtkWidget *widget;
+  GType widget_type;
 
   GtkBitmask *widget_actions_disabled;
 };
@@ -87,6 +88,7 @@ enum
   PROP_0,
   PROP_PARENT,
   PROP_WIDGET,
+  PROP_WIDGET_TYPE,
   NUM_PROPERTIES
 };
 
@@ -556,16 +558,15 @@ prop_action_notify (GObject    *object,
 }
 
 static void
-prop_actions_connect (GtkActionMuxer *muxer)
+prop_actions_connect (GtkActionMuxer *muxer,
+                      GtkWidgetClass *klass)
 {
   GtkWidgetClassPrivate *priv;
   GtkWidgetAction *action;
-  GtkWidgetClass *klass;
 
   if (!muxer->widget)
     return;
 
-  klass = GTK_WIDGET_GET_CLASS (muxer->widget);
   priv = klass->priv;
   if (!priv->actions)
     return;
@@ -869,7 +870,12 @@ gtk_action_muxer_constructed (GObject *object)
 {
   GtkActionMuxer *muxer = GTK_ACTION_MUXER (object);
 
-  prop_actions_connect (muxer);
+  if (muxer->widget && muxer->widget_type)
+    {
+      GtkWidgetClass *widget_class = g_type_class_ref (muxer->widget_type);
+      prop_actions_connect (muxer, widget_class);
+      g_type_class_unref (widget_class);
+    }
 
   G_OBJECT_CLASS (gtk_action_muxer_parent_class)->constructed (object);
 }
@@ -892,6 +898,10 @@ gtk_action_muxer_get_property (GObject    *object,
       g_value_set_object (value, muxer->widget);
       break;
 
+    case PROP_WIDGET_TYPE:
+      g_value_set_gtype (value, muxer->widget_type);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
     }
@@ -915,6 +925,10 @@ gtk_action_muxer_set_property (GObject      *object,
       muxer->widget = g_value_get_object (value);
       break;
 
+    case PROP_WIDGET_TYPE:
+      muxer->widget_type = g_value_get_gtype (value);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
     }
@@ -977,6 +991,13 @@ gtk_action_muxer_class_init (GObjectClass *class)
                                                  G_PARAM_CONSTRUCT_ONLY |
                                                  G_PARAM_STATIC_STRINGS);
 
+  properties[PROP_WIDGET_TYPE] = g_param_spec_gtype ("widget-type", "Widget Type",
+                                                     "The widget type that owns the muxer",
+                                                     GTK_TYPE_WIDGET,
+                                                     G_PARAM_READWRITE |
+                                                     G_PARAM_CONSTRUCT_ONLY |
+                                                     G_PARAM_STATIC_STRINGS);
+
   g_object_class_install_properties (class, NUM_PROPERTIES, properties);
 }
 
@@ -1075,10 +1096,25 @@ gtk_action_muxer_remove (GtkActionMuxer *muxer,
  * Creates a new #GtkActionMuxer.
  */
 GtkActionMuxer *
-gtk_action_muxer_new (GtkWidget *widget)
+gtk_action_muxer_new (GtkWidget *widget,
+                      GType      widget_type)
 {
+  g_return_val_if_fail (!widget || GTK_IS_WIDGET (widget), NULL);
+  g_return_val_if_fail (widget_type == G_TYPE_INVALID ||
+                        g_type_is_a (widget_type, GTK_TYPE_WIDGET),
+                        NULL);
+
+  if (widget_type == G_TYPE_INVALID)
+    {
+      if (widget != NULL)
+        widget_type = G_OBJECT_TYPE (widget);
+      else
+        widget_type = GTK_TYPE_WIDGET;
+    }
+
   return g_object_new (GTK_TYPE_ACTION_MUXER,
                        "widget", widget,
+                       "widget-type", widget_type,
                        NULL);
 }
 
diff --git a/gtk/gtkactionmuxerprivate.h b/gtk/gtkactionmuxerprivate.h
index 0c5670c6f8..675948b427 100644
--- a/gtk/gtkactionmuxerprivate.h
+++ b/gtk/gtkactionmuxerprivate.h
@@ -49,7 +49,8 @@ struct _GtkWidgetAction
 };
 
 GType                   gtk_action_muxer_get_type                       (void);
-GtkActionMuxer *        gtk_action_muxer_new                            (GtkWidget      *widget);
+GtkActionMuxer *        gtk_action_muxer_new                            (GtkWidget      *widget,
+                                                                         GType           widget_type);
 
 void                    gtk_action_muxer_insert                         (GtkActionMuxer *muxer,
                                                                          const gchar    *prefix,
diff --git a/gtk/gtkapplication.c b/gtk/gtkapplication.c
index 2f4a3ceaf2..c0d80cd6ed 100644
--- a/gtk/gtkapplication.c
+++ b/gtk/gtkapplication.c
@@ -401,7 +401,7 @@ gtk_application_init (GtkApplication *application)
 {
   GtkApplicationPrivate *priv = gtk_application_get_instance_private (application);
 
-  priv->muxer = gtk_action_muxer_new (NULL);
+  priv->muxer = gtk_action_muxer_new (NULL, G_TYPE_INVALID);
 
   priv->accels = gtk_application_accels_new ();
 }
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index bff01bd016..55aeaebeae 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -2325,7 +2325,7 @@ gtk_widget_init (GTypeInstance *instance, gpointer g_class)
    * subclasses have access to it with the proper actions registered (even
    * though they don't have the g_class pointer available).
    */
-  (void)_gtk_widget_get_action_muxer (widget, g_class, FALSE);
+  _gtk_widget_get_action_muxer (widget, g_class, FALSE);
 
   /* this will be set to TRUE if the widget gets a child or if the
    * expand flag is set on the widget, but until one of those happen
@@ -10724,7 +10724,7 @@ _gtk_widget_get_action_muxer (GtkWidget      *widget,
 
   if (create || priv->actions)
     {
-      muxer = gtk_action_muxer_new (widget);
+      muxer = gtk_action_muxer_new (widget, G_TYPE_FROM_CLASS (widget_class));
       g_object_set_qdata_full (G_OBJECT (widget),
                                quark_action_muxer,
                                muxer,


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