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 c3d67d3271
commit a94d4648c8

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