[glib] application: introduce methods to mark the application as busy



commit db325cd6a3ed3e95d497d7a4087c0f37f155ef01
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Wed Apr 3 14:12:03 2013 -0400

    application: introduce methods to mark the application as busy
    
    This feature is intended for clients that want to signal a desktop shell
    their busy state, for instance because a long-running operation is
    pending.
    The API works in a similar way to g_application_hold and
    g_application_release: applications can call g_application_mark_busy()
    to increase a counter that will keep the application marked as busy
    until the counter reaches zero again.
    
    The busy state is exported read-only on the org.gtk.Application interface
    for clients to use.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=672018

 docs/reference/gio/gio-sections.txt |    3 ++
 gio/gapplication.c                  |   58 +++++++++++++++++++++++++++++++++++
 gio/gapplication.h                  |    5 +++
 gio/gapplicationimpl-dbus.c         |   55 +++++++++++++++++++++++++++++++++
 gio/gapplicationimpl.h              |    3 ++
 5 files changed, 124 insertions(+), 0 deletions(-)
---
diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt
index add972f..52ebbbb 100644
--- a/docs/reference/gio/gio-sections.txt
+++ b/docs/reference/gio/gio-sections.txt
@@ -2953,6 +2953,9 @@ g_application_open
 g_application_run
 g_application_set_default
 g_application_get_default
+<SUBSECTION>
+g_application_mark_busy
+g_application_unmark_busy
 <SUBSECTION Standard>
 G_TYPE_APPLICATION
 G_APPLICATION
diff --git a/gio/gapplication.c b/gio/gapplication.c
index 36c91bd..638bb31 100644
--- a/gio/gapplication.c
+++ b/gio/gapplication.c
@@ -239,6 +239,7 @@ struct _GApplicationPrivate
   guint              inactivity_timeout_id;
   guint              inactivity_timeout;
   guint              use_count;
+  guint              busy_count;
 
   guint              is_registered : 1;
   guint              is_remote : 1;
@@ -1850,5 +1851,62 @@ g_application_quit (GApplication *application)
   application->priv->must_quit_now = TRUE;
 }
 
+/**
+ * g_application_mark_busy:
+ * @application: a #GApplication
+ *
+ * Increases the busy count of @application.
+ *
+ * Use this function to indicate that the application is busy, for instance
+ * while a long running operation is pending.
+ *
+ * The busy state will be exposed to other processes, so a session shell will
+ * use that information to indicate the state to the user (e.g. with a
+ * spinner).
+ *
+ * To cancel the busy indication, use g_application_unmark_busy().
+ *
+ * Since: 2.38
+ **/
+void
+g_application_mark_busy (GApplication *application)
+{
+  gboolean was_busy;
+
+  g_return_if_fail (G_IS_APPLICATION (application));
+
+  was_busy = (application->priv->busy_count > 0);
+  application->priv->busy_count++;
+
+  if (!was_busy)
+    g_application_impl_set_busy_state (application->priv->impl, TRUE);
+}
+
+/**
+ * g_application_unmark_busy:
+ * @application: a #GApplication
+ *
+ * Decreases the busy count of @application.
+ *
+ * When the busy count reaches zero, the new state will be propagated
+ * to other processes.
+ *
+ * This function must only be called to cancel the effect of a previous
+ * call to g_application_mark_busy().
+ *
+ * Since: 2.38
+ **/
+void
+g_application_unmark_busy (GApplication *application)
+{
+  g_return_if_fail (G_IS_APPLICATION (application));
+  g_return_if_fail (application->priv->busy_count > 0);
+
+  application->priv->busy_count--;
+
+  if (application->priv->busy_count == 0)
+    g_application_impl_set_busy_state (application->priv->impl, FALSE);
+}
+
 /* Epilogue {{{1 */
 /* vim:set foldmethod=marker: */
diff --git a/gio/gapplication.h b/gio/gapplication.h
index 7829892..5878a7f 100644
--- a/gio/gapplication.h
+++ b/gio/gapplication.h
@@ -196,6 +196,11 @@ GApplication *          g_application_get_default                       (void);
 GLIB_AVAILABLE_IN_2_32
 void                    g_application_set_default                       (GApplication             
*application);
 
+GLIB_AVAILABLE_IN_2_38
+void                    g_application_mark_busy                         (GApplication             
*application);
+GLIB_AVAILABLE_IN_2_38
+void                    g_application_unmark_busy                       (GApplication             
*application);
+
 G_END_DECLS
 
 #endif /* __G_APPLICATION_H__ */
diff --git a/gio/gapplicationimpl-dbus.c b/gio/gapplicationimpl-dbus.c
index 5afb0d0..68b0d28 100644
--- a/gio/gapplicationimpl-dbus.c
+++ b/gio/gapplicationimpl-dbus.c
@@ -67,6 +67,7 @@ static const gchar org_gtk_Application_xml[] =
         "<arg type='a{sv}' name='platform-data' direction='in'/>"
         "<arg type='i' name='exit-status' direction='out'/>"
       "</method>"
+    "<property name='Busy' type='b' access='read'/>"
     "</interface>"
   "</node>";
 
@@ -99,6 +100,7 @@ struct _GApplicationImpl
 
   gboolean         properties_live;
   gboolean         primary;
+  gboolean         busy;
   GApplication    *app;
 };
 
@@ -106,6 +108,46 @@ struct _GApplicationImpl
 static GApplicationCommandLine *
 g_dbus_command_line_new (GDBusMethodInvocation *invocation);
 
+static GVariant *
+g_application_impl_get_property (GDBusConnection *connection,
+                                 const gchar  *sender,
+                                 const gchar  *object_path,
+                                 const gchar  *interface_name,
+                                 const gchar  *property_name,
+                                 GError      **error,
+                                 gpointer      user_data)
+{
+  GApplicationImpl *impl = user_data;
+
+  if (strcmp (property_name, "Busy") == 0)
+    return g_variant_new_boolean (impl->busy);
+
+  g_assert_not_reached ();
+
+  return NULL;
+}
+
+static void
+send_property_change (GApplicationImpl *impl)
+{
+  GVariantBuilder builder;
+
+  g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
+  g_variant_builder_add (&builder,
+                         "{sv}",
+                         "Busy", g_variant_new_boolean (impl->busy));
+
+  g_dbus_connection_emit_signal (impl->session_bus,
+                                 NULL,
+                                 impl->object_path,
+                                 "org.freedesktop.DBus.Properties",
+                                 "PropertiesChanged",
+                                 g_variant_new ("(sa{sv}as)",
+                                                "org.gtk.Application",
+                                                &builder,
+                                                NULL),
+                                 NULL);
+}
 
 static void
 g_application_impl_method_call (GDBusConnection       *connection,
@@ -229,6 +271,8 @@ g_application_impl_attempt_primary (GApplicationImpl  *impl,
 {
   const static GDBusInterfaceVTable vtable = {
     g_application_impl_method_call,
+    g_application_impl_get_property,
+    NULL /* set_property */
   };
   GApplicationClass *app_class = G_APPLICATION_GET_CLASS (impl->app);
   GVariant *reply;
@@ -353,6 +397,17 @@ g_application_impl_stop_primary (GApplicationImpl *impl)
 }
 
 void
+g_application_impl_set_busy_state (GApplicationImpl *impl,
+                                   gboolean          busy)
+{
+  if (impl->busy != busy)
+    {
+      impl->busy = busy;
+      send_property_change (impl);
+    }
+}
+
+void
 g_application_impl_destroy (GApplicationImpl *impl)
 {
   g_application_impl_stop_primary (impl);
diff --git a/gio/gapplicationimpl.h b/gio/gapplicationimpl.h
index 8743d0f..85d7a3e 100644
--- a/gio/gapplicationimpl.h
+++ b/gio/gapplicationimpl.h
@@ -39,3 +39,6 @@ void                    g_application_impl_flush                        (GApplic
 GDBusConnection *       g_application_impl_get_dbus_connection          (GApplicationImpl   *impl);
 
 const gchar *           g_application_impl_get_dbus_object_path         (GApplicationImpl   *impl);
+
+void                    g_application_impl_set_busy_state               (GApplicationImpl   *impl,
+                                                                         gboolean            busy);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]