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 committed by Matthias Clasen
parent b7efe4eb4f
commit ad60efb5d7

View File

@ -1292,6 +1292,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)
{
@ -1319,6 +1334,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);
@ -1331,6 +1348,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;
@ -1386,6 +1406,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;
@ -1394,7 +1417,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);