expression: Invalidate bindings before destroying them

Use a weak ref to invalidate bindings. Make sure that this happens
before creating any watches, so that notifies from the
watched expression about changes will not trigger set_property() calls
during dispose()/finalize().

Invalidating also ensures that the watches aren't removed, which can
trigger warnings if the watches are watching the object itself, and the
weak refs cannot be removed anymore.
This commit is contained in:
Benjamin Otte
2019-11-26 03:57:40 +01:00
parent 196a64c380
commit c40fb49e38

View File

@@ -1263,6 +1263,21 @@ typedef struct {
GParamSpec *pspec;
} GtkExpressionBind;
static void
invalidate_binds (gpointer unused,
GObject *object)
{
GSList *l, *binds;
binds = g_object_get_data (object, "gtk-expression-binds");
for (l = binds; l; l = l->next)
{
GtkExpressionBind *bind = l->data;
bind->object = NULL;
}
}
static void
free_binds (gpointer data)
{
@@ -1290,6 +1305,8 @@ gtk_expression_bind_free (gpointer data)
binds = g_slist_remove (binds, bind);
if (binds)
g_object_set_data_full (bind->object, "gtk-expression-binds", binds, free_binds);
else
g_object_weak_unref (bind->object, invalidate_binds, NULL);
}
gtk_expression_unref (bind->expression);
@@ -1302,6 +1319,9 @@ gtk_expression_bind_notify (gpointer data)
GValue value = G_VALUE_INIT;
GtkExpressionBind *bind = data;
if (bind->object == NULL)
return;
if (!gtk_expression_evaluate (bind->expression, bind->object, &value))
return;
@@ -1357,6 +1377,9 @@ gtk_expression_bind (GtkExpression *self,
}
bind = g_slice_new0 (GtkExpressionBind);
binds = g_object_steal_data (object, "gtk-expression-binds");
if (binds == NULL)
g_object_weak_ref (object, invalidate_binds, NULL);
bind->expression = self;
bind->object = object;
bind->pspec = pspec;
@@ -1365,7 +1388,6 @@ gtk_expression_bind (GtkExpression *self,
gtk_expression_bind_notify,
bind,
gtk_expression_bind_free);
binds = g_object_steal_data (object, "gtk-expression-binds");
binds = g_slist_prepend (binds, bind);
g_object_set_data_full (object, "gtk-expression-binds", binds, free_binds);