Fix binding properties of the same object

This problem was pointed out in bug 639873.
The patch here is based on Matt Barnes patch,
I've added a testcase as well.
This commit is contained in:
Matthias Clasen 2012-03-04 20:49:04 -05:00
parent 840c32281d
commit 1426a8ca07
2 changed files with 41 additions and 3 deletions

View File

@ -575,9 +575,11 @@ g_binding_constructed (GObject *gobject)
G_CALLBACK (on_target_notify), G_CALLBACK (on_target_notify),
binding); binding);
if (binding->target != binding->source)
{
g_object_weak_ref (binding->target, weak_unbind, binding); g_object_weak_ref (binding->target, weak_unbind, binding);
add_binding_qdata (binding->target, binding); add_binding_qdata (binding->target, binding);
}
} }
static void static void

View File

@ -7,6 +7,7 @@ typedef struct _BindingSource
GObject parent_instance; GObject parent_instance;
gint foo; gint foo;
gint bar;
gdouble value; gdouble value;
gboolean toggle; gboolean toggle;
} BindingSource; } BindingSource;
@ -21,6 +22,7 @@ enum
PROP_SOURCE_0, PROP_SOURCE_0,
PROP_SOURCE_FOO, PROP_SOURCE_FOO,
PROP_SOURCE_BAR,
PROP_SOURCE_VALUE, PROP_SOURCE_VALUE,
PROP_SOURCE_TOGGLE PROP_SOURCE_TOGGLE
}; };
@ -42,6 +44,10 @@ binding_source_set_property (GObject *gobject,
source->foo = g_value_get_int (value); source->foo = g_value_get_int (value);
break; break;
case PROP_SOURCE_BAR:
source->bar = g_value_get_int (value);
break;
case PROP_SOURCE_VALUE: case PROP_SOURCE_VALUE:
source->value = g_value_get_double (value); source->value = g_value_get_double (value);
break; break;
@ -69,6 +75,10 @@ binding_source_get_property (GObject *gobject,
g_value_set_int (value, source->foo); g_value_set_int (value, source->foo);
break; break;
case PROP_SOURCE_BAR:
g_value_set_int (value, source->bar);
break;
case PROP_SOURCE_VALUE: case PROP_SOURCE_VALUE:
g_value_set_double (value, source->value); g_value_set_double (value, source->value);
break; break;
@ -95,6 +105,11 @@ binding_source_class_init (BindingSourceClass *klass)
-1, 100, -1, 100,
0, 0,
G_PARAM_READWRITE)); G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_SOURCE_BAR,
g_param_spec_int ("bar", "Bar", "Bar",
-1, 100,
0,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_SOURCE_VALUE, g_object_class_install_property (gobject_class, PROP_SOURCE_VALUE,
g_param_spec_double ("value", "Value", "Value", g_param_spec_double ("value", "Value", "Value",
-100.0, 200.0, -100.0, 200.0,
@ -532,6 +547,26 @@ binding_invert_boolean (void)
g_object_unref (target); g_object_unref (target);
} }
static void
binding_same_object (void)
{
BindingSource *source = g_object_new (binding_source_get_type (),
"foo", 100,
"bar", 50,
NULL);
GBinding *binding G_GNUC_UNUSED;
binding = g_object_bind_property (source, "foo",
source, "bar",
G_BINDING_BIDIRECTIONAL);
g_object_set (source, "foo", 10, NULL);
g_assert_cmpint (source->foo, ==, 10);
g_assert_cmpint (source->bar, ==, 10);
g_object_unref (source);
}
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
@ -548,6 +583,7 @@ main (int argc, char *argv[])
g_test_add_func ("/binding/chain", binding_chain); g_test_add_func ("/binding/chain", binding_chain);
g_test_add_func ("/binding/sync-create", binding_sync_create); g_test_add_func ("/binding/sync-create", binding_sync_create);
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);
return g_test_run (); return g_test_run ();
} }