[glib] gapplication: tune busy-binding
- From: Lars Uebernickel <larsu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] gapplication: tune busy-binding
- Date: Wed, 18 Feb 2015 19:17:36 +0000 (UTC)
commit 2d3d8cdce2e30978c259bdbc61c2af26ee081533
Author: Lars Uebernickel <lars uebernickel canonical com>
Date: Tue Feb 17 08:39:05 2015 +0100
gapplication: tune busy-binding
g_application_bind_busy_property() had the restriction that only one
property can be bound per object, so that NULL could be used to unbind.
Even though this is enough for most uses, it is a weird API.
Lift that restriction and add an explicit unbind function.
https://bugzilla.gnome.org/show_bug.cgi?id=744565
docs/reference/gio/gio-sections.txt | 1 +
gio/gapplication.c | 89 +++++++++++++++++++++++------------
gio/gapplication.h | 5 ++
3 files changed, 65 insertions(+), 30 deletions(-)
---
diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt
index 6674c4c..adc7152 100644
--- a/docs/reference/gio/gio-sections.txt
+++ b/docs/reference/gio/gio-sections.txt
@@ -3151,6 +3151,7 @@ g_application_get_default
g_application_mark_busy
g_application_unmark_busy
g_application_bind_busy_property
+g_application_unbind_busy_property
<SUBSECTION Standard>
G_TYPE_APPLICATION
G_APPLICATION
diff --git a/gio/gapplication.c b/gio/gapplication.c
index f4a65fe..e51f0cb 100644
--- a/gio/gapplication.c
+++ b/gio/gapplication.c
@@ -2711,15 +2711,11 @@ g_application_notify_busy_binding (GObject *object,
* g_application_bind_busy_property:
* @application: a #GApplication
* @object: a #GObject
- * @property: (allow-none): the name of a boolean property of @object
+ * @property: the name of a boolean property of @object
*
* Marks @application as busy (see g_application_mark_busy()) while
* @property on @object is %TRUE.
*
- * Multiple such bindings can exist, but only one property can be bound
- * per object. Calling this function again for the same object replaces
- * a previous binding. If @property is %NULL, the binding is destroyed.
- *
* The binding holds a reference to @application while it is active, but
* not to @object. Instead, the binding is destroyed when @object is
* finalized.
@@ -2731,45 +2727,78 @@ g_application_bind_busy_property (GApplication *application,
gpointer object,
const gchar *property)
{
- GClosure *closure = NULL;
guint notify_id;
- gulong handler_id;
+ GQuark property_quark;
+ GParamSpec *pspec;
+ GApplicationBusyBinding *binding;
+ GClosure *closure;
g_return_if_fail (G_IS_APPLICATION (application));
g_return_if_fail (G_IS_OBJECT (object));
+ g_return_if_fail (property != NULL);
notify_id = g_signal_lookup ("notify", G_TYPE_OBJECT);
+ property_quark = g_quark_from_string (property);
+ pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), property);
- if (property != NULL)
+ g_return_if_fail (pspec != NULL && pspec->value_type == G_TYPE_BOOLEAN);
+
+ if (g_signal_handler_find (object, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | G_SIGNAL_MATCH_FUNC,
+ notify_id, property_quark, NULL, g_application_notify_busy_binding, NULL) > 0)
{
- GParamSpec *pspec;
- GApplicationBusyBinding *binding;
+ g_critical ("%s: '%s' is already bound to the busy state of the application", G_STRFUNC, property);
+ return;
+ }
- pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), property);
- g_return_if_fail (pspec != NULL && pspec->value_type == G_TYPE_BOOLEAN);
+ binding = g_slice_new (GApplicationBusyBinding);
+ binding->app = g_object_ref (application);
+ binding->is_busy = FALSE;
- binding = g_slice_new (GApplicationBusyBinding);
- binding->app = g_object_ref (application);
- binding->is_busy = FALSE;
+ closure = g_cclosure_new (G_CALLBACK (g_application_notify_busy_binding), binding,
+ g_application_busy_binding_destroy);
+ g_signal_connect_closure_by_id (object, notify_id, property_quark, closure, FALSE);
- /* fetch the initial value */
- g_application_notify_busy_binding (object, pspec, binding);
+ /* fetch the initial value */
+ g_application_notify_busy_binding (object, pspec, binding);
+}
- closure = g_cclosure_new (G_CALLBACK (g_application_notify_busy_binding), binding,
- g_application_busy_binding_destroy);
- }
+/**
+ * g_application_unbind_busy_property:
+ * @application: a #GApplication
+ * @object: a #GObject
+ * @property: the name of a boolean property of @object
+ *
+ * Destroys a binding between @property and the busy state of
+ * @application that was previously created with
+ * g_application_bind_busy_property().
+ *
+ * Since: 2.44
+ */
+void
+g_application_unbind_busy_property (GApplication *application,
+ gpointer object,
+ const gchar *property)
+{
+ guint notify_id;
+ GQuark property_quark;
+ gulong handler_id;
- /* unset a previous binding after fetching the new initial value, so
- * that we don't switch to FALSE for a brief moment when both the
- * old and the new property are set to TRUE
- */
- handler_id = g_signal_handler_find (object, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC, notify_id,
- 0, NULL, g_application_notify_busy_binding, NULL);
- if (handler_id > 0)
- g_signal_handler_disconnect (object, handler_id);
+ g_return_if_fail (G_IS_APPLICATION (application));
+ g_return_if_fail (G_IS_OBJECT (object));
+ g_return_if_fail (property != NULL);
+
+ notify_id = g_signal_lookup ("notify", G_TYPE_OBJECT);
+ property_quark = g_quark_from_string (property);
+
+ handler_id = g_signal_handler_find (object, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL |
G_SIGNAL_MATCH_FUNC,
+ notify_id, property_quark, NULL, g_application_notify_busy_binding,
NULL);
+ if (handler_id == 0)
+ {
+ g_critical ("%s: '%s' is not bound to the busy state of the application", G_STRFUNC, property);
+ return;
+ }
- if (closure)
- g_signal_connect_closure_by_id (object, notify_id, g_quark_from_string (property), closure, FALSE);
+ g_signal_handler_disconnect (object, handler_id);
}
/* Epilogue {{{1 */
diff --git a/gio/gapplication.h b/gio/gapplication.h
index a5e9712..98ceb90 100644
--- a/gio/gapplication.h
+++ b/gio/gapplication.h
@@ -231,6 +231,11 @@ void g_application_bind_busy_property (GApplic
gpointer object,
const gchar *property);
+GLIB_AVAILABLE_IN_2_44
+void g_application_unbind_busy_property (GApplication
*application,
+ gpointer object,
+ const gchar *property);
+
G_END_DECLS
#endif /* __G_APPLICATION_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]