[gtk/wip/ebassi/constraint-layout: 888/890] Propagate rooting and unrooting widgets to layout managers



commit 796dc2c77bcd16a4f8dcf8c37783b92b5707a68d
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Mon Jun 10 14:43:14 2019 +0100

    Propagate rooting and unrooting widgets to layout managers
    
    Layout managers may need to get access to data attached to the root of a
    scene graph.

 gtk/gtklayoutmanager.c        | 45 +++++++++++++++++++++++++++++++++++++++++++
 gtk/gtklayoutmanager.h        |  7 +++++++
 gtk/gtklayoutmanagerprivate.h |  3 +++
 gtk/gtkwidget.c               |  6 ++++++
 4 files changed, 61 insertions(+)
---
diff --git a/gtk/gtklayoutmanager.c b/gtk/gtklayoutmanager.c
index c41a604b99..1aa7724d49 100644
--- a/gtk/gtklayoutmanager.c
+++ b/gtk/gtklayoutmanager.c
@@ -91,6 +91,7 @@
 
 typedef struct {
   GtkWidget *widget;
+  GtkRoot *root;
 
   /* HashTable<Widget, LayoutChild> */
   GHashTable *layout_children;
@@ -98,6 +99,16 @@ typedef struct {
 
 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GtkLayoutManager, gtk_layout_manager, G_TYPE_OBJECT)
 
+static void
+gtk_layout_manager_real_root (GtkLayoutManager *manager)
+{
+}
+
+static void
+gtk_layout_manager_real_unroot (GtkLayoutManager *manager)
+{
+}
+
 static GtkSizeRequestMode
 gtk_layout_manager_real_get_request_mode (GtkLayoutManager *manager,
                                           GtkWidget        *widget)
@@ -195,6 +206,8 @@ gtk_layout_manager_class_init (GtkLayoutManagerClass *klass)
   klass->measure = gtk_layout_manager_real_measure;
   klass->allocate = gtk_layout_manager_real_allocate;
   klass->create_layout_child = gtk_layout_manager_real_create_layout_child;
+  klass->root = gtk_layout_manager_real_root;
+  klass->unroot = gtk_layout_manager_real_unroot;
 }
 
 static void
@@ -226,6 +239,38 @@ gtk_layout_manager_set_widget (GtkLayoutManager *layout_manager,
     }
 
   priv->widget = widget;
+
+  if (widget != NULL)
+    gtk_layout_manager_set_root (layout_manager, gtk_widget_get_root (widget));
+}
+
+/*< private >
+ * gtk_layout_manager_set_root:
+ * @layout_manager: a #GtkLayoutManager
+ * @root: (nullable): a #GtkWidget implementing #GtkRoot
+ *
+ * Sets a back pointer from @root to @layout_manager.
+ *
+ * This function is called by #GtkWidget when getting rooted and unrooted,
+ * and will call #GtkLayoutManagerClass.root() or #GtkLayoutManagerClass.unroot()
+ * depending on whether @root is a #GtkWidget or %NULL.
+ */
+void
+gtk_layout_manager_set_root (GtkLayoutManager *layout_manager,
+                             GtkRoot          *root)
+{
+  GtkLayoutManagerPrivate *priv = gtk_layout_manager_get_instance_private (layout_manager);
+  GtkRoot *old_root = priv->root;
+
+  priv->root = root;
+
+  if (old_root != root)
+    {
+      if (priv->root != NULL)
+        GTK_LAYOUT_MANAGER_GET_CLASS (layout_manager)->root (layout_manager);
+      else
+        GTK_LAYOUT_MANAGER_GET_CLASS (layout_manager)->unroot (layout_manager);
+    }
 }
 
 /**
diff --git a/gtk/gtklayoutmanager.h b/gtk/gtklayoutmanager.h
index 06659ee70e..3066dc5660 100644
--- a/gtk/gtklayoutmanager.h
+++ b/gtk/gtklayoutmanager.h
@@ -42,6 +42,10 @@ G_DECLARE_DERIVABLE_TYPE (GtkLayoutManager, gtk_layout_manager, GTK, LAYOUT_MANA
  * @layout_child_type: the type of #GtkLayoutChild used by this layout manager
  * @create_layout_child: a virtual function, used to create a #GtkLayoutChild
  *   meta object for the layout properties
+ * @root: a virtual function, called when the widget using the layout
+ *   manager is attached to a #GtkRoot
+ * @unroot: a virtual function, called when the widget using the layout
+ *   manager is detached from a #GtkRoot
  *
  * The `GtkLayoutManagerClass` structure contains only private data, and
  * should only be accessed through the provided API, or when subclassing
@@ -77,6 +81,9 @@ struct _GtkLayoutManagerClass
                                               GtkWidget        *widget,
                                               GtkWidget        *for_child);
 
+  void               (* root)                (GtkLayoutManager *manager);
+  void               (* unroot)              (GtkLayoutManager *manager);
+
   /*< private >*/
   gpointer _padding[16];
 };
diff --git a/gtk/gtklayoutmanagerprivate.h b/gtk/gtklayoutmanagerprivate.h
index 14eb30e161..5cdbf2e440 100644
--- a/gtk/gtklayoutmanagerprivate.h
+++ b/gtk/gtklayoutmanagerprivate.h
@@ -10,4 +10,7 @@ void gtk_layout_manager_set_widget (GtkLayoutManager *manager,
 void gtk_layout_manager_remove_layout_child (GtkLayoutManager *manager,
                                              GtkWidget        *widget);
 
+void gtk_layout_manager_set_root (GtkLayoutManager *manager,
+                                  GtkRoot          *root);
+
 G_END_DECLS
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 0bc88b06b2..ef8293c3af 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -2890,6 +2890,9 @@ gtk_widget_root (GtkWidget *widget)
   if (priv->surface_transform_data)
     add_parent_surface_transform_changed_listener (widget);
 
+  if (priv->layout_manager)
+    gtk_layout_manager_set_root (priv->layout_manager, priv->root);
+
   GTK_WIDGET_GET_CLASS (widget)->root (widget);
 
   if (!GTK_IS_ROOT (widget))
@@ -2915,6 +2918,9 @@ gtk_widget_unroot (GtkWidget *widget)
   if (priv->context)
     gtk_style_context_set_display (priv->context, gdk_display_get_default ());
 
+  if (priv->layout_manager)
+    gtk_layout_manager_set_root (priv->layout_manager, NULL);
+
   if (g_object_get_qdata (G_OBJECT (widget), quark_pango_context))
     g_object_set_qdata (G_OBJECT (widget), quark_pango_context, NULL);
 


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