mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-27 06:26:15 +01:00
Merge branch 'bindung-unbind-fix' into 'master'
g_binding_unbind: make it more introspection friendly; allow calling it multiple times. Fixes #1373 Closes #1373 See merge request GNOME/glib!244
This commit is contained in:
commit
ed6903f6fb
@ -373,6 +373,7 @@ g_binding_unbind_internal (GBinding *binding,
|
|||||||
gboolean unref_binding)
|
gboolean unref_binding)
|
||||||
{
|
{
|
||||||
gboolean source_is_target = binding->source == binding->target;
|
gboolean source_is_target = binding->source == binding->target;
|
||||||
|
gboolean binding_was_removed = FALSE;
|
||||||
|
|
||||||
/* dispose of the transformation data */
|
/* dispose of the transformation data */
|
||||||
if (binding->notify != NULL)
|
if (binding->notify != NULL)
|
||||||
@ -392,6 +393,7 @@ g_binding_unbind_internal (GBinding *binding,
|
|||||||
|
|
||||||
binding->source_notify = 0;
|
binding->source_notify = 0;
|
||||||
binding->source = NULL;
|
binding->source = NULL;
|
||||||
|
binding_was_removed = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (binding->target != NULL)
|
if (binding->target != NULL)
|
||||||
@ -404,9 +406,10 @@ g_binding_unbind_internal (GBinding *binding,
|
|||||||
|
|
||||||
binding->target_notify = 0;
|
binding->target_notify = 0;
|
||||||
binding->target = NULL;
|
binding->target = NULL;
|
||||||
|
binding_was_removed = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unref_binding)
|
if (binding_was_removed && unref_binding)
|
||||||
g_object_unref (binding);
|
g_object_unref (binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -748,7 +751,7 @@ g_binding_get_target_property (GBinding *binding)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* g_binding_unbind:
|
* g_binding_unbind:
|
||||||
* @binding: (transfer full): a #GBinding
|
* @binding: a #GBinding
|
||||||
*
|
*
|
||||||
* Explicitly releases the binding between the source and the target
|
* Explicitly releases the binding between the source and the target
|
||||||
* property expressed by @binding.
|
* property expressed by @binding.
|
||||||
|
@ -460,6 +460,7 @@ binding_chain (void)
|
|||||||
BindingSource *c = g_object_new (binding_source_get_type (), NULL);
|
BindingSource *c = g_object_new (binding_source_get_type (), NULL);
|
||||||
GBinding *binding_1, *binding_2;
|
GBinding *binding_1, *binding_2;
|
||||||
|
|
||||||
|
g_test_bug_base ("http://bugzilla.gnome.org/");
|
||||||
g_test_bug ("621782");
|
g_test_bug ("621782");
|
||||||
|
|
||||||
/* A -> B, B -> C */
|
/* A -> B, B -> C */
|
||||||
@ -625,6 +626,83 @@ binding_unbind (void)
|
|||||||
g_object_unref (source);
|
g_object_unref (source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* When source or target die, so does the binding if there is no other ref */
|
||||||
|
static void
|
||||||
|
binding_unbind_weak (void)
|
||||||
|
{
|
||||||
|
GBinding *binding;
|
||||||
|
BindingSource *source;
|
||||||
|
BindingTarget *target;
|
||||||
|
|
||||||
|
/* first source, then target */
|
||||||
|
source = g_object_new (binding_source_get_type (), NULL);
|
||||||
|
target = g_object_new (binding_target_get_type (), NULL);
|
||||||
|
binding = g_object_bind_property (source, "foo",
|
||||||
|
target, "bar",
|
||||||
|
G_BINDING_DEFAULT);
|
||||||
|
g_object_add_weak_pointer (G_OBJECT (binding), (gpointer *) &binding);
|
||||||
|
g_assert_nonnull (binding);
|
||||||
|
g_object_unref (source);
|
||||||
|
g_assert_null (binding);
|
||||||
|
g_object_unref (target);
|
||||||
|
g_assert_null (binding);
|
||||||
|
|
||||||
|
/* first target, then source */
|
||||||
|
source = g_object_new (binding_source_get_type (), NULL);
|
||||||
|
target = g_object_new (binding_target_get_type (), NULL);
|
||||||
|
binding = g_object_bind_property (source, "foo",
|
||||||
|
target, "bar",
|
||||||
|
G_BINDING_DEFAULT);
|
||||||
|
g_object_add_weak_pointer (G_OBJECT (binding), (gpointer *) &binding);
|
||||||
|
g_assert_nonnull (binding);
|
||||||
|
g_object_unref (target);
|
||||||
|
g_assert_null (binding);
|
||||||
|
g_object_unref (source);
|
||||||
|
g_assert_null (binding);
|
||||||
|
|
||||||
|
/* target and source are the same */
|
||||||
|
source = g_object_new (binding_source_get_type (), NULL);
|
||||||
|
binding = g_object_bind_property (source, "foo",
|
||||||
|
source, "bar",
|
||||||
|
G_BINDING_DEFAULT);
|
||||||
|
g_object_add_weak_pointer (G_OBJECT (binding), (gpointer *) &binding);
|
||||||
|
g_assert_nonnull (binding);
|
||||||
|
g_object_unref (source);
|
||||||
|
g_assert_null (binding);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test that every call to unbind() after the first is a noop */
|
||||||
|
static void
|
||||||
|
binding_unbind_multiple (void)
|
||||||
|
{
|
||||||
|
BindingSource *source = g_object_new (binding_source_get_type (), NULL);
|
||||||
|
BindingTarget *target = g_object_new (binding_target_get_type (), NULL);
|
||||||
|
GBinding *binding;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
g_test_bug ("1373");
|
||||||
|
|
||||||
|
binding = g_object_bind_property (source, "foo",
|
||||||
|
target, "bar",
|
||||||
|
G_BINDING_DEFAULT);
|
||||||
|
g_object_ref (binding);
|
||||||
|
g_object_add_weak_pointer (G_OBJECT (binding), (gpointer *) &binding);
|
||||||
|
g_assert_nonnull (binding);
|
||||||
|
|
||||||
|
/* this shouldn't crash */
|
||||||
|
for (i = 0; i < 50; i++)
|
||||||
|
{
|
||||||
|
g_binding_unbind (binding);
|
||||||
|
g_assert_nonnull (binding);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref (binding);
|
||||||
|
g_assert_null (binding);
|
||||||
|
|
||||||
|
g_object_unref (source);
|
||||||
|
g_object_unref (target);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
binding_fail (void)
|
binding_fail (void)
|
||||||
{
|
{
|
||||||
@ -653,7 +731,7 @@ main (int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
g_test_init (&argc, &argv, NULL);
|
g_test_init (&argc, &argv, NULL);
|
||||||
|
|
||||||
g_test_bug_base ("http://bugzilla.gnome.org/");
|
g_test_bug_base ("https://gitlab.gnome.org/GNOME/glib/issues/");
|
||||||
|
|
||||||
g_test_add_func ("/binding/default", binding_default);
|
g_test_add_func ("/binding/default", binding_default);
|
||||||
g_test_add_func ("/binding/bidirectional", binding_bidirectional);
|
g_test_add_func ("/binding/bidirectional", binding_bidirectional);
|
||||||
@ -665,6 +743,8 @@ main (int argc, char *argv[])
|
|||||||
g_test_add_func ("/binding/invert-boolean", binding_invert_boolean);
|
g_test_add_func ("/binding/invert-boolean", binding_invert_boolean);
|
||||||
g_test_add_func ("/binding/same-object", binding_same_object);
|
g_test_add_func ("/binding/same-object", binding_same_object);
|
||||||
g_test_add_func ("/binding/unbind", binding_unbind);
|
g_test_add_func ("/binding/unbind", binding_unbind);
|
||||||
|
g_test_add_func ("/binding/unbind-weak", binding_unbind_weak);
|
||||||
|
g_test_add_func ("/binding/unbind-multiple", binding_unbind_multiple);
|
||||||
g_test_add_func ("/binding/fail", binding_fail);
|
g_test_add_func ("/binding/fail", binding_fail);
|
||||||
|
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
|
Loading…
Reference in New Issue
Block a user