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
This commit is contained in:
Matthias Clasen 2021-09-24 16:34:48 -04:00
parent c8f29a689d
commit ec62402908
6 changed files with 55 additions and 10 deletions

View File

@ -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));
@ -582,6 +585,9 @@ gtk_builder_get_parameters (GtkBuilder *builder,
continue;
}
/* Delay setting property */
prop->applied = TRUE;
property = g_slice_new (DelayedProperty);
property->pspec = prop->pspec;
property->object = g_strdup (object_name);
@ -612,9 +618,15 @@ gtk_builder_get_parameters (GtkBuilder *builder,
g_assert (G_IS_VALUE (&property_value));
if ((prop->pspec->flags & filter_flags) != 0 && filtered_parameters)
{
object_properties_add (filtered_parameters, property_name, &property_value);
prop->applied = TRUE;
}
else if ((prop->pspec->flags & filter_flags) == 0 && parameters)
{
object_properties_add (parameters, property_name, &property_value);
prop->applied = TRUE;
}
else
g_value_unset (&property_value);
}

View File

@ -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;

View File

@ -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;

View File

@ -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>

View File

@ -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>

View File

@ -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',