mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-11 15:06:14 +01:00
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
This commit is contained in:
parent
a2172ee247
commit
2d3d8cdce2
@ -3151,6 +3151,7 @@ g_application_get_default
|
|||||||
g_application_mark_busy
|
g_application_mark_busy
|
||||||
g_application_unmark_busy
|
g_application_unmark_busy
|
||||||
g_application_bind_busy_property
|
g_application_bind_busy_property
|
||||||
|
g_application_unbind_busy_property
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
G_TYPE_APPLICATION
|
G_TYPE_APPLICATION
|
||||||
G_APPLICATION
|
G_APPLICATION
|
||||||
|
@ -2711,15 +2711,11 @@ g_application_notify_busy_binding (GObject *object,
|
|||||||
* g_application_bind_busy_property:
|
* g_application_bind_busy_property:
|
||||||
* @application: a #GApplication
|
* @application: a #GApplication
|
||||||
* @object: a #GObject
|
* @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
|
* Marks @application as busy (see g_application_mark_busy()) while
|
||||||
* @property on @object is %TRUE.
|
* @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
|
* The binding holds a reference to @application while it is active, but
|
||||||
* not to @object. Instead, the binding is destroyed when @object is
|
* not to @object. Instead, the binding is destroyed when @object is
|
||||||
* finalized.
|
* finalized.
|
||||||
@ -2731,45 +2727,78 @@ g_application_bind_busy_property (GApplication *application,
|
|||||||
gpointer object,
|
gpointer object,
|
||||||
const gchar *property)
|
const gchar *property)
|
||||||
{
|
{
|
||||||
GClosure *closure = NULL;
|
|
||||||
guint notify_id;
|
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_APPLICATION (application));
|
||||||
g_return_if_fail (G_IS_OBJECT (object));
|
g_return_if_fail (G_IS_OBJECT (object));
|
||||||
|
g_return_if_fail (property != NULL);
|
||||||
|
|
||||||
notify_id = g_signal_lookup ("notify", G_TYPE_OBJECT);
|
notify_id = g_signal_lookup ("notify", G_TYPE_OBJECT);
|
||||||
|
property_quark = g_quark_from_string (property);
|
||||||
if (property != NULL)
|
|
||||||
{
|
|
||||||
GParamSpec *pspec;
|
|
||||||
GApplicationBusyBinding *binding;
|
|
||||||
|
|
||||||
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), property);
|
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), property);
|
||||||
|
|
||||||
g_return_if_fail (pspec != NULL && pspec->value_type == G_TYPE_BOOLEAN);
|
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)
|
||||||
|
{
|
||||||
|
g_critical ("%s: '%s' is already bound to the busy state of the application", G_STRFUNC, property);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
binding = g_slice_new (GApplicationBusyBinding);
|
binding = g_slice_new (GApplicationBusyBinding);
|
||||||
binding->app = g_object_ref (application);
|
binding->app = g_object_ref (application);
|
||||||
binding->is_busy = FALSE;
|
binding->is_busy = FALSE;
|
||||||
|
|
||||||
/* fetch the initial value */
|
|
||||||
g_application_notify_busy_binding (object, pspec, binding);
|
|
||||||
|
|
||||||
closure = g_cclosure_new (G_CALLBACK (g_application_notify_busy_binding), binding,
|
closure = g_cclosure_new (G_CALLBACK (g_application_notify_busy_binding), binding,
|
||||||
g_application_busy_binding_destroy);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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
|
* g_application_unbind_busy_property:
|
||||||
* old and the new property are set to TRUE
|
* @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
|
||||||
*/
|
*/
|
||||||
handler_id = g_signal_handler_find (object, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC, notify_id,
|
void
|
||||||
0, NULL, g_application_notify_busy_binding, NULL);
|
g_application_unbind_busy_property (GApplication *application,
|
||||||
if (handler_id > 0)
|
gpointer object,
|
||||||
g_signal_handler_disconnect (object, handler_id);
|
const gchar *property)
|
||||||
|
{
|
||||||
|
guint notify_id;
|
||||||
|
GQuark property_quark;
|
||||||
|
gulong handler_id;
|
||||||
|
|
||||||
if (closure)
|
g_return_if_fail (G_IS_APPLICATION (application));
|
||||||
g_signal_connect_closure_by_id (object, notify_id, g_quark_from_string (property), closure, FALSE);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_signal_handler_disconnect (object, handler_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Epilogue {{{1 */
|
/* Epilogue {{{1 */
|
||||||
|
@ -231,6 +231,11 @@ void g_application_bind_busy_property (GApplic
|
|||||||
gpointer object,
|
gpointer object,
|
||||||
const gchar *property);
|
const gchar *property);
|
||||||
|
|
||||||
|
GLIB_AVAILABLE_IN_2_44
|
||||||
|
void g_application_unbind_busy_property (GApplication *application,
|
||||||
|
gpointer object,
|
||||||
|
const gchar *property);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __G_APPLICATION_H__ */
|
#endif /* __G_APPLICATION_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user