1 /* gbinding.c: Binding for object properties
3 * Copyright (C) 2010 Intel Corp.
5 * SPDX-License-Identifier: LGPL-2.1-or-later
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General
18 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 * Author: Emmanuele Bassi <ebassi@linux.intel.com>
26 * @Short_Description: Bind two object properties
28 * #GBinding is the representation of a binding between a property on a
29 * #GObject instance (or source) and another property on another #GObject
30 * instance (or target).
32 * Whenever the source property changes, the same value is applied to the
33 * target property; for instance, the following binding:
35 * |[<!-- language="C" -->
36 * g_object_bind_property (object1, "property-a",
37 * object2, "property-b",
41 * will cause the property named "property-b" of @object2 to be updated
42 * every time g_object_set() or the specific accessor changes the value of
43 * the property "property-a" of @object1.
45 * It is possible to create a bidirectional binding between two properties
46 * of two #GObject instances, so that if either property changes, the
47 * other is updated as well, for instance:
49 * |[<!-- language="C" -->
50 * g_object_bind_property (object1, "property-a",
51 * object2, "property-b",
52 * G_BINDING_BIDIRECTIONAL);
55 * will keep the two properties in sync.
57 * It is also possible to set a custom transformation function (in both
58 * directions, in case of a bidirectional binding) to apply a custom
59 * transformation from the source value to the target value before
60 * applying it; for instance, the following binding:
62 * |[<!-- language="C" -->
63 * g_object_bind_property_full (adjustment1, "value",
64 * adjustment2, "value",
65 * G_BINDING_BIDIRECTIONAL,
66 * celsius_to_fahrenheit,
67 * fahrenheit_to_celsius,
71 * will keep the "value" property of the two adjustments in sync; the
72 * @celsius_to_fahrenheit function will be called whenever the "value"
73 * property of @adjustment1 changes and will transform the current value
74 * of the property before applying it to the "value" property of @adjustment2.
76 * Vice versa, the @fahrenheit_to_celsius function will be called whenever
77 * the "value" property of @adjustment2 changes, and will transform the
78 * current value of the property before applying it to the "value" property
81 * Note that #GBinding does not resolve cycles by itself; a cycle like
84 * object1:propertyA -> object2:propertyB
85 * object2:propertyB -> object3:propertyC
86 * object3:propertyC -> object1:propertyA
89 * might lead to an infinite loop. The loop, in this particular case,
90 * can be avoided if the objects emit the #GObject::notify signal only
91 * if the value has effectively been changed. A binding is implemented
92 * using the #GObject::notify signal, so it is susceptible to all the
93 * various ways of blocking a signal emission, like g_signal_stop_emission()
94 * or g_signal_handler_block().
96 * A binding will be severed, and the resources it allocates freed, whenever
97 * either one of the #GObject instances it refers to are finalized, or when
98 * the #GBinding instance loses its last reference.
100 * Bindings for languages with garbage collection can use
101 * g_binding_unbind() to explicitly release a binding between the source
102 * and target properties, instead of relying on the last reference on the
103 * binding, source, and target instances to drop.
105 * #GBinding is available since GObject 2.26
112 #include "gbinding.h"
114 #include "gmarshal.h"
117 #include "gparamspecs.h"
118 #include "gvaluetypes.h"
120 #include "glibintl.h"
124 g_binding_flags_get_type (void)
126 static gsize static_g_define_type_id = 0;
128 if (g_once_init_enter (&static_g_define_type_id))
130 static const GFlagsValue values[] = {
131 { G_BINDING_DEFAULT, "G_BINDING_DEFAULT", "default" },
132 { G_BINDING_BIDIRECTIONAL, "G_BINDING_BIDIRECTIONAL", "bidirectional" },
133 { G_BINDING_SYNC_CREATE, "G_BINDING_SYNC_CREATE", "sync-create" },
134 { G_BINDING_INVERT_BOOLEAN, "G_BINDING_INVERT_BOOLEAN", "invert-boolean" },
137 GType g_define_type_id =
138 g_flags_register_static (g_intern_static_string ("GBindingFlags"), values);
139 g_once_init_leave (&static_g_define_type_id, g_define_type_id);
142 return static_g_define_type_id;
145 /* Reference counted helper struct that is passed to all callbacks to ensure
146 * that they never work with already freed objects without having to store
147 * strong references for them.
149 * Using strong references anywhere is not possible because of the API
150 * requirements of GBinding, specifically that the initial reference of the
151 * GBinding is owned by the source/target and the caller and can be released
152 * either by the source/target being finalized or calling g_binding_unbind().
154 * As such, the only strong reference has to be owned by both weak notifies of
155 * the source and target and the first to be called has to release it.
161 gboolean binding_removed;
164 static BindingContext *
165 binding_context_ref (BindingContext *context)
167 return g_atomic_rc_box_acquire (context);
171 binding_context_clear (BindingContext *context)
173 g_weak_ref_clear (&context->binding);
174 g_weak_ref_clear (&context->source);
175 g_weak_ref_clear (&context->target);
179 binding_context_unref (BindingContext *context)
181 g_atomic_rc_box_release_full (context, (GDestroyNotify) binding_context_clear);
184 /* Reference counting for the transform functions to ensure that they're always
185 * valid while making use of them in the property notify callbacks.
187 * The transform functions are released when unbinding but unbinding can happen
188 * while the transform functions are currently in use inside the notify callbacks.
191 GBindingTransformFunc transform_s2t;
192 GBindingTransformFunc transform_t2s;
194 gpointer transform_data;
195 GDestroyNotify destroy_notify;
198 static TransformFunc *
199 transform_func_new (GBindingTransformFunc transform_s2t,
200 GBindingTransformFunc transform_t2s,
201 gpointer transform_data,
202 GDestroyNotify destroy_notify)
204 TransformFunc *func = g_atomic_rc_box_new0 (TransformFunc);
206 func->transform_s2t = transform_s2t;
207 func->transform_t2s = transform_t2s;
208 func->transform_data = transform_data;
209 func->destroy_notify = destroy_notify;
214 static TransformFunc *
215 transform_func_ref (TransformFunc *func)
217 return g_atomic_rc_box_acquire (func);
221 transform_func_clear (TransformFunc *func)
223 if (func->destroy_notify)
224 func->destroy_notify (func->transform_data);
228 transform_func_unref (TransformFunc *func)
230 g_atomic_rc_box_release_full (func, (GDestroyNotify) transform_func_clear);
233 #define G_BINDING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_BINDING, GBindingClass))
234 #define G_IS_BINDING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_BINDING))
235 #define G_BINDING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_BINDING, GBindingClass))
237 typedef struct _GBindingClass GBindingClass;
241 GObject parent_instance;
243 /* no reference is held on the objects, to avoid cycles */
244 BindingContext *context;
246 /* protects transform_func, source, target property notify and
247 * target_weak_notify_installed for unbinding */
250 /* transform functions, only NULL after unbinding */
251 TransformFunc *transform_func; /* LOCK: unbind_lock */
253 /* the property names are interned, so they should not be freed */
254 const gchar *source_property;
255 const gchar *target_property;
257 GParamSpec *source_pspec;
258 GParamSpec *target_pspec;
262 guint source_notify; /* LOCK: unbind_lock */
263 guint target_notify; /* LOCK: unbind_lock */
264 gboolean target_weak_notify_installed; /* LOCK: unbind_lock */
266 /* a guard, to avoid loops */
270 struct _GBindingClass
272 GObjectClass parent_class;
281 PROP_SOURCE_PROPERTY,
282 PROP_TARGET_PROPERTY,
286 static guint gobject_notify_signal_id;
288 G_DEFINE_TYPE (GBinding, g_binding, G_TYPE_OBJECT)
290 static void weak_unbind (gpointer user_data, GObject *where_the_object_was);
292 /* Must be called with the unbind lock held, context/binding != NULL and strong
293 * references to source/target or NULL.
294 * Return TRUE if the binding was actually removed and FALSE if it was already
297 unbind_internal_locked (BindingContext *context, GBinding *binding, GObject *source, GObject *target)
299 gboolean binding_was_removed = FALSE;
301 g_assert (context != NULL);
302 g_assert (binding != NULL);
304 /* If the target went away we still have a strong reference to the source
305 * here and can clear it from the binding. Otherwise if the source went away
306 * we can clear the target from the binding. Finalizing an object clears its
307 * signal handlers and all weak references pointing to it before calling
308 * weak notify callbacks.
310 * If both still exist we clean up everything set up by the binding.
314 /* We always add/remove the source property notify and the weak notify
315 * of the source at the same time, and should only ever do that once. */
316 if (binding->source_notify != 0)
318 g_signal_handler_disconnect (source, binding->source_notify);
320 g_object_weak_unref (source, weak_unbind, context);
321 binding_context_unref (context);
323 binding->source_notify = 0;
325 g_weak_ref_set (&context->source, NULL);
328 /* As above, but with the target. If source==target then no weak notify was
329 * installed for the target, which is why that is stored as a separate
330 * boolean inside the binding. */
333 /* There might be a target property notify without a weak notify on the
334 * target or the other way around, so these have to be handled
335 * independently here unlike for the source. */
336 if (binding->target_notify != 0)
338 g_signal_handler_disconnect (target, binding->target_notify);
340 binding->target_notify = 0;
342 g_weak_ref_set (&context->target, NULL);
344 /* Remove the weak notify from the target, at most once */
345 if (binding->target_weak_notify_installed)
347 g_object_weak_unref (target, weak_unbind, context);
348 binding_context_unref (context);
349 binding->target_weak_notify_installed = FALSE;
353 /* Make sure to remove the binding only once and return to the caller that
354 * this was the call that actually removed it. */
355 if (!context->binding_removed)
357 context->binding_removed = TRUE;
358 binding_was_removed = TRUE;
361 return binding_was_removed;
364 /* the basic assumption is that if either the source or the target
365 * goes away then the binding does not exist any more and it should
366 * be reaped as well. Each weak notify owns a strong reference to the
367 * binding that should be dropped here. */
369 weak_unbind (gpointer user_data,
370 GObject *where_the_object_was)
372 BindingContext *context = user_data;
374 GObject *source, *target;
375 gboolean binding_was_removed = FALSE;
376 TransformFunc *transform_func;
378 binding = g_weak_ref_get (&context->binding);
381 /* The binding was already destroyed before so there's nothing to do */
382 binding_context_unref (context);
386 g_mutex_lock (&binding->unbind_lock);
388 transform_func = g_steal_pointer (&binding->transform_func);
390 source = g_weak_ref_get (&context->source);
391 target = g_weak_ref_get (&context->target);
393 /* If this is called then either the source or target or both must be in the
394 * process of being disposed. If this happens as part of g_object_unref()
395 * then the weak references are actually cleared, otherwise if disposing
396 * happens as part of g_object_run_dispose() then they would still point to
397 * the disposed object.
399 * If the object this is being called for is either the source or the target
400 * and we actually got a strong reference to it nonetheless (see above),
401 * then signal handlers and weak notifies for it are already disconnected
402 * and they must not be disconnected a second time. Instead simply clear the
403 * weak reference and be done with it.
405 * See https://gitlab.gnome.org/GNOME/glib/-/issues/2266 */
407 if (source == where_the_object_was)
409 g_weak_ref_set (&context->source, NULL);
410 g_clear_object (&source);
413 if (target == where_the_object_was)
415 g_weak_ref_set (&context->target, NULL);
416 g_clear_object (&target);
419 binding_was_removed = unbind_internal_locked (context, binding, source, target);
421 g_mutex_unlock (&binding->unbind_lock);
423 /* Unref source, target and transform_func after the mutex is unlocked as it
424 * might release the last reference, which then accesses the mutex again */
425 g_clear_object (&target);
426 g_clear_object (&source);
428 g_clear_pointer (&transform_func, transform_func_unref);
430 /* This releases the strong reference we got from the weak ref above */
431 g_object_unref (binding);
433 /* This will take care of the binding itself. */
434 if (binding_was_removed)
435 g_object_unref (binding);
437 /* Each weak notify owns a reference to the binding context. */
438 binding_context_unref (context);
442 default_transform (GBinding *binding,
443 const GValue *value_a,
445 gpointer user_data G_GNUC_UNUSED)
447 /* if it's not the same type, try to convert it using the GValue
448 * transformation API; otherwise just copy it
450 if (!g_type_is_a (G_VALUE_TYPE (value_a), G_VALUE_TYPE (value_b)))
452 /* are these two types compatible (can be directly copied)? */
453 if (g_value_type_compatible (G_VALUE_TYPE (value_a),
454 G_VALUE_TYPE (value_b)))
456 g_value_copy (value_a, value_b);
460 if (g_value_type_transformable (G_VALUE_TYPE (value_a),
461 G_VALUE_TYPE (value_b)))
463 if (g_value_transform (value_a, value_b))
467 g_critical ("%s: Unable to convert a value of type %s to a "
470 g_type_name (G_VALUE_TYPE (value_a)),
471 g_type_name (G_VALUE_TYPE (value_b)));
476 g_value_copy (value_a, value_b);
481 default_invert_boolean_transform (GBinding *binding,
482 const GValue *value_a,
484 gpointer user_data G_GNUC_UNUSED)
488 g_assert (G_VALUE_HOLDS_BOOLEAN (value_a));
489 g_assert (G_VALUE_HOLDS_BOOLEAN (value_b));
491 value = g_value_get_boolean (value_a);
494 g_value_set_boolean (value_b, value);
500 on_source_notify (GObject *source,
502 BindingContext *context)
506 TransformFunc *transform_func;
507 GValue from_value = G_VALUE_INIT;
508 GValue to_value = G_VALUE_INIT;
511 binding = g_weak_ref_get (&context->binding);
515 if (binding->is_frozen)
517 g_object_unref (binding);
521 target = g_weak_ref_get (&context->target);
524 g_object_unref (binding);
528 /* Get the transform function safely */
529 g_mutex_lock (&binding->unbind_lock);
530 if (!binding->transform_func)
532 /* it was released already during unbinding, nothing to do here */
533 g_mutex_unlock (&binding->unbind_lock);
536 transform_func = transform_func_ref (binding->transform_func);
537 g_mutex_unlock (&binding->unbind_lock);
539 g_value_init (&from_value, G_PARAM_SPEC_VALUE_TYPE (binding->source_pspec));
540 g_value_init (&to_value, G_PARAM_SPEC_VALUE_TYPE (binding->target_pspec));
542 g_object_get_property (source, binding->source_pspec->name, &from_value);
544 res = transform_func->transform_s2t (binding,
547 transform_func->transform_data);
549 transform_func_unref (transform_func);
553 binding->is_frozen = TRUE;
555 (void) g_param_value_validate (binding->target_pspec, &to_value);
556 g_object_set_property (target, binding->target_pspec->name, &to_value);
558 binding->is_frozen = FALSE;
561 g_value_unset (&from_value);
562 g_value_unset (&to_value);
564 g_object_unref (target);
565 g_object_unref (binding);
569 on_target_notify (GObject *target,
571 BindingContext *context)
575 TransformFunc *transform_func;
576 GValue from_value = G_VALUE_INIT;
577 GValue to_value = G_VALUE_INIT;
580 binding = g_weak_ref_get (&context->binding);
584 if (binding->is_frozen)
586 g_object_unref (binding);
590 source = g_weak_ref_get (&context->source);
593 g_object_unref (binding);
597 /* Get the transform function safely */
598 g_mutex_lock (&binding->unbind_lock);
599 if (!binding->transform_func)
601 /* it was released already during unbinding, nothing to do here */
602 g_mutex_unlock (&binding->unbind_lock);
605 transform_func = transform_func_ref (binding->transform_func);
606 g_mutex_unlock (&binding->unbind_lock);
608 g_value_init (&from_value, G_PARAM_SPEC_VALUE_TYPE (binding->target_pspec));
609 g_value_init (&to_value, G_PARAM_SPEC_VALUE_TYPE (binding->source_pspec));
611 g_object_get_property (target, binding->target_pspec->name, &from_value);
613 res = transform_func->transform_t2s (binding,
616 transform_func->transform_data);
617 transform_func_unref (transform_func);
621 binding->is_frozen = TRUE;
623 (void) g_param_value_validate (binding->source_pspec, &to_value);
624 g_object_set_property (source, binding->source_pspec->name, &to_value);
626 binding->is_frozen = FALSE;
629 g_value_unset (&from_value);
630 g_value_unset (&to_value);
632 g_object_unref (source);
633 g_object_unref (binding);
637 g_binding_unbind_internal (GBinding *binding,
638 gboolean unref_binding)
640 BindingContext *context = binding->context;
641 GObject *source, *target;
642 gboolean binding_was_removed = FALSE;
643 TransformFunc *transform_func;
645 g_mutex_lock (&binding->unbind_lock);
647 transform_func = g_steal_pointer (&binding->transform_func);
649 source = g_weak_ref_get (&context->source);
650 target = g_weak_ref_get (&context->target);
652 binding_was_removed = unbind_internal_locked (context, binding, source, target);
654 g_mutex_unlock (&binding->unbind_lock);
656 /* Unref source, target and transform_func after the mutex is unlocked as it
657 * might release the last reference, which then accesses the mutex again */
658 g_clear_object (&target);
659 g_clear_object (&source);
661 g_clear_pointer (&transform_func, transform_func_unref);
663 if (binding_was_removed && unref_binding)
664 g_object_unref (binding);
668 g_binding_finalize (GObject *gobject)
670 GBinding *binding = G_BINDING (gobject);
672 g_binding_unbind_internal (binding, FALSE);
674 binding_context_unref (binding->context);
676 g_mutex_clear (&binding->unbind_lock);
678 G_OBJECT_CLASS (g_binding_parent_class)->finalize (gobject);
681 /* @key must have already been validated with is_valid()
682 * Modifies @key in place. */
684 canonicalize_key (gchar *key)
688 for (p = key; *p != 0; p++)
697 /* @key must have already been validated with is_valid() */
699 is_canonical (const gchar *key)
701 return (strchr (key, '_') == NULL);
705 g_binding_set_property (GObject *gobject,
710 GBinding *binding = G_BINDING (gobject);
715 g_weak_ref_set (&binding->context->source, g_value_get_object (value));
719 g_weak_ref_set (&binding->context->target, g_value_get_object (value));
722 case PROP_SOURCE_PROPERTY:
723 case PROP_TARGET_PROPERTY:
725 gchar *name_copy = NULL;
726 const gchar *name = g_value_get_string (value);
729 /* Ensure the name we intern is canonical. */
730 if (!is_canonical (name))
732 name_copy = g_value_dup_string (value);
733 canonicalize_key (name_copy);
737 if (prop_id == PROP_SOURCE_PROPERTY)
738 dest = &binding->source_property;
740 dest = &binding->target_property;
742 *dest = g_intern_string (name);
749 binding->flags = g_value_get_flags (value);
753 G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
759 g_binding_get_property (GObject *gobject,
764 GBinding *binding = G_BINDING (gobject);
769 g_value_take_object (value, g_weak_ref_get (&binding->context->source));
772 case PROP_SOURCE_PROPERTY:
773 /* @source_property is interned, so we don’t need to take a copy */
774 g_value_set_interned_string (value, binding->source_property);
778 g_value_take_object (value, g_weak_ref_get (&binding->context->target));
781 case PROP_TARGET_PROPERTY:
782 /* @target_property is interned, so we don’t need to take a copy */
783 g_value_set_interned_string (value, binding->target_property);
787 g_value_set_flags (value, binding->flags);
791 G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
797 g_binding_constructed (GObject *gobject)
799 GBinding *binding = G_BINDING (gobject);
800 GBindingTransformFunc transform_func = default_transform;
801 GObject *source, *target;
802 GQuark source_property_detail;
803 GClosure *source_notify_closure;
805 /* assert that we were constructed correctly */
806 source = g_weak_ref_get (&binding->context->source);
807 target = g_weak_ref_get (&binding->context->target);
808 g_assert (source != NULL);
809 g_assert (target != NULL);
810 g_assert (binding->source_property != NULL);
811 g_assert (binding->target_property != NULL);
813 /* we assume a check was performed prior to construction - since
814 * g_object_bind_property_full() does it; we cannot fail construction
815 * anyway, so it would be hard for use to properly warn here
817 binding->source_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (source), binding->source_property);
818 binding->target_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (target), binding->target_property);
819 g_assert (binding->source_pspec != NULL);
820 g_assert (binding->target_pspec != NULL);
822 /* switch to the invert boolean transform if needed */
823 if (binding->flags & G_BINDING_INVERT_BOOLEAN)
824 transform_func = default_invert_boolean_transform;
826 /* set the default transformation functions here */
827 binding->transform_func = transform_func_new (transform_func, transform_func, NULL, NULL);
829 source_property_detail = g_quark_from_string (binding->source_property);
830 source_notify_closure = g_cclosure_new (G_CALLBACK (on_source_notify),
831 binding_context_ref (binding->context),
832 (GClosureNotify) binding_context_unref);
833 binding->source_notify = g_signal_connect_closure_by_id (source,
834 gobject_notify_signal_id,
835 source_property_detail,
836 source_notify_closure,
839 g_object_weak_ref (source, weak_unbind, binding_context_ref (binding->context));
841 if (binding->flags & G_BINDING_BIDIRECTIONAL)
843 GQuark target_property_detail;
844 GClosure *target_notify_closure;
846 target_property_detail = g_quark_from_string (binding->target_property);
847 target_notify_closure = g_cclosure_new (G_CALLBACK (on_target_notify),
848 binding_context_ref (binding->context),
849 (GClosureNotify) binding_context_unref);
850 binding->target_notify = g_signal_connect_closure_by_id (target,
851 gobject_notify_signal_id,
852 target_property_detail,
853 target_notify_closure,
857 if (target != source)
859 g_object_weak_ref (target, weak_unbind, binding_context_ref (binding->context));
861 /* Need to remember separately if a target weak notify was installed as
862 * unlike for the source it can exist independently of the property
863 * notification callback */
864 binding->target_weak_notify_installed = TRUE;
867 g_object_unref (source);
868 g_object_unref (target);
872 g_binding_class_init (GBindingClass *klass)
874 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
876 gobject_notify_signal_id = g_signal_lookup ("notify", G_TYPE_OBJECT);
877 g_assert (gobject_notify_signal_id != 0);
879 gobject_class->constructed = g_binding_constructed;
880 gobject_class->set_property = g_binding_set_property;
881 gobject_class->get_property = g_binding_get_property;
882 gobject_class->finalize = g_binding_finalize;
887 * The #GObject that should be used as the source of the binding
891 g_object_class_install_property (gobject_class, PROP_SOURCE,
892 g_param_spec_object ("source",
894 P_("The source of the binding"),
896 G_PARAM_CONSTRUCT_ONLY |
898 G_PARAM_STATIC_STRINGS));
902 * The #GObject that should be used as the target of the binding
906 g_object_class_install_property (gobject_class, PROP_TARGET,
907 g_param_spec_object ("target",
909 P_("The target of the binding"),
911 G_PARAM_CONSTRUCT_ONLY |
913 G_PARAM_STATIC_STRINGS));
915 * GBinding:source-property:
917 * The name of the property of #GBinding:source that should be used
918 * as the source of the binding.
920 * This should be in [canonical form][canonical-parameter-names] to get the
925 g_object_class_install_property (gobject_class, PROP_SOURCE_PROPERTY,
926 g_param_spec_string ("source-property",
927 P_("Source Property"),
928 P_("The property on the source to bind"),
930 G_PARAM_CONSTRUCT_ONLY |
932 G_PARAM_STATIC_STRINGS));
934 * GBinding:target-property:
936 * The name of the property of #GBinding:target that should be used
937 * as the target of the binding.
939 * This should be in [canonical form][canonical-parameter-names] to get the
944 g_object_class_install_property (gobject_class, PROP_TARGET_PROPERTY,
945 g_param_spec_string ("target-property",
946 P_("Target Property"),
947 P_("The property on the target to bind"),
949 G_PARAM_CONSTRUCT_ONLY |
951 G_PARAM_STATIC_STRINGS));
955 * Flags to be used to control the #GBinding
959 g_object_class_install_property (gobject_class, PROP_FLAGS,
960 g_param_spec_flags ("flags",
962 P_("The binding flags"),
963 G_TYPE_BINDING_FLAGS,
965 G_PARAM_CONSTRUCT_ONLY |
967 G_PARAM_STATIC_STRINGS));
971 g_binding_init (GBinding *binding)
973 g_mutex_init (&binding->unbind_lock);
975 binding->context = g_atomic_rc_box_new0 (BindingContext);
976 g_weak_ref_init (&binding->context->binding, binding);
977 g_weak_ref_init (&binding->context->source, NULL);
978 g_weak_ref_init (&binding->context->target, NULL);
982 * g_binding_get_flags:
983 * @binding: a #GBinding
985 * Retrieves the flags passed when constructing the #GBinding.
987 * Returns: the #GBindingFlags used by the #GBinding
992 g_binding_get_flags (GBinding *binding)
994 g_return_val_if_fail (G_IS_BINDING (binding), G_BINDING_DEFAULT);
996 return binding->flags;
1000 * g_binding_get_source:
1001 * @binding: a #GBinding
1003 * Retrieves the #GObject instance used as the source of the binding.
1005 * A #GBinding can outlive the source #GObject as the binding does not hold a
1006 * strong reference to the source. If the source is destroyed before the
1007 * binding then this function will return %NULL.
1009 * Use g_binding_dup_source() if the source or binding are used from different
1010 * threads as otherwise the pointer returned from this function might become
1011 * invalid if the source is finalized from another thread in the meantime.
1013 * Returns: (transfer none) (nullable): the source #GObject, or %NULL if the
1014 * source does not exist any more.
1016 * Deprecated: 2.68: Use g_binding_dup_source() for a safer version of this
1022 g_binding_get_source (GBinding *binding)
1026 g_return_val_if_fail (G_IS_BINDING (binding), NULL);
1028 source = g_weak_ref_get (&binding->context->source);
1029 /* Unref here, this API is not thread-safe
1030 * FIXME: Remove this API when we next break API */
1032 g_object_unref (source);
1038 * g_binding_dup_source:
1039 * @binding: a #GBinding
1041 * Retrieves the #GObject instance used as the source of the binding.
1043 * A #GBinding can outlive the source #GObject as the binding does not hold a
1044 * strong reference to the source. If the source is destroyed before the
1045 * binding then this function will return %NULL.
1047 * Returns: (transfer full) (nullable): the source #GObject, or %NULL if the
1048 * source does not exist any more.
1053 g_binding_dup_source (GBinding *binding)
1055 g_return_val_if_fail (G_IS_BINDING (binding), NULL);
1057 return g_weak_ref_get (&binding->context->source);
1061 * g_binding_get_target:
1062 * @binding: a #GBinding
1064 * Retrieves the #GObject instance used as the target of the binding.
1066 * A #GBinding can outlive the target #GObject as the binding does not hold a
1067 * strong reference to the target. If the target is destroyed before the
1068 * binding then this function will return %NULL.
1070 * Use g_binding_dup_target() if the target or binding are used from different
1071 * threads as otherwise the pointer returned from this function might become
1072 * invalid if the target is finalized from another thread in the meantime.
1074 * Returns: (transfer none) (nullable): the target #GObject, or %NULL if the
1075 * target does not exist any more.
1077 * Deprecated: 2.68: Use g_binding_dup_target() for a safer version of this
1083 g_binding_get_target (GBinding *binding)
1087 g_return_val_if_fail (G_IS_BINDING (binding), NULL);
1089 target = g_weak_ref_get (&binding->context->target);
1090 /* Unref here, this API is not thread-safe
1091 * FIXME: Remove this API when we next break API */
1093 g_object_unref (target);
1099 * g_binding_dup_target:
1100 * @binding: a #GBinding
1102 * Retrieves the #GObject instance used as the target of the binding.
1104 * A #GBinding can outlive the target #GObject as the binding does not hold a
1105 * strong reference to the target. If the target is destroyed before the
1106 * binding then this function will return %NULL.
1108 * Returns: (transfer full) (nullable): the target #GObject, or %NULL if the
1109 * target does not exist any more.
1114 g_binding_dup_target (GBinding *binding)
1116 g_return_val_if_fail (G_IS_BINDING (binding), NULL);
1118 return g_weak_ref_get (&binding->context->target);
1122 * g_binding_get_source_property:
1123 * @binding: a #GBinding
1125 * Retrieves the name of the property of #GBinding:source used as the source
1128 * Returns: the name of the source property
1133 g_binding_get_source_property (GBinding *binding)
1135 g_return_val_if_fail (G_IS_BINDING (binding), NULL);
1137 return binding->source_property;
1141 * g_binding_get_target_property:
1142 * @binding: a #GBinding
1144 * Retrieves the name of the property of #GBinding:target used as the target
1147 * Returns: the name of the target property
1152 g_binding_get_target_property (GBinding *binding)
1154 g_return_val_if_fail (G_IS_BINDING (binding), NULL);
1156 return binding->target_property;
1161 * @binding: a #GBinding
1163 * Explicitly releases the binding between the source and the target
1164 * property expressed by @binding.
1166 * This function will release the reference that is being held on
1167 * the @binding instance if the binding is still bound; if you want to hold on
1168 * to the #GBinding instance after calling g_binding_unbind(), you will need
1169 * to hold a reference to it.
1171 * Note however that this function does not take ownership of @binding, it
1172 * only unrefs the reference that was initially created by
1173 * g_object_bind_property() and is owned by the binding.
1178 g_binding_unbind (GBinding *binding)
1180 g_return_if_fail (G_IS_BINDING (binding));
1182 g_binding_unbind_internal (binding, TRUE);
1186 * g_object_bind_property_full:
1187 * @source: (type GObject.Object): the source #GObject
1188 * @source_property: the property on @source to bind
1189 * @target: (type GObject.Object): the target #GObject
1190 * @target_property: the property on @target to bind
1191 * @flags: flags to pass to #GBinding
1192 * @transform_to: (scope notified) (nullable): the transformation function
1193 * from the @source to the @target, or %NULL to use the default
1194 * @transform_from: (scope notified) (nullable): the transformation function
1195 * from the @target to the @source, or %NULL to use the default
1196 * @user_data: custom data to be passed to the transformation functions,
1198 * @notify: (nullable): a function to call when disposing the binding, to free
1199 * resources used by the transformation functions, or %NULL if not required
1201 * Complete version of g_object_bind_property().
1203 * Creates a binding between @source_property on @source and @target_property
1204 * on @target, allowing you to set the transformation functions to be used by
1207 * If @flags contains %G_BINDING_BIDIRECTIONAL then the binding will be mutual:
1208 * if @target_property on @target changes then the @source_property on @source
1209 * will be updated as well. The @transform_from function is only used in case
1210 * of bidirectional bindings, otherwise it will be ignored
1212 * The binding will automatically be removed when either the @source or the
1213 * @target instances are finalized. This will release the reference that is
1214 * being held on the #GBinding instance; if you want to hold on to the
1215 * #GBinding instance, you will need to hold a reference to it.
1217 * To remove the binding, call g_binding_unbind().
1219 * A #GObject can have multiple bindings.
1221 * The same @user_data parameter will be used for both @transform_to
1222 * and @transform_from transformation functions; the @notify function will
1223 * be called once, when the binding is removed. If you need different data
1224 * for each transformation function, please use
1225 * g_object_bind_property_with_closures() instead.
1227 * Returns: (transfer none): the #GBinding instance representing the
1228 * binding between the two #GObject instances. The binding is released
1229 * whenever the #GBinding reference count reaches zero.
1234 g_object_bind_property_full (gpointer source,
1235 const gchar *source_property,
1237 const gchar *target_property,
1238 GBindingFlags flags,
1239 GBindingTransformFunc transform_to,
1240 GBindingTransformFunc transform_from,
1242 GDestroyNotify notify)
1247 g_return_val_if_fail (G_IS_OBJECT (source), NULL);
1248 g_return_val_if_fail (source_property != NULL, NULL);
1249 g_return_val_if_fail (g_param_spec_is_valid_name (source_property), NULL);
1250 g_return_val_if_fail (G_IS_OBJECT (target), NULL);
1251 g_return_val_if_fail (target_property != NULL, NULL);
1252 g_return_val_if_fail (g_param_spec_is_valid_name (target_property), NULL);
1254 if (source == target && g_strcmp0 (source_property, target_property) == 0)
1256 g_critical ("Unable to bind the same property on the same instance");
1260 /* remove the G_BINDING_INVERT_BOOLEAN flag in case we have
1261 * custom transformation functions
1263 if ((flags & G_BINDING_INVERT_BOOLEAN) &&
1264 (transform_to != NULL || transform_from != NULL))
1266 flags &= ~G_BINDING_INVERT_BOOLEAN;
1269 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (source), source_property);
1272 g_critical ("%s: The source object of type %s has no property called '%s'",
1274 G_OBJECT_TYPE_NAME (source),
1279 if (!(pspec->flags & G_PARAM_READABLE))
1281 g_critical ("%s: The source object of type %s has no readable property called '%s'",
1283 G_OBJECT_TYPE_NAME (source),
1288 if ((flags & G_BINDING_BIDIRECTIONAL) &&
1289 ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) || !(pspec->flags & G_PARAM_WRITABLE)))
1291 g_critical ("%s: The source object of type %s has no writable property called '%s'",
1293 G_OBJECT_TYPE_NAME (source),
1298 if ((flags & G_BINDING_INVERT_BOOLEAN) &&
1299 !(G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_BOOLEAN))
1301 g_critical ("%s: The G_BINDING_INVERT_BOOLEAN flag can only be used "
1302 "when binding boolean properties; the source property '%s' "
1306 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
1310 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (target), target_property);
1313 g_critical ("%s: The target object of type %s has no property called '%s'",
1315 G_OBJECT_TYPE_NAME (target),
1320 if ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) || !(pspec->flags & G_PARAM_WRITABLE))
1322 g_critical ("%s: The target object of type %s has no writable property called '%s'",
1324 G_OBJECT_TYPE_NAME (target),
1329 if ((flags & G_BINDING_BIDIRECTIONAL) &&
1330 !(pspec->flags & G_PARAM_READABLE))
1332 g_critical ("%s: The target object of type %s has no readable property called '%s'",
1334 G_OBJECT_TYPE_NAME (target),
1339 if ((flags & G_BINDING_INVERT_BOOLEAN) &&
1340 !(G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_BOOLEAN))
1342 g_critical ("%s: The G_BINDING_INVERT_BOOLEAN flag can only be used "
1343 "when binding boolean properties; the target property '%s' "
1347 g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
1351 binding = g_object_new (G_TYPE_BINDING,
1353 "source-property", source_property,
1355 "target-property", target_property,
1359 g_assert (binding->transform_func != NULL);
1361 /* Use default functions if not provided here */
1362 if (transform_to == NULL)
1363 transform_to = binding->transform_func->transform_s2t;
1365 if (transform_from == NULL)
1366 transform_from = binding->transform_func->transform_t2s;
1368 g_clear_pointer (&binding->transform_func, transform_func_unref);
1369 binding->transform_func = transform_func_new (transform_to, transform_from, user_data, notify);
1371 /* synchronize the target with the source by faking an emission of
1372 * the ::notify signal for the source property; this will also take
1373 * care of the bidirectional binding case because the eventual change
1374 * will emit a notification on the target
1376 if (flags & G_BINDING_SYNC_CREATE)
1377 on_source_notify (source, binding->source_pspec, binding->context);
1383 * g_object_bind_property:
1384 * @source: (type GObject.Object): the source #GObject
1385 * @source_property: the property on @source to bind
1386 * @target: (type GObject.Object): the target #GObject
1387 * @target_property: the property on @target to bind
1388 * @flags: flags to pass to #GBinding
1390 * Creates a binding between @source_property on @source and @target_property
1393 * Whenever the @source_property is changed the @target_property is
1394 * updated using the same value. For instance:
1396 * |[<!-- language="C" -->
1397 * g_object_bind_property (action, "active", widget, "sensitive", 0);
1400 * Will result in the "sensitive" property of the widget #GObject instance to be
1401 * updated with the same value of the "active" property of the action #GObject
1404 * If @flags contains %G_BINDING_BIDIRECTIONAL then the binding will be mutual:
1405 * if @target_property on @target changes then the @source_property on @source
1406 * will be updated as well.
1408 * The binding will automatically be removed when either the @source or the
1409 * @target instances are finalized. To remove the binding without affecting the
1410 * @source and the @target you can just call g_object_unref() on the returned
1411 * #GBinding instance.
1413 * Removing the binding by calling g_object_unref() on it must only be done if
1414 * the binding, @source and @target are only used from a single thread and it
1415 * is clear that both @source and @target outlive the binding. Especially it
1416 * is not safe to rely on this if the binding, @source or @target can be
1417 * finalized from different threads. Keep another reference to the binding and
1418 * use g_binding_unbind() instead to be on the safe side.
1420 * A #GObject can have multiple bindings.
1422 * Returns: (transfer none): the #GBinding instance representing the
1423 * binding between the two #GObject instances. The binding is released
1424 * whenever the #GBinding reference count reaches zero.
1429 g_object_bind_property (gpointer source,
1430 const gchar *source_property,
1432 const gchar *target_property,
1433 GBindingFlags flags)
1435 /* type checking is done in g_object_bind_property_full() */
1437 return g_object_bind_property_full (source, source_property,
1438 target, target_property,
1445 typedef struct _TransformData
1447 GClosure *transform_to_closure;
1448 GClosure *transform_from_closure;
1452 bind_with_closures_transform_to (GBinding *binding,
1453 const GValue *source,
1457 TransformData *t_data = data;
1458 GValue params[3] = { G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT };
1459 GValue retval = G_VALUE_INIT;
1462 g_value_init (¶ms[0], G_TYPE_BINDING);
1463 g_value_set_object (¶ms[0], binding);
1465 g_value_init (¶ms[1], G_TYPE_VALUE);
1466 g_value_set_boxed (¶ms[1], source);
1468 g_value_init (¶ms[2], G_TYPE_VALUE);
1469 g_value_set_boxed (¶ms[2], target);
1471 g_value_init (&retval, G_TYPE_BOOLEAN);
1472 g_value_set_boolean (&retval, FALSE);
1474 g_closure_invoke (t_data->transform_to_closure, &retval, 3, params, NULL);
1476 res = g_value_get_boolean (&retval);
1479 const GValue *out_value = g_value_get_boxed (¶ms[2]);
1481 g_assert (out_value != NULL);
1483 g_value_copy (out_value, target);
1486 g_value_unset (¶ms[0]);
1487 g_value_unset (¶ms[1]);
1488 g_value_unset (¶ms[2]);
1489 g_value_unset (&retval);
1495 bind_with_closures_transform_from (GBinding *binding,
1496 const GValue *source,
1500 TransformData *t_data = data;
1501 GValue params[3] = { G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT };
1502 GValue retval = G_VALUE_INIT;
1505 g_value_init (¶ms[0], G_TYPE_BINDING);
1506 g_value_set_object (¶ms[0], binding);
1508 g_value_init (¶ms[1], G_TYPE_VALUE);
1509 g_value_set_boxed (¶ms[1], source);
1511 g_value_init (¶ms[2], G_TYPE_VALUE);
1512 g_value_set_boxed (¶ms[2], target);
1514 g_value_init (&retval, G_TYPE_BOOLEAN);
1515 g_value_set_boolean (&retval, FALSE);
1517 g_closure_invoke (t_data->transform_from_closure, &retval, 3, params, NULL);
1519 res = g_value_get_boolean (&retval);
1522 const GValue *out_value = g_value_get_boxed (¶ms[2]);
1524 g_assert (out_value != NULL);
1526 g_value_copy (out_value, target);
1529 g_value_unset (¶ms[0]);
1530 g_value_unset (¶ms[1]);
1531 g_value_unset (¶ms[2]);
1532 g_value_unset (&retval);
1538 bind_with_closures_free_func (gpointer data)
1540 TransformData *t_data = data;
1542 if (t_data->transform_to_closure != NULL)
1543 g_closure_unref (t_data->transform_to_closure);
1545 if (t_data->transform_from_closure != NULL)
1546 g_closure_unref (t_data->transform_from_closure);
1548 g_slice_free (TransformData, t_data);
1552 * g_object_bind_property_with_closures: (rename-to g_object_bind_property_full)
1553 * @source: (type GObject.Object): the source #GObject
1554 * @source_property: the property on @source to bind
1555 * @target: (type GObject.Object): the target #GObject
1556 * @target_property: the property on @target to bind
1557 * @flags: flags to pass to #GBinding
1558 * @transform_to: a #GClosure wrapping the transformation function
1559 * from the @source to the @target, or %NULL to use the default
1560 * @transform_from: a #GClosure wrapping the transformation function
1561 * from the @target to the @source, or %NULL to use the default
1563 * Creates a binding between @source_property on @source and @target_property
1564 * on @target, allowing you to set the transformation functions to be used by
1567 * This function is the language bindings friendly version of
1568 * g_object_bind_property_full(), using #GClosures instead of
1569 * function pointers.
1571 * Returns: (transfer none): the #GBinding instance representing the
1572 * binding between the two #GObject instances. The binding is released
1573 * whenever the #GBinding reference count reaches zero.
1578 g_object_bind_property_with_closures (gpointer source,
1579 const gchar *source_property,
1581 const gchar *target_property,
1582 GBindingFlags flags,
1583 GClosure *transform_to,
1584 GClosure *transform_from)
1586 TransformData *data;
1588 data = g_slice_new0 (TransformData);
1590 if (transform_to != NULL)
1592 if (G_CLOSURE_NEEDS_MARSHAL (transform_to))
1593 g_closure_set_marshal (transform_to, g_cclosure_marshal_BOOLEAN__BOXED_BOXED);
1595 data->transform_to_closure = g_closure_ref (transform_to);
1596 g_closure_sink (data->transform_to_closure);
1599 if (transform_from != NULL)
1601 if (G_CLOSURE_NEEDS_MARSHAL (transform_from))
1602 g_closure_set_marshal (transform_from, g_cclosure_marshal_BOOLEAN__BOXED_BOXED);
1604 data->transform_from_closure = g_closure_ref (transform_from);
1605 g_closure_sink (data->transform_from_closure);
1608 return g_object_bind_property_full (source, source_property,
1609 target, target_property,
1611 transform_to != NULL ? bind_with_closures_transform_to : NULL,
1612 transform_from != NULL ? bind_with_closures_transform_from : NULL,
1614 bind_with_closures_free_func);