[gtk/fix-builder-parsing] builder: Fix parsing of mixed declarations




commit 28f26002932cadfa6c01a1d5c655caaea69d4b20
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Sep 24 16:34:48 2021 -0400

    builder: Fix parsing of mixed declarations
    
    The GtkBuilder parser constructs the object e.g.
    when handling a <binding> element. There may be
    more <property> elements after it, which we were
    just not applying. Fix that by always applying
    property when we see </object>. To do that, we
    need to track the applied status per property.
    
    Test included.
    
    Fixes: #4208

 gtk/gtkbuilder.c                        | 10 ++++++++--
 gtk/gtkbuilderparser.c                  |  5 -----
 gtk/gtkbuilderprivate.h                 |  6 +++---
 testsuite/reftests/late-property.ref.ui | 18 ++++++++++++++++++
 testsuite/reftests/late-property.ui     | 18 ++++++++++++++++++
 testsuite/reftests/meson.build          |  2 ++
 6 files changed, 49 insertions(+), 10 deletions(-)
---
diff --git a/gtk/gtkbuilder.c b/gtk/gtkbuilder.c
index 809f55ff63..02b4bfca41 100644
--- a/gtk/gtkbuilder.c
+++ b/gtk/gtkbuilder.c
@@ -540,6 +540,9 @@ gtk_builder_get_parameters (GtkBuilder         *builder,
       const char *property_name = prop->pspec->name;
       GValue property_value = G_VALUE_INIT;
 
+      if (prop->applied)
+        continue;
+
       if (prop->value)
         {
           g_value_init (&property_value, G_PARAM_SPEC_VALUE_TYPE (prop->pspec));
@@ -567,6 +570,8 @@ gtk_builder_get_parameters (GtkBuilder         *builder,
           GObject *object = g_hash_table_lookup (priv->objects,
                                                  g_strstrip (prop->text->str));
 
+          prop->applied = TRUE;
+
           if (object)
             {
               g_value_init (&property_value, G_OBJECT_TYPE (object));
@@ -588,8 +593,7 @@ gtk_builder_get_parameters (GtkBuilder         *builder,
               property->value = g_strdup (prop->text->str);
               property->line = prop->line;
               property->col = prop->col;
-              priv->delayed_properties = g_slist_prepend (priv->delayed_properties,
-                                                          property);
+              priv->delayed_properties = g_slist_prepend (priv->delayed_properties, property);
               continue;
             }
         }
@@ -606,6 +610,8 @@ gtk_builder_get_parameters (GtkBuilder         *builder,
           continue;
         }
 
+      prop->applied = TRUE;
+
       if (prop->pspec->flags & filter_flags)
         {
           if (filtered_parameters)
diff --git a/gtk/gtkbuilderparser.c b/gtk/gtkbuilderparser.c
index 0e614ccdac..c17062849d 100644
--- a/gtk/gtkbuilderparser.c
+++ b/gtk/gtkbuilderparser.c
@@ -470,9 +470,6 @@ builder_construct (ParserData  *data,
 
   g_assert (object_info != NULL);
 
-  if (object_info->object && object_info->applied_properties)
-    return object_info->object;
-
   if (object_info->object == NULL)
     {
       object = _gtk_builder_construct (data->builder, object_info, error);
@@ -488,8 +485,6 @@ builder_construct (ParserData  *data,
       _gtk_builder_apply_properties (data->builder, object_info, error);
     }
 
-  object_info->applied_properties = TRUE;
-
   g_assert (G_IS_OBJECT (object));
 
   object_info->object = object;
diff --git a/gtk/gtkbuilderprivate.h b/gtk/gtkbuilderprivate.h
index 913fa263a9..32cb470f4b 100644
--- a/gtk/gtkbuilderprivate.h
+++ b/gtk/gtkbuilderprivate.h
@@ -53,7 +53,6 @@ typedef struct {
 
   GObject *object;
   CommonInfo *parent;
-  gboolean applied_properties;
 } ObjectInfo;
 
 typedef struct {
@@ -71,8 +70,9 @@ typedef struct {
   GParamSpec *pspec;
   gpointer value;
   GString *text;
-  gboolean translatable:1;
-  gboolean bound:1;
+  gboolean translatable : 1;
+  gboolean bound        : 1;
+  gboolean applied      : 1;
   char *context;
   int line;
   int col;
diff --git a/testsuite/reftests/late-property.ref.ui b/testsuite/reftests/late-property.ref.ui
new file mode 100644
index 0000000000..f079ea78a5
--- /dev/null
+++ b/testsuite/reftests/late-property.ref.ui
@@ -0,0 +1,18 @@
+<interface>
+  <object class="GtkWindow">
+    <child type="titlebar">
+      <object class="GtkHeaderBar">
+        <property name="title-widget">
+          <object class="GtkLabel">
+            <property name="label">Title widget</property>
+          </object>
+        </property>
+        <child type="start">
+          <object class="GtkButton">
+            <property name="label">Button</property>
+          </object>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/testsuite/reftests/late-property.ui b/testsuite/reftests/late-property.ui
new file mode 100644
index 0000000000..5283860044
--- /dev/null
+++ b/testsuite/reftests/late-property.ui
@@ -0,0 +1,18 @@
+<interface>
+  <object class="GtkWindow">
+    <child type="titlebar">
+      <object class="GtkHeaderBar">
+        <child type="start">
+          <object class="GtkButton">
+            <property name="label">Button</property>
+          </object>
+        </child>
+        <property name="title-widget">
+          <object class="GtkLabel">
+            <property name="label">Title widget</property>
+          </object>
+        </property>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/testsuite/reftests/meson.build b/testsuite/reftests/meson.build
index ea967f2d0c..e4e860fc9f 100644
--- a/testsuite/reftests/meson.build
+++ b/testsuite/reftests/meson.build
@@ -331,6 +331,8 @@ testdata = [
   # that are not valid with subpixel positioning
   #'label-wrap-justify.ref.ui',
   #'label-wrap-justify.ui',
+  'late-property.ui',
+  'late-property.ref.ui',
   'letter-spacing.css',
   'letter-spacing.ui',
   'letter-spacing.ref.ui',


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