[glib] Rework GApplication API to use GInitable



commit 102c5f6a7d13ec099a8c89db0651172fd3230268
Author: Colin Walters <walters verbum org>
Date:   Wed Jun 16 00:18:09 2010 -0400

    Rework GApplication API to use GInitable
    
    https://bugzilla.gnome.org/show_bug.cgi?id=620952

 gio/gapplication.c      |  407 +++++++++++++++++++++++++++++++++++------------
 gio/gapplication.h      |   21 ++-
 gio/gdbusapplication.c  |  119 ++++++--------
 gio/gio.symbols         |    5 +-
 gio/gnullapplication.c  |   13 +-
 gio/tests/application.c |    2 +-
 gio/tests/testapp.c     |    8 +-
 7 files changed, 388 insertions(+), 187 deletions(-)
---
diff --git a/gio/gapplication.c b/gio/gapplication.c
index 9f85db3..da44828 100644
--- a/gio/gapplication.c
+++ b/gio/gapplication.c
@@ -33,6 +33,7 @@
 #include "glibintl.h"
 
 #include "gioerror.h"
+#include "ginitable.h"
 
 #include "gdbusconnection.h"
 #include "gdbusintrospection.h"
@@ -130,6 +131,11 @@
  * application instance when a second instance fails to take the bus name.
  * @arguments contains the commandline arguments given to the second instance
  * and @data contains platform-specific additional data.
+ * 
+ * On all platforms, @data is guaranteed to have a key "cwd" of type
+ * singature "ay" which contains the working directory of the invoked
+ * executable.
+ * 
  * </para>
  * <para>
  * The <methodname>InvokeAction</methodname> function can be called to
@@ -161,15 +167,22 @@
  * </refsect2>
  */
 
-G_DEFINE_TYPE (GApplication, g_application, G_TYPE_OBJECT);
+static void initable_iface_init       (GInitableIface      *initable_iface);
+
+G_DEFINE_TYPE_WITH_CODE (GApplication, g_application, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init));
+
 
 enum
 {
   PROP_0,
 
   PROP_APPLICATION_ID,
+  PROP_REGISTER,
   PROP_DEFAULT_QUIT,
-  PROP_IS_REMOTE
+  PROP_IS_REMOTE,
+  PROP_ARGV,
+  PROP_PLATFORM_DATA
 };
 
 enum
@@ -195,6 +208,10 @@ struct _GApplicationPrivate
   GHashTable *actions; /* name -> GApplicationAction */
   GMainLoop *mainloop;
 
+  GVariant *argv;
+  GVariant *platform_data;
+
+  guint do_register  : 1;
   guint default_quit : 1;
   guint is_remote    : 1;
 
@@ -209,18 +226,31 @@ struct _GApplicationPrivate
 static GApplication *primary_application = NULL;
 static GHashTable *instances_for_appid = NULL;
 
-static void     _g_application_platform_init                    (GApplication  *app); 
-static gboolean _g_application_platform_acquire_single_instance (GApplication  *app,
-                                                                 GError       **error);
+static gboolean initable_init (GInitable     *initable,
+			       GCancellable  *cancellable,
+			       GError       **error);
+
+static gboolean _g_application_platform_init                    (GApplication  *app,
+								 GCancellable  *cancellable,
+								 GError       **error); 
+static gboolean _g_application_platform_register                (GApplication  *app,
+								 gboolean      *unique,
+								 GCancellable  *cancellable,
+								 GError       **error); 
+
 static void     _g_application_platform_remote_invoke_action    (GApplication  *app,
                                                                  const gchar   *action,
                                                                  GVariant      *platform_data);
 static void     _g_application_platform_remote_quit             (GApplication  *app,
                                                                  GVariant      *platform_data);
-static void     _g_application_platform_activate                (GApplication  *app,
-                                                                 GVariant      *data) G_GNUC_NORETURN;
 static void     _g_application_platform_on_actions_changed      (GApplication  *app);
 
+static void
+initable_iface_init (GInitableIface *initable_iface)
+{
+  initable_iface->init = initable_init;
+}
+
 #ifdef G_OS_UNIX
 #include "gdbusapplication.c"
 #else
@@ -288,45 +318,25 @@ g_application_default_run (GApplication *application)
   g_main_loop_run (application->priv->mainloop);
 }
 
-static void
-_g_application_handle_activation (GApplication  *app,
-                                  int            argc,
-                                  char         **argv,
-                                  GVariant      *platform_data)
+static GVariant *
+variant_from_argv (int    argc,
+		   char **argv)
 {
   GVariantBuilder builder;
-  GVariant *message;
   int i;
 
-  g_variant_builder_init (&builder, G_VARIANT_TYPE ("(aaya{sv})"));
-  g_variant_builder_open (&builder, G_VARIANT_TYPE ("aay"));
+  g_variant_builder_init (&builder, G_VARIANT_TYPE ("aay"));
 
   for (i = 1; i < argc; i++)
     {
-      int j;
       guint8 *argv_bytes;
 
-      g_variant_builder_open (&builder, G_VARIANT_TYPE ("ay"));
-
       argv_bytes = (guint8*) argv[i];
-      for (j = 0; argv_bytes[j]; j++)
-        g_variant_builder_add_value (&builder,
-                                     g_variant_new_byte (argv_bytes[j]));
-      g_variant_builder_close (&builder);
-    }
-  g_variant_builder_close (&builder);
-
-  if (platform_data)
-    g_variant_builder_add (&builder, "@a{sv}", platform_data);
-  else
-    {
-      g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{sv}"));
-      g_variant_builder_close (&builder);
+      g_variant_builder_add_value (&builder,
+				   g_variant_new_byte_array (argv_bytes, -1));
     }
-
-  message = g_variant_builder_end (&builder);
-  _g_application_platform_activate (app, message);
-  g_variant_unref (message);
+  
+  return g_variant_builder_end (&builder);
 }
 
 static gboolean
@@ -350,6 +360,24 @@ queue_actions_change_notification (GApplication *application)
     priv->actions_changed_id = g_timeout_add (0, timeout_handle_actions_changed, application);
 }
 
+static gboolean
+initable_init (GInitable     *initable,
+               GCancellable  *cancellable,
+               GError       **error)
+{
+  GApplication *app = G_APPLICATION (initable);
+  gboolean unique;
+
+  if (!_g_application_platform_init (app, cancellable, error))
+    return FALSE;
+
+  if (app->priv->do_register &&
+      !_g_application_platform_register (app, &unique, cancellable ,error))
+    return FALSE;
+
+  return TRUE;
+}
+
 static void
 g_application_action_free (gpointer data)
 {
@@ -364,15 +392,35 @@ g_application_action_free (gpointer data)
     }
 }
 
-
 /**
  * g_application_new:
  * @appid: System-dependent application identifier
+ * @argc: Number of arguments in @argv
+ * @argv: (allow-none) (array length=argc): Argument vector, usually from the <parameter>argv</parameter> parameter of main() 
+ *
+ * Create a new #GApplication.  This uses a platform-specific
+ * mechanism to ensure the current process is the unique owner of the
+ * application (as defined by the @appid). If successful, the
+ * #GApplication:is-remote property will be %FALSE, and it is safe to
+ * continue creating other resources such as graphics windows.
  *
- * Create a new #GApplication.  The application is initially in
- * "remote" mode.  Almost certainly, you want to call
- * g_application_register() immediately after this function, which
- * will finish initialization.
+ * If the given @appid is already running in another process, the the
+ * GApplication::activate_with_data signal will be emitted in the
+ * remote process, with the data from @argv and other
+ * platform-specific data available.  Subsequently the
+ * #GApplication:default-exit property will be evaluated.  If it's
+ * %TRUE, then the current process will terminate.  If %FALSE, then
+ * the application remains in the #GApplication:is-remote state, and
+ * you can e.g. call g_application_invoke_action().
+ *
+ * This function may do synchronous I/O to obtain unique ownership
+ * of the application id, and will block the calling thread in this
+ * case.
+ *
+ * If the environment does not support the basic functionality of
+ * #GApplication, this function will invoke g_error(), which by
+ * default is a fatal operation.  This may arise for example on
+ * UNIX systems using D-Bus when the session bus is not available.
  *
  * As a convenience, this function is defined to call g_type_init() as
  * its very first action.
@@ -382,79 +430,133 @@ g_application_action_free (gpointer data)
  * Since: 2.26
  */
 GApplication *
-g_application_new (const gchar *appid)
+g_application_new (const gchar *appid,
+		   int          argc,
+		   char       **argv)
 {
+  GObject *app;
+  GError *error = NULL;
+  GVariant *argv_variant;
+
   g_type_init ();
 
-  return G_APPLICATION (g_object_new (G_TYPE_APPLICATION, "application-id", appid, NULL));
+  g_return_val_if_fail (appid != NULL, NULL);
+  
+  argv_variant = variant_from_argv (argc, argv);
+  
+  app = g_initable_new (G_TYPE_APPLICATION, 
+			NULL,
+			&error,
+			"application-id", appid, 
+			"argv", argv_variant, 
+			NULL);
+  if (!app)
+    {
+      g_error ("%s", error->message);
+      g_clear_error (&error);
+      return NULL;
+    }
+  return G_APPLICATION (app);
 }
 
 /**
- * g_application_register_with_data:
- * @application: A #GApplication
- * @argc: System argument count
- * @argv: (array length=argc): System argument vector
- * @platform_data: (allow-none): Arbitrary platform-specific data, must have signature "a{sv}"
- *
- * Ensure the current process is the unique owner of the application.
- * If successful, the #GApplication:is-remote property will be changed
- * to %FALSE, and it is safe to continue creating other resources
- * such as graphics windows.
- *
- * If the given @appid is already running in another process, the
- * #GApplication:default-exit property will be evaluated.  If it's
- * %TRUE, then a platform-specific action such as bringing any
- * graphics windows associated with the application to the foreground
- * may be initiated.  After that, the current process will terminate.
- * If %FALSE, then the application remains in the #GApplication:is-remote
- * state, and you can e.g. call g_application_invoke_action().
+ * g_application_try_new:
+ * @appid: System-dependent application identifier
+ * @argc: Number of arguments in @argv
+ * @argv: (allow-none) (array length=argc): Argument vector, usually from the <parameter>argv</parameter> parameter of main() 
+ * @error: a #GError
  *
- * This function may do synchronous I/O to obtain unique ownership
- * of the application id, and will block the calling thread in this
- * case.
+ * This function is similar to g_application_new(), but allows for
+ * more graceful fallback if the environment doesn't support the
+ * basic #GApplication functionality.
+ *
+ * Returns: (transfer full): An application instance
+ *
+ * Since: 2.26
  */
-void
-g_application_register_with_data (GApplication  *application,
-                                  gint           argc,
-                                  gchar        **argv,
-                                  GVariant      *platform_data)
+GApplication *
+g_application_try_new (const gchar *appid,
+		       int          argc,
+		       char       **argv,
+		       GError     **error)
 {
-  g_return_if_fail (application->priv->appid != NULL);
-  g_return_if_fail (application->priv->is_remote);
-  g_return_if_fail (platform_data == NULL
-                    || g_variant_is_of_type (platform_data, G_VARIANT_TYPE ("a{sv}")));
-
-  if (!_g_application_platform_acquire_single_instance (application, NULL))
-    {
-      if (application->priv->default_quit)
-        _g_application_handle_activation (application, argc, argv, platform_data);
-      else
-        return;
-    }
+  GVariant *argv_variant;
 
-  application->priv->is_remote = FALSE;
+  g_type_init ();
 
-  _g_application_platform_init (application);
+  g_return_val_if_fail (appid != NULL, NULL);
+  
+  argv_variant = variant_from_argv (argc, argv);
+  
+  return G_APPLICATION (g_initable_new (G_TYPE_APPLICATION, 
+					NULL,
+					error,
+					"application-id", appid, 
+					"argv", argv_variant, 
+					NULL));
 }
 
 /**
- * g_application_new_and_register:
- * @appid: An application identifier
- * @argc: System argument count
- * @argv: (array length=argc): System argument vector
- *
- * This is a convenience function which combines g_application_new()
- * with g_application_register_with_data(). Therefore, it may block
- * the calling thread just like g_application_register_with_data().
+ * g_application_unregistered_try_new:
+ * @appid: System-dependent application identifier
+ * @argc: Number of arguments in @argv
+ * @argv: (allow-none) (array length=argc): Argument vector, usually from the <parameter>argv</parameter> parameter of main() 
+ * @error: a #GError
+ *
+ * This function is similar to g_application_try_new(), but also
+ * sets the GApplication:register property to %FALSE.  You can later
+ * call g_application_register() to complete initialization.
+ *
+ * Returns: (transfer full): An application instance
+ *
+ * Since: 2.26
  */
 GApplication *
-g_application_new_and_register (const gchar  *appid,
-                                gint          argc,
-                                gchar       **argv)
+g_application_unregistered_try_new (const gchar *appid,
+				    int          argc,
+				    char       **argv,
+				    GError     **error)
+{
+  GVariant *argv_variant;
+
+  g_type_init ();
+
+  g_return_val_if_fail (appid != NULL, NULL);
+  
+  argv_variant = variant_from_argv (argc, argv);
+  
+  return G_APPLICATION (g_initable_new (G_TYPE_APPLICATION, 
+					NULL,
+					error,
+					"application-id", appid, 
+					"argv", argv_variant, 
+					"register", FALSE,
+					NULL));
+}
+
+/**
+ * g_application_register:
+ * @app: a #GApplication
+ * 
+ * By default, #GApplication ensures process uniqueness when
+ * initialized, but this behavior is controlled by the
+ * GApplication:register property.  If it was given as %FALSE at
+ * construction time, this function allows you to later attempt
+ * to ensure uniqueness.
+ *
+ * Returns: %TRUE if registration was successful
+ */
+gboolean
+g_application_register (GApplication   *app)
 {
-  GApplication *app = g_application_new (appid);
-  g_application_register_with_data (app, argc, argv, NULL);
-  return app;
+  gboolean unique;
+
+  g_return_val_if_fail (G_IS_APPLICATION (app), FALSE);
+  g_return_val_if_fail (app->priv->is_remote, FALSE);
+  
+  if (!_g_application_platform_register (app, &unique, NULL, NULL))
+    return FALSE;
+  return unique;
 }
 
 /**
@@ -563,25 +665,33 @@ g_application_invoke_action (GApplication *application,
   g_return_if_fail (G_IS_APPLICATION (application));
   g_return_if_fail (name != NULL);
   g_return_if_fail (platform_data == NULL
-                    || g_variant_is_of_type (platform_data, "a{sv}"));
+                    || g_variant_is_of_type (platform_data, G_VARIANT_TYPE ("a{sv}")));
+  
+  if (platform_data == NULL)
+    platform_data = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
+  else
+    g_variant_ref (platform_data);
 
   priv = application->priv;
-
+  
   if (priv->is_remote)
     {
       _g_application_platform_remote_invoke_action (application, name, platform_data);
-      return;
+      goto out;
     }
 
   action = g_hash_table_lookup (priv->actions, name);
   g_return_if_fail (action != NULL);
   if (!action->enabled)
-    return;
+    goto out;
 
   g_signal_emit (application, application_signals[ACTION_WITH_DATA],
                  g_quark_from_string (name),
                  name,
                  platform_data);
+
+ out:
+  g_variant_unref (platform_data);
 }
 
 /**
@@ -779,7 +889,12 @@ g_application_quit_with_data (GApplication *application,
 
   g_return_val_if_fail (G_IS_APPLICATION (application), FALSE);
   g_return_val_if_fail (platform_data == NULL
-			|| g_variant_is_of_type (platform_data, "a{sv}"), FALSE);
+			|| g_variant_is_of_type (platform_data, G_VARIANT_TYPE ("a{sv}")), FALSE);
+
+  if (platform_data == NULL)
+    platform_data = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
+  else
+    g_variant_ref (platform_data);
 
   if (application->priv->is_remote)
     {
@@ -789,6 +904,8 @@ g_application_quit_with_data (GApplication *application,
   else
     g_signal_emit (application, application_signals[QUIT_WITH_DATA], 0, platform_data, &retval);
 
+  g_variant_unref (platform_data);
+
   return retval;
 }
 
@@ -855,6 +972,7 @@ g_application_init (GApplication *app)
                                               NULL,
                                               g_application_action_free);
   app->priv->default_quit = TRUE;
+  app->priv->do_register = TRUE;
   app->priv->is_remote = TRUE;
 }
 
@@ -880,6 +998,18 @@ g_application_get_property (GObject    *object,
       g_value_set_boolean (value, g_application_is_remote (app));
       break;
 
+    case PROP_REGISTER:
+      g_value_set_boolean (value, app->priv->do_register);
+      break;
+
+    case PROP_ARGV:
+      g_value_set_boxed (value, app->priv->argv);
+      break;
+
+    case PROP_PLATFORM_DATA:
+      g_value_set_boxed (value, app->priv->platform_data);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -904,6 +1034,28 @@ g_application_set_property (GObject      *object,
       app->priv->default_quit = g_value_get_boolean (value);
       break;
 
+    case PROP_REGISTER:
+      app->priv->do_register = g_value_get_boolean (value);
+      break;
+
+    case PROP_ARGV:
+      {
+	GVariant *argv = g_value_get_boxed (value);
+	g_return_if_fail (argv == NULL ||
+			  g_variant_is_of_type (argv, G_VARIANT_TYPE ("aay")));
+	app->priv->argv = argv;
+      }
+      break;
+
+    case PROP_PLATFORM_DATA:
+      {
+	GVariant *platform_data = g_value_get_boxed (value);
+	g_return_if_fail (platform_data == NULL ||
+			  g_variant_is_of_type (platform_data, G_VARIANT_TYPE ("a{sv}")));
+	app->priv->platform_data = platform_data;
+      }
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -1053,7 +1205,7 @@ g_application_class_init (GApplicationClass *klass)
                   G_TYPE_VARIANT,
                   G_TYPE_VARIANT);
 
-   /**
+  /**
    * GApplication:application-id:
    *
    * The unique identifier for this application.  See the documentation for
@@ -1071,6 +1223,40 @@ g_application_class_init (GApplicationClass *klass)
                                                         G_PARAM_STATIC_STRINGS));
 
   /**
+   * GApplication:argv:
+   *
+   * The argument vector given to this application.  It must be a #GVariant
+   * with a type signature "aay".
+   *
+   */
+  g_object_class_install_property (gobject_class,
+                                   PROP_ARGV,
+                                   g_param_spec_boxed ("argv",
+						       P_("Argument vector"),
+						       P_("System argument vector with type signature aay"),
+						       G_TYPE_VARIANT,
+						       G_PARAM_READWRITE |
+						       G_PARAM_CONSTRUCT_ONLY |
+						       G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GApplication:platform-data:
+   *
+   * Platform-specific data retrieved from the operating system
+   * environment.  It must be a #GVariant with type signature "a{sv}".
+   *
+   */
+  g_object_class_install_property (gobject_class,
+                                   PROP_PLATFORM_DATA,
+                                   g_param_spec_boxed ("platform-data",
+						       P_("Platform data"),
+						       P_("Environmental data, must have type signature a{sv}"),
+						       G_TYPE_VARIANT,
+						       G_PARAM_READWRITE |
+						       G_PARAM_CONSTRUCT_ONLY |
+						       G_PARAM_STATIC_STRINGS));
+
+  /**
    * GApplication:default-quit:
    *
    * By default, if a different process is running this application, the
@@ -1103,6 +1289,23 @@ g_application_class_init (GApplicationClass *klass)
                                                          P_("Whether this application is a proxy for another process"),
                                                          TRUE,
                                                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GApplication:register:
+   *
+   * If this property is %FALSE, the application construction will not attempt
+   * to ensure process uniqueness, and the application is guaranteed to be in the
+   * remote state.  See GApplication:is-remote.
+   */
+  g_object_class_install_property (gobject_class,
+                                   PROP_REGISTER,
+                                   g_param_spec_boolean ("register",
+                                                         P_("Register"),
+                                                         P_("If false, do not "),
+                                                         TRUE,
+                                                         G_PARAM_READWRITE | 
+							 G_PARAM_CONSTRUCT_ONLY |
+							 G_PARAM_STATIC_STRINGS));
 }
 
 #define __G_APPLICATION_C__
diff --git a/gio/gapplication.h b/gio/gapplication.h
index 898c43a..206f599 100644
--- a/gio/gapplication.h
+++ b/gio/gapplication.h
@@ -102,16 +102,21 @@ struct _GApplicationClass
 };
 GType                   g_application_get_type                  (void) G_GNUC_CONST;
 
-GApplication *          g_application_new                       (const gchar              *appid);
+GApplication *          g_application_new                       (const gchar      *appid,
+								 int               argc,
+								 char            **argv);
 
-void                    g_application_register_with_data        (GApplication      *application,
-                                                                 gint               argc,
-                                                                 gchar            **argv,
-                                                                 GVariant          *platform_data);
+GApplication *          g_application_try_new                   (const gchar      *appid,
+								 int               argc,
+								 char            **argv,
+								 GError          **error);
+
+GApplication *          g_application_unregistered_try_new      (const gchar      *appid,
+								 int               argc,
+								 char            **argv,
+								 GError          **error);
 
-GApplication *          g_application_new_and_register           (const gchar      *appid,
-                                                                  gint              argc,
-                                                                  gchar           **argv);
+gboolean                g_application_register                  (GApplication      *application);
 
 GApplication *          g_application_get_instance              (void);
 G_CONST_RETURN gchar *  g_application_get_id                    (GApplication      *application);
diff --git a/gio/gdbusapplication.c b/gio/gdbusapplication.c
index e0f1fec..39f46ed 100644
--- a/gio/gdbusapplication.c
+++ b/gio/gdbusapplication.c
@@ -259,15 +259,6 @@ static GDBusInterfaceVTable application_dbus_vtable =
   NULL
 };
 
-static GVariant *
-create_empty_vardict ()
-{
-  GVariantBuilder builder;
-
-  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
-  return g_variant_builder_end (&builder);
-}
-
 static gchar *
 application_path_from_appid (const gchar *appid)
 {
@@ -284,42 +275,32 @@ application_path_from_appid (const gchar *appid)
   return appid_path;
 }
 
-static void
-ensure_bus (GApplication *app)
+static gboolean
+_g_application_platform_init (GApplication  *app,
+			      GCancellable  *cancellable,
+			      GError       **error)
 {
-  GError *error = NULL;
-
   if (app->priv->session_bus == NULL)
-    app->priv->session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
-  if (app->priv->session_bus == NULL)
-    {
-      g_error ("%s", error->message);
-      g_error_free (error);
-    }
+    app->priv->session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, cancellable, error);
+  if (!app->priv->session_bus)
+    return FALSE;
 
-  if (app->priv->dbus_path == NULL)
+  if (!app->priv->dbus_path)
     app->priv->dbus_path = application_path_from_appid (app->priv->appid);
-}
-
-static void
-_g_application_platform_init (GApplication *app)
-{
+  return TRUE;
 }
 
 static gboolean
-_g_application_platform_acquire_single_instance (GApplication  *app,
-                                                 GError       **error)
+_g_application_platform_register (GApplication  *app,
+				  gboolean      *unique,
+				  GCancellable  *cancellable,
+				  GError       **error)
 {
   GVariant *request_result;
   guint32 request_status;
   gboolean result;
   guint registration_id;
 
-  ensure_bus (app);
-
-  if (app->priv->session_bus == NULL)
-    return FALSE;
-
   registration_id = g_dbus_connection_register_object (app->priv->session_bus,
                                                        app->priv->dbus_path,
                                                        &application_dbus_interface_info,
@@ -336,7 +317,7 @@ _g_application_platform_acquire_single_instance (GApplication  *app,
                                                 "org.freedesktop.DBus",
                                                 "RequestName",
                                                 g_variant_new ("(su)", app->priv->appid, 0x4),
-                                                NULL, 0, -1, NULL, error);
+                                                NULL, 0, -1, cancellable, error);
 
   if (request_result == NULL)
     {
@@ -351,18 +332,45 @@ _g_application_platform_acquire_single_instance (GApplication  *app,
 
   g_variant_unref (request_result);
 
-  if (request_status != 1 && request_status != 4)
+  *unique = (request_status == 1 || request_status == 4);
+  result = TRUE;
+
+  if (*unique)
+    {
+      app->priv->is_remote = FALSE;
+    }
+  else if (app->priv->default_quit)
     {
-      if (request_status == 3)
-        g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Another process has name \"%s\"", app->priv->appid);
+      GVariantBuilder builder;
+      GVariant *message;
+      GVariant *result;
+
+      g_variant_builder_init (&builder, G_VARIANT_TYPE ("(aaya{sv})"));
+      g_variant_builder_add (&builder, "@aay", app->priv->argv);
+
+      if (app->priv->platform_data)
+	g_variant_builder_add (&builder, "@a{sv}", app->priv->platform_data);
       else
-        g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unknown error");
+	{
+	  g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{sv}"));
+	  g_variant_builder_close (&builder);
+	}
 
-      result = FALSE;
-      goto done;
-    }
+      message = g_variant_builder_end (&builder);
 
-  result = TRUE;
+      result = g_dbus_connection_call_sync (app->priv->session_bus,
+					    app->priv->appid,
+					    app->priv->dbus_path,
+					    G_APPLICATION_IFACE,
+					    "Activate",
+					    message,
+					    NULL, 0, -1, NULL, NULL);
+
+      if (result)
+	g_variant_unref (result);
+
+      exit (0);
+    }
 
 done:
   if (!result)
@@ -387,8 +395,6 @@ _g_application_platform_remote_invoke_action (GApplication  *app,
 {
   GVariant *result;
 
-  ensure_bus (app);
-
   result = g_dbus_connection_call_sync (app->priv->session_bus,
                                         app->priv->appid,
                                         app->priv->dbus_path,
@@ -396,7 +402,7 @@ _g_application_platform_remote_invoke_action (GApplication  *app,
                                         "InvokeAction",
                                         g_variant_new ("(s a{sv})",
                                                        action,
-                                                       platform_data || create_empty_vardict ()),
+                                                       platform_data),
                                         NULL, 0, -1, NULL, NULL);
   if (result)
     g_variant_unref (result);
@@ -408,38 +414,15 @@ _g_application_platform_remote_quit (GApplication *app,
 {
   GVariant *result;
 
-  ensure_bus (app);
-
   result = g_dbus_connection_call_sync (app->priv->session_bus,
                                         app->priv->appid,
                                         app->priv->dbus_path,
                                         G_APPLICATION_IFACE,
                                         "Quit",
                                         g_variant_new ("(@a{sv})",
-                                                       platform_data || create_empty_vardict ()),
+                                                       platform_data),
                                         NULL, 0, -1, NULL, NULL);
   if (result)
     g_variant_unref (result);
 }
 
-static void
-_g_application_platform_activate (GApplication *app,
-                                  GVariant     *data)
-{
-  GVariant *result;
-
-  ensure_bus (app);
-
-  result = g_dbus_connection_call_sync (app->priv->session_bus,
-                                        app->priv->appid,
-                                        app->priv->dbus_path,
-                                        G_APPLICATION_IFACE,
-                                        "Activate",
-                                        data,
-                                        NULL, 0, -1, NULL, NULL);
-
-  if (result)
-    g_variant_unref (result);
-
-  exit (0);
-}
diff --git a/gio/gio.symbols b/gio/gio.symbols
index 690dd81..707e0cc 100644
--- a/gio/gio.symbols
+++ b/gio/gio.symbols
@@ -30,7 +30,6 @@ g_vfs_get_local
 #if IN_FILE(__G_APPLICATION_C__)
 g_application_get_type G_GNUC_CONST
 g_application_new
-g_application_new_and_register
 g_application_get_instance
 g_application_get_id
 g_application_set_action_enabled
@@ -38,10 +37,12 @@ g_application_get_action_enabled
 g_application_get_action_description
 g_application_add_action
 g_application_remove_action
-g_application_register_with_data
 g_application_invoke_action
 g_application_list_actions
 g_application_run
+g_application_register
+g_application_try_new
+g_application_unregistered_try_new
 g_application_quit_with_data
 g_application_is_remote
 #endif
diff --git a/gio/gnullapplication.c b/gio/gnullapplication.c
index 91a6578..7c3c3e0 100644
--- a/gio/gnullapplication.c
+++ b/gio/gnullapplication.c
@@ -25,14 +25,19 @@
 
 #include "gioerror.h"
 
-static void
-_g_application_platform_init (GApplication *app)
+static gboolean
+_g_application_platform_init (GApplication *app,
+			      GCancellable *cancellable,
+			      GError      **error)
 {
+  return TRUE;
 }
 
 static gboolean
-_g_application_platform_acquire_single_instance (GApplication  *app,
-                                                 GError       **error)
+_g_application_platform_register (GApplication *app,
+				  gboolean     *unique,
+				  GCancellable *cancellable,
+				  GError      **error)
 {
   return TRUE;
 }
diff --git a/gio/tests/application.c b/gio/tests/application.c
index d2e60dc..3307b3a 100644
--- a/gio/tests/application.c
+++ b/gio/tests/application.c
@@ -149,7 +149,7 @@ test_basic (void)
 {
   GApplication *app;
 
-  app = g_application_new_and_register ("org.gtk.TestApplication", 0, NULL);
+  app = g_application_new ("org.gtk.TestApplication", 0, NULL);
   g_application_add_action (app, "About", "Print an about message");
 
   g_signal_connect (app, "action-with-data::About", G_CALLBACK (on_app_action), NULL);
diff --git a/gio/tests/testapp.c b/gio/tests/testapp.c
index 34e88d6..1985698 100644
--- a/gio/tests/testapp.c
+++ b/gio/tests/testapp.c
@@ -60,9 +60,13 @@ main (int argc, char *argv[])
   }
 #endif
 
-  app = g_application_new ("org.gtk.test.app");
+  app = g_application_unregistered_try_new ("org.gtk.test.app", 
+					    argc, argv, NULL);
   if (!(argc > 1 && strcmp (argv[1], "--non-unique") == 0))
-    g_application_register_with_data (app, argc, argv, NULL);
+    {
+      if (!g_application_register (app))
+	exit (0);
+    }
 
   if (g_application_is_remote (app))
     {



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