[glib/application: 135/135] GApplication is starting to work...
- From: Ryan Lortie <ryanl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/application: 135/135] GApplication is starting to work...
- Date: Thu, 5 Aug 2010 23:57:57 +0000 (UTC)
commit 034c5483402013b93fe52bd0de14db920638aaac
Author: Ryan Lortie <desrt desrt ca>
Date: Thu Aug 5 19:57:27 2010 -0400
GApplication is starting to work...
gio/Makefile.am | 2 +
gio/gapplication.c | 783 +++++++++++++++------------------
gio/gapplication.h | 21 +-
gio/gapplicationimpl-dbus-interface.c | 90 ++++
gio/gapplicationimpl-dbus-private.h | 29 ++
gio/gapplicationimpl-dbus.c | 310 +++++++++++++
gio/gapplicationinvocation.c | 22 +-
gio/gdbusapplication.c | 424 ------------------
gio/gioenums.h | 20 +
9 files changed, 838 insertions(+), 863 deletions(-)
---
diff --git a/gio/Makefile.am b/gio/Makefile.am
index 44f3b59..32064be 100644
--- a/gio/Makefile.am
+++ b/gio/Makefile.am
@@ -260,6 +260,8 @@ SUBDIRS += tests
libgio_2_0_la_SOURCES = \
gappinfo.c \
+ gapplicationimpl-dbus-interface.h \
+ gapplicationimpl-dbus-interface.c \
gapplicationinvocation.c\
gapplication.c \
gapplication.h \
diff --git a/gio/gapplication.c b/gio/gapplication.c
index 669c5c6..cd5ed1f 100644
--- a/gio/gapplication.c
+++ b/gio/gapplication.c
@@ -1,5 +1,6 @@
/* GIO - GLib Input, Output and Streaming Library
*
+ * Coypright © 2010 Codethink Limited
* Copyright © 2010 Red Hat, Inc
*
* This library is free software; you can redistribute it and/or
@@ -19,6 +20,7 @@
*
* Authors: Colin Walters <walters verbum org>
* Emmanuele Bassi <ebassi linux intel com>
+ * Ryan Lortie <desrt desrt ca>
*/
#include "config.h"
@@ -38,7 +40,8 @@
#include "gdbusconnection.h"
#include "gdbusintrospection.h"
#include "gdbusmethodinvocation.h"
-
+#include "gioenumtypes.h"
+#include "gapplicationinvocation.h"
/**
* SECTION: gapplication
@@ -167,92 +170,86 @@
* </refsect2>
*/
-static void initable_iface_init (GInitableIface *initable_iface);
+G_DEFINE_TYPE (GApplication, g_application, G_TYPE_OBJECT)
+
+typedef struct _GApplicationImpl GApplicationImpl;
+
+static void g_application_impl_init (GApplicationImpl *impl,
+ gpointer app);
+
+static void g_application_impl_set_id (GApplicationImpl *impl,
+ const gchar *appid);
+
+static gboolean g_application_impl_register (GApplicationImpl *impl,
+ gboolean *is_remote,
+ GCancellable *cancellable,
+ GError **error);
+
+static void g_application_impl_activate (GApplicationImpl *impl,
+ GVariant *platform_data);
+
+static void g_application_impl_open (GApplicationImpl *impl,
+ GFile **files,
+ gint n_files,
+ const gchar *hint,
+ GVariant *platform_data);
+
+static void g_application_impl_action (GApplicationImpl *impl,
+ const gchar *action_name,
+ GVariant *parameters,
+ GVariant *platform_data);
+
+static int g_application_impl_cmdline (GApplicationImpl *impl,
+ GVariant *arguments,
+ GVariant *platform_data);
-G_DEFINE_TYPE_WITH_CODE (GApplication, g_application, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init));
+static void g_application_impl_flush (GApplicationImpl *impl);
+#ifdef G_OS_UNIX
+#include "gapplicationimpl-dbus.c"
+#else
+#include "gnullapplication.c"
+#endif
enum
{
PROP_0,
PROP_APPLICATION_ID,
+ PROP_FLAGS,
PROP_IS_REMOTE
};
-enum
-{
- QUIT_WITH_DATA,
- ACTION_WITH_DATA,
- PREPARE_ACTIVATION,
-
- LAST_SIGNAL
-};
-
-static guint application_signals[LAST_SIGNAL] = { 0 };
-
typedef struct {
gchar *name;
gchar *description;
- guint enabled : 1;
+
+ GVariantType *type;
+ gboolean enabled;
} GApplicationAction;
struct _GApplicationPrivate
{
gchar *appid;
+
GHashTable *actions; /* name -> GApplicationAction */
GMainLoop *mainloop;
- GVariant *argv;
- GVariant *platform_data;
+ guint is_remote : 1;
+ guint registered : 1;
- guint do_register : 1;
- guint default_quit : 1;
- guint is_remote : 1;
- guint registration_tried : 1;
+ GApplicationFlags flags;
+ guint use_count;
+ guint inactivity_timeout;
guint actions_changed_id;
-#ifdef G_OS_UNIX
- gchar *dbus_path;
- GDBusConnection *session_bus;
-#endif
+
+ GApplicationImpl impl;
};
static GApplication *primary_application = NULL;
static GHashTable *instances_for_appid = NULL;
-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_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
-#include "gnullapplication.c"
-#endif
-
static gboolean
_g_application_validate_id (const char *id)
{
@@ -295,58 +292,27 @@ application_for_appid (const char *appid)
return g_hash_table_lookup (instances_for_appid, appid);
}
-static gboolean
-g_application_default_quit_with_data (GApplication *application,
- GVariant *platform_data)
-{
- g_return_val_if_fail (application->priv->mainloop != NULL, FALSE);
- g_main_loop_quit (application->priv->mainloop);
-
- return TRUE;
-}
-
-static gint
-g_application_default_run (GApplication *application,
- GVariant *arguments,
- GVariant *platform_data)
-{
- if (application->priv->mainloop == NULL)
- application->priv->mainloop = g_main_loop_new (NULL, TRUE);
-
- g_main_loop_run (application->priv->mainloop);
-
- return 0;
-}
-
static GVariant *
-append_cwd_to_platform_data (GVariant *platform_data)
+g_application_get_platform_data (GApplication *application)
{
- GVariantBuilder builder;
- gchar *cwd;
+ GVariantBuilder *builder;
GVariant *result;
- cwd = g_get_current_dir ();
+ builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
- g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
- if (cwd)
- g_variant_builder_add (&builder, "{sv}",
- "cwd",
- g_variant_new_bytestring (cwd));
- g_free (cwd);
+ {
+ gchar *cwd = g_get_current_dir ();
+ g_variant_builder_add (builder, "{sv}", "cwd",
+ g_variant_new_bytestring (cwd));
+ g_free (cwd);
+ }
+
+ G_APPLICATION_GET_CLASS (application)->
+ add_platform_data (application, builder);
+
+ result = g_variant_builder_end (builder);
+ g_variant_builder_unref (builder);
- if (platform_data)
- {
- GVariantIter iter;
- GVariant *item;
-
- g_variant_iter_init (&iter, platform_data);
- while (g_variant_iter_next (&iter, "@{sv}", &item))
- {
- g_variant_builder_add_value (&builder, item);
- g_variant_unref (item);
- }
- }
- result = g_variant_builder_end (&builder);
return result;
}
@@ -357,8 +323,6 @@ timeout_handle_actions_changed (gpointer user_data)
application->priv->actions_changed_id = 0;
- _g_application_platform_on_actions_changed (application);
-
return FALSE;
}
@@ -371,24 +335,6 @@ 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)
{
@@ -442,12 +388,14 @@ g_application_action_free (gpointer data)
* Since: 2.26
*/
GApplication *
-g_application_new (const gchar *appid)
+g_application_new (const gchar *appid,
+ GApplicationFlags flags)
{
g_type_init ();
return g_object_new (G_TYPE_APPLICATION,
"application-id", appid,
+ "flags", flags,
NULL);
}
@@ -498,17 +446,25 @@ g_application_try_new (const gchar *appid)
* Returns: %TRUE if registration was successful
*/
gboolean
-g_application_register (GApplication *application)
+g_application_register (GApplication *application,
+ GCancellable *cancellable,
+ GError **error)
{
- gboolean unique;
+ gboolean is_remote;
g_return_val_if_fail (G_IS_APPLICATION (application), FALSE);
- g_return_val_if_fail (application->priv->is_remote, FALSE);
- g_return_val_if_fail (!application->priv->registration_tried, FALSE);
- if (!_g_application_platform_register (application, &unique, NULL, NULL))
+ if (application->priv->registered)
+ return TRUE;
+
+ if (!g_application_impl_register (&application->priv->impl,
+ &is_remote, cancellable, error))
return FALSE;
- return unique;
+
+ application->priv->is_remote = is_remote;
+ application->priv->registered = TRUE;
+
+ return TRUE;
}
/**
@@ -586,67 +542,6 @@ g_application_remove_action (GApplication *application,
}
/**
- * g_application_invoke_action:
- * @application: a #GApplication
- * @name: the name of the action to invoke
- * @platform_data: (allow-none): platform-specific event data
- *
- * Invokes the action @name of the passed #GApplication.
- *
- * This function has different behavior depending on whether @application
- * is acting as a proxy for another process. In the normal case where
- * the current process is hosting the application, and the specified
- * action exists and is enabled, the #GApplication::action signal will
- * be emitted.
- *
- * If @application is a proxy, then the specified action will be invoked
- * in the remote process. It is not necessary to call
- * g_application_add_action() in the current process in order to invoke
- * one remotely.
- *
- * Since: 2.26
- */
-void
-g_application_invoke_action (GApplication *application,
- const gchar *name,
- GVariant *platform_data)
-{
- GApplicationPrivate *priv;
- GApplicationAction *action;
-
- 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, 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);
- goto out;
- }
-
- action = g_hash_table_lookup (priv->actions, name);
- g_return_if_fail (action != NULL);
- if (!action->enabled)
- 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);
-}
-
-/**
* g_application_list_actions:
* @application: a #GApplication
*
@@ -747,7 +642,7 @@ g_application_get_action_description (GApplication *application,
const gchar *name)
{
GApplicationAction *action;
-
+
g_return_val_if_fail (G_IS_APPLICATION (application), NULL);
g_return_val_if_fail (name != NULL, NULL);
g_return_val_if_fail (!application->priv->is_remote, NULL);
@@ -758,7 +653,6 @@ g_application_get_action_description (GApplication *application,
return action->description;
}
-
/**
* g_application_get_action_enabled:
* @application: a #GApplication
@@ -792,81 +686,6 @@ g_application_get_action_enabled (GApplication *application,
}
/**
- * g_application_run:
- * @application: a #GApplication
- *
- * Starts the application.
- *
- * The default implementation of this virtual function will simply run
- * a main loop.
- *
- * It is an error to call this function if @application is a proxy for
- * a remote application.
- *
- * Since: 2.26
- */
-int
-g_application_run (GApplication *application,
- int argc,
- char **argv)
-{
- GVariant *arguments;
-
- g_return_val_if_fail (G_IS_APPLICATION (application), 1);
-
- arguments = g_variant_new_bytestring_array ((const gchar **) argv, argc);
-
- return G_APPLICATION_GET_CLASS (application)->run (application, arguments);
-}
-
-/**
- * g_application_quit_with_data:
- * @application: a #GApplication
- * @platform_data: (allow-none): platform-specific data
- *
- * Request that the application quits.
- *
- * This function has different behavior depending on whether @application
- * is acting as a proxy for another process. In the normal case where
- * the current process is hosting the application, the default
- * implementation will quit the main loop created by g_application_run().
- *
- * If @application is a proxy, then the remote process will be asked
- * to quit.
- *
- * Returns: %TRUE if the application accepted the request, %FALSE otherwise
- *
- * Since: 2.26
- */
-gboolean
-g_application_quit_with_data (GApplication *application,
- GVariant *platform_data)
-{
- gboolean retval = FALSE;
-
- 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, 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)
- {
- _g_application_platform_remote_quit (application, platform_data);
- retval = TRUE;
- }
- else
- g_signal_emit (application, application_signals[QUIT_WITH_DATA], 0, platform_data, &retval);
-
- g_variant_unref (platform_data);
-
- return retval;
-}
-
-/**
* g_application_get_instance:
*
* In the normal case where there is exactly one #GApplication instance
@@ -930,10 +749,15 @@ g_application_init (GApplication *app)
app->priv->actions = g_hash_table_new_full (g_str_hash, g_str_equal,
NULL,
g_application_action_free);
- app->priv->default_quit = TRUE;
- app->priv->do_register = TRUE;
- app->priv->is_remote = TRUE;
- app->priv->platform_data = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
+ g_application_impl_init (&app->priv->impl, app);
+}
+
+GApplicationFlags
+g_application_get_flags (GApplication *application)
+{
+ g_return_val_if_fail (G_IS_APPLICATION (application), 0);
+
+ return application->priv->flags;
}
static void
@@ -950,6 +774,9 @@ g_application_get_property (GObject *object,
g_value_set_string (value, g_application_get_id (app));
break;
+ case PROP_FLAGS:
+ g_value_set_flags (value, g_application_get_flags (app));
+
case PROP_IS_REMOTE:
g_value_set_boolean (value, g_application_is_remote (app));
break;
@@ -972,6 +799,11 @@ g_application_set_property (GObject *object,
case PROP_APPLICATION_ID:
g_return_if_fail (_g_application_validate_id (g_value_get_string (value)));
app->priv->appid = g_value_dup_string (value);
+ g_application_impl_set_id (&app->priv->impl, app->priv->appid);
+ break;
+
+ case PROP_FLAGS:
+ app->priv->flags = g_value_get_flags (value);
break;
default:
@@ -979,46 +811,13 @@ g_application_set_property (GObject *object,
}
}
-static GObject*
-g_application_constructor (GType type,
- guint n_construct_properties,
- GObjectConstructParam *construct_params)
-{
- GApplication *app;
- GObject *object;
- const char *appid = NULL;
- guint i;
-
- for (i = 0; i < n_construct_properties; i++)
- {
- GObjectConstructParam *param = &construct_params[i];
- if (strcmp (param->pspec->name, "application-id") == 0)
- appid = g_value_get_string (param->value);
- }
-
- g_return_val_if_fail (appid != NULL, NULL);
-
- app = application_for_appid (appid);
- if (app != NULL)
- return g_object_ref (app);
-
- object = (* G_OBJECT_CLASS (g_application_parent_class)->constructor) (type,
- n_construct_properties,
- construct_params);
- app = G_APPLICATION (object);
-
- if (primary_application == NULL)
- primary_application = app;
- g_hash_table_insert (instances_for_appid, g_strdup (appid), app);
-
- return object;
-}
-
static void
g_application_finalize (GObject *object)
{
GApplication *app = G_APPLICATION (object);
+ g_application_impl_destroy (&app->priv->impl);
+
g_free (app->priv->appid);
if (app->priv->actions)
g_hash_table_unref (app->priv->actions);
@@ -1027,13 +826,90 @@ g_application_finalize (GObject *object)
if (app->priv->mainloop)
g_main_loop_unref (app->priv->mainloop);
-#ifdef G_OS_UNIX
- g_free (app->priv->dbus_path);
- if (app->priv->session_bus)
- g_object_unref (app->priv->session_bus);
-#endif
+ G_OBJECT_CLASS (g_application_parent_class)
+ ->finalize (object);
+}
+
+static gboolean
+g_application_process_cmdline (GApplication *application,
+ GVariant **arguments,
+ int *exit_status)
+{
+ return FALSE;
+}
+
+static void
+g_application_add_platform_data (GApplication *application,
+ GVariantBuilder *builder)
+{
+}
+
+static GApplicationInvocation *
+g_application_create_invocation (GApplication *application,
+ GVariant *arguments,
+ GVariant *platform_data)
+{
+ return g_object_new (G_TYPE_APPLICATION_INVOCATION,
+ "arguments", arguments,
+ "platform-data", platform_data,
+ NULL);
+}
- G_OBJECT_CLASS (g_application_parent_class)->finalize (object);
+static int
+g_application_emit_cmdline (GApplication *application,
+ GApplicationInvocation *invocation)
+{
+ return G_APPLICATION_GET_CLASS (application)
+ ->cmdline (application, invocation);
+}
+
+int
+g_application_real_cmdline (GApplication *application,
+ GApplicationInvocation *invocation)
+{
+ g_warning ("G_APPLICATION_FLAGS_REMOTE_CMDLINE specified but the "
+ "cmdline() virtual function has not been implemented");
+
+ return 1;
+}
+
+static void
+g_application_real_run_mainloop (GApplication *application)
+{
+ if (application->priv->mainloop == NULL)
+ application->priv->mainloop = g_main_loop_new (NULL, TRUE);
+
+ g_main_loop_run (application->priv->mainloop);
+}
+
+static void
+g_application_real_quit_mainloop (GApplication *application)
+{
+ g_main_loop_quit (application->priv->mainloop);
+}
+
+void
+g_application_startup (GApplication *application)
+{
+}
+
+static void
+g_application_emit_activate (GApplication *application,
+ GVariant *platform_data)
+{
+ G_APPLICATION_GET_CLASS (application)
+ ->activate (application);
+}
+
+static void
+g_application_emit_open (GApplication *application,
+ GFile **files,
+ gint n_files,
+ const gchar *hint,
+ GVariant *platform_data)
+{
+ G_APPLICATION_GET_CLASS (application)
+ ->open (application, files, n_files, hint);
}
static void
@@ -1041,87 +917,26 @@ g_application_class_init (GApplicationClass *klass)
{
GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
+ klass->process_cmdline = g_application_process_cmdline;
+ klass->add_platform_data = g_application_add_platform_data;
+ klass->create_invocation = g_application_create_invocation;
+ klass->emit_cmdline = g_application_emit_cmdline;
+ klass->cmdline = g_application_real_cmdline;
+ klass->run_mainloop = g_application_real_run_mainloop;
+ klass->quit_mainloop = g_application_real_quit_mainloop;
+ klass->startup = g_application_startup;
+ klass->emit_activate = g_application_emit_activate;
+ klass->emit_open = g_application_emit_open;
+
g_type_class_add_private (klass, sizeof (GApplicationPrivate));
- gobject_class->constructor = g_application_constructor;
gobject_class->set_property = g_application_set_property;
gobject_class->get_property = g_application_get_property;
gobject_class->finalize = g_application_finalize;
- klass->run = g_application_default_run;
- klass->quit_with_data = g_application_default_quit_with_data;
-
- /**
- * GApplication::quit-with-data:
- * @application: the object on which the signal is emitted
- * @platform_data: Platform-specific data, or %NULL
- *
- * This signal is emitted when the Quit action is invoked on the
- * application.
- *
- * The default handler for this signal exits the mainloop of the
- * application.
- *
- * Returns: %TRUE if the signal has been handled, %FALSE to continue
- * signal emission
- */
- application_signals[QUIT_WITH_DATA] =
- g_signal_new (g_intern_static_string ("quit-with-data"),
- G_OBJECT_CLASS_TYPE (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GApplicationClass, quit_with_data),
- g_signal_accumulator_true_handled, NULL,
- _gio_marshal_BOOLEAN__VARIANT,
- G_TYPE_BOOLEAN, 1,
- G_TYPE_VARIANT);
-
- /**
- * GApplication::action-with-data:
- * @application: the object on which the signal is emitted
- * @name: The name of the activated action
- * @platform_data: Platform-specific data, or %NULL
- *
- * This signal is emitted when an action is activated. The action name
- * is passed as the first argument, but also as signal detail, so it
- * is possible to connect to this signal for individual actions.
- *
- * The signal is never emitted for disabled actions.
- */
- application_signals[ACTION_WITH_DATA] =
- g_signal_new (g_intern_static_string ("action-with-data"),
- G_OBJECT_CLASS_TYPE (klass),
- G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED,
- G_STRUCT_OFFSET (GApplicationClass, action_with_data),
- NULL, NULL,
- _gio_marshal_VOID__STRING_VARIANT,
- G_TYPE_NONE, 2,
- G_TYPE_STRING,
- G_TYPE_VARIANT);
-
- /**
- * GApplication::prepare-activation:
- * @application: the object on which the signal is emitted
- * @arguments: A #GVariant with the signature "aay"
- * @platform_data: A #GVariant with the signature "a{sv}", or %NULL
- *
- * This signal is emitted when a non-primary process for a given
- * application is invoked while your application is running; for
- * example, when a file browser launches your program to open a
- * file. The raw operating system arguments are passed in the
- * @arguments variant. Additional platform-dependent data is
- * stored in @platform_data.
- */
- application_signals[PREPARE_ACTIVATION] =
- g_signal_new (g_intern_static_string ("prepare-activation"),
- G_OBJECT_CLASS_TYPE (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GApplicationClass, prepare_activation),
- NULL, NULL,
- _gio_marshal_VOID__VARIANT_VARIANT,
- G_TYPE_NONE, 2,
- G_TYPE_VARIANT,
- G_TYPE_VARIANT);
+ //klass->run = g_application_default_run;
+ //klass->quit_with_data = g_application_default_quit_with_data;
/**
* GApplication:application-id:
@@ -1154,6 +969,22 @@ 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:flags:
+ *
+ * The flags that define the behaviour of this application.
+ **/
+ g_object_class_install_property (gobject_class,
+ PROP_FLAGS,
+ g_param_spec_flags ("flags",
+ P_("Application Flags"),
+ P_("Application Flags"),
+ G_TYPE_APPLICATION_FLAGS,
+ G_APPLICATION_FLAGS_NONE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
}
@@ -1169,7 +1000,7 @@ g_application_class_init (GApplicationClass *klass)
*
* If this process is the first instance of the application that was
* invoked then the 'open' signal is emitted.
- *
+ */
/**
* g_application_invoke_variant:
@@ -1182,49 +1013,103 @@ g_application_class_init (GApplicationClass *klass)
* This is a bindings-friendly version of g_application_invoke().
**/
int
-g_application_invoke_variant (GApplication *application,
- GVariant *arguments)
+g_application_cmdline_with_arguments (GApplication *application,
+ GVariant *arguments)
{
GApplicationClass *class = G_APPLICATION_GET_CLASS (application);
+ GError *error = NULL;
int exit_status;
g_variant_ref_sink (arguments);
- if (class->preprocess_args (application, &arguments, &exit_status))
+ if (class->process_cmdline (application, &arguments, &exit_status))
{
g_variant_unref (arguments);
return exit_status;
}
- g_application_register (application);
+ if (!g_application_register (application, NULL, &error))
+ {
+ g_critical ("%s", error->message);
+ g_variant_unref (arguments);
+ g_error_free (error);
- if (g_application_is_remote (application))
+ return 1;
+ }
+
+ if (application->priv->flags & G_APPLICATION_FLAGS_REMOTE_CMDLINE)
{
- GVariantBuilder *builder;
- GVariant *platform_data;
+ if (g_application_is_remote (application))
+ {
+ GVariant *platform_data;
+
+ platform_data = g_application_get_platform_data (application);
+ exit_status = g_application_impl_cmdline (&application->priv->impl,
+ arguments, platform_data);
+ }
+ else
+ {
+ GApplicationInvocation *invocation;
+
+ invocation = G_APPLICATION_GET_CLASS (application)
+ ->create_invocation (application, arguments, NULL);
- builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
- class->add_platform_data (application, builder);
- platform_data = g_variant_builder_end (builder);
- g_variant_builder_free (builder);
+ exit_status = class->emit_cmdline (application, invocation);
- status = remote_impl_run (arguments, platform_data);
+ g_object_unref (invocation);
+
+ if (exit_status == 0)
+ class->run_mainloop (application);
+ }
}
- else
+
+ else /* not G_APPLICATION_FLAGS_REMOTE_CMDLINE */
{
- GApplicationInvocation *invocation;
+ gint n;
+
+ n = g_variant_n_children (arguments);
- invocation = class->create_invocation (application, arguments, NULL);
- class->prepare_invocation (application, invocation);
- exit_status = class->invoked (application, invocation);
- g_object_unref (invocation);
+ if (n < 2)
+ g_application_activate (application);
- if (exit_status == 0)
- class->run_mainloop (application);
+ else
+ {
+ if (application->priv->flags & G_APPLICATION_FLAGS_CAN_OPEN)
+ {
+ GFile **files;
+ gint i;
+
+ files = g_new (GFile *, (n - 1) + 1);
+ for (i = 0; i < n - 1; i++)
+ {
+ const gchar *arg;
+
+ g_variant_get_child (arguments, i + 1, "^&ay", &arg);
+ files[i] = g_file_new_for_commandline_arg (arg);
+ }
+ files[i] = NULL;
+
+ g_application_open (application, files, n - 1, "");
+ }
+
+ else
+ {
+ g_critical ("This application does not open files.");
+ exit_status = 1;
+ }
+ }
}
g_variant_unref (arguments);
+ if (application->priv->use_count)
+ {
+ G_APPLICATION_GET_CLASS (application)->run_mainloop (application);
+ exit_status = 0;
+ }
+
+ g_application_impl_flush (&application->priv->impl);
+
return exit_status;
}
@@ -1266,13 +1151,13 @@ g_application_invoke_variant (GApplication *application,
* status of the process calling it.
**/
int
-g_application_invoke (GApplication *application,
- int argc, char **argv)
+g_application_cmdline (GApplication *application,
+ int argc, char **argv)
{
GVariant *args;
- args = g_variant_bytestring_array_new ((const gchar **) argv, argc);
- return g_application_invoke_with_arguments (args);
+ args = g_variant_new_bytestring_array ((const gchar **) argv, argc);
+ return g_application_cmdline_with_arguments (application, args);
}
/**
@@ -1293,12 +1178,26 @@ g_application_hold (GApplication *application)
if (application->priv->inactivity_timeout)
{
g_source_remove (application->priv->inactivity_timeout);
- application->priv->inactivity_timeout;
+ application->priv->inactivity_timeout = 0;
}
application->priv->use_count++;
}
+void
+g_application_quit_mainloop (GApplication *app)
+{
+ G_APPLICATION_GET_CLASS (app)
+ ->quit_mainloop (app);
+}
+
+void
+g_application_run_mainloop (GApplication *app)
+{
+ G_APPLICATION_GET_CLASS (app)
+ ->run_mainloop (app);
+}
+
/**
* g_application_release:
* @application: a #GApplication
@@ -1316,7 +1215,7 @@ g_application_release (GApplication *application)
application->priv->use_count--;
if (application->priv->use_count == 0)
- g_application_quit (application);
+ g_application_quit_mainloop (application);
}
static gboolean
@@ -1326,11 +1225,27 @@ g_application_inactivity_timeout (gpointer data)
g_message ("exiting application due to inactivity");
application->priv->inactivity_timeout = 0;
- g_application_quit (application);
+ g_application_quit_mainloop (application);
return FALSE;
}
+void
+g_application_activate (GApplication *application)
+{
+ g_print ("act\n");
+ if (g_application_is_remote (application))
+ {
+ GVariant *platform_data;
+
+ platform_data = g_application_get_platform_data (application);
+ g_application_impl_activate (&application->priv->impl, platform_data);
+ }
+ else
+ G_APPLICATION_GET_CLASS (application)
+ ->activate (application);
+}
+
/**
* g_application_run_service:
* @application: a #GApplication
@@ -1364,17 +1279,43 @@ g_application_inactivity_timeout (gpointer data)
int
g_application_run_service (GApplication *application)
{
+ GError *error = NULL;
+
g_return_val_if_fail (G_IS_APPLICATION (application), 1);
- g_return_val_if_fail (application->priv->disposition ==
- G_APPLICATION_DISPOSITION_SERVICE ||
- !application->priv->registered, 1);
- g_application_set_disposition (application,
- G_APPLICATION_DISPOSITION_SERVICE);
- g_application_register (application);
+ if (!g_application_register (application, NULL, &error))
+ {
+ g_critical ("%s", error->message);
+ g_error_free (error);
+
+ return 1;
+ }
application->priv->inactivity_timeout =
g_timeout_add (10000, g_application_inactivity_timeout, application);
g_application_run_mainloop (application);
+
+ return 0;
+}
+
+void
+g_application_open (GApplication *application,
+ GFile **files,
+ gint n_files,
+ const gchar *hint)
+{
+ if (g_application_is_remote (application))
+ {
+ GVariant *platform_data;
+
+ platform_data = g_application_get_platform_data (application);
+ g_application_impl_open (&application->priv->impl,
+ files, n_files, hint, platform_data);
+ }
+ else
+ {
+ G_APPLICATION_GET_CLASS (application)
+ ->open (application, files, n_files, hint);
+ }
}
diff --git a/gio/gapplication.h b/gio/gapplication.h
index 91a646a..19c6ad5 100644
--- a/gio/gapplication.h
+++ b/gio/gapplication.h
@@ -97,7 +97,7 @@ struct _GApplicationClass
/* vfuncs */
void (* add_platform_data) (GApplication *application,
GVariantBuilder *builder);
- gboolean (* process_arguments) (GApplication *application,
+ gboolean (* process_cmdline) (GApplication *application,
GVariant **arguments,
gint *exit_status);
@@ -105,10 +105,12 @@ struct _GApplicationClass
GVariant *arguments,
GVariant *platform_data);
- void (* emit_invocation) (GApplication *application,
+ int (* emit_cmdline) (GApplication *application,
GApplicationInvocation *invocation);
void (* emit_open) (GApplication *application,
- GFile *file,
+ GFile **files,
+ gint n_files,
+ const gchar *hint,
GVariant *platform_data);
void (* emit_activate) (GApplication *application,
GVariant *platform_data);
@@ -117,19 +119,12 @@ struct _GApplicationClass
GVariant *platform_data);
void (* quit_mainloop) (GApplication *application);
- int (* run_mainloop) (GApplication *application);
+ void (* run_mainloop) (GApplication *application);
/*< private >*/
gpointer padding[12];
};
-typedef enum
-{
- G_APPLICATION_FLAGS_NONE,
- G_APPLICATION_FLAGS_CAN_OPEN = (1 << 0),
- G_APPLICATION_FLAGS_REMOTE_CMDLINE = (1 << 1)
-} GApplicationFlags;
-
GType g_application_get_type (void) G_GNUC_CONST;
GApplication * g_application_get_instance (void);
@@ -138,7 +133,9 @@ gboolean g_application_is_supported (void);
GApplication * g_application_new (const gchar *appid,
GApplicationFlags flags);
-gboolean g_application_register (GApplication *application);
+gboolean g_application_register (GApplication *application,
+ GCancellable *cancellable,
+ GError **error);
gboolean g_application_is_remote (GApplication *application);
void g_application_set_flags (GApplication *application,
GApplicationFlags flags);
diff --git a/gio/gapplicationimpl-dbus-interface.c b/gio/gapplicationimpl-dbus-interface.c
new file mode 100644
index 0000000..e395830
--- /dev/null
+++ b/gio/gapplicationimpl-dbus-interface.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt desrt ca>
+ */
+
+#include "gapplicationimpl-dbus-private.h"
+
+static GDBusArgInfo platform_data_arg = { -1, (gchar *) "platform_data", (gchar *) "a{sv}" };
+
+static GDBusArgInfo open_uris_arg = { -1, (gchar *) "uris", (gchar *) "as" };
+static GDBusArgInfo open_hint_arg = { -1, (gchar *) "hint", (gchar *) "s" };
+
+static GDBusArgInfo invoke_action_name_arg = { -1, (gchar *) "name", (gchar *) "s" };
+static GDBusArgInfo invoke_action_args_arg = { -1, (gchar *) "args", (gchar *) "v" };
+
+static GDBusArgInfo cmdline_path_arg = { -1, (gchar *) "path", (gchar *) "o" };
+static GDBusArgInfo cmdline_arguments_arg = { -1, (gchar *) "arguments", (gchar *) "aay" };
+static GDBusArgInfo cmdline_exit_status_arg = { -1, (gchar *) "exit_status", (gchar *) "i" };
+
+static GDBusArgInfo list_actions_actions_arg = { -1, (gchar *) "actions", (gchar *) "a{s(sgb)}" };
+
+static const GDBusArgInfo *activate_in[] = { &platform_data_arg, NULL };
+static const GDBusArgInfo *activate_out[] = { NULL };
+
+static const GDBusArgInfo *open_in[] = { &open_uris_arg, &open_hint_arg, &platform_data_arg, NULL };
+static const GDBusArgInfo *open_out[] = { NULL };
+
+static const GDBusArgInfo *list_actions_in[] = { NULL };
+static const GDBusArgInfo *list_actions_out[] = { &list_actions_actions_arg, NULL };
+
+static const GDBusArgInfo *invoke_action_in[] = { &invoke_action_name_arg, &invoke_action_args_arg, NULL };
+static const GDBusArgInfo *invoke_action_out[] = { NULL };
+
+static const GDBusArgInfo *cmdline_in[] = { &cmdline_path_arg, &cmdline_arguments_arg, &platform_data_arg, NULL };
+static const GDBusArgInfo *cmdline_out[] = { &cmdline_exit_status_arg, NULL };
+
+static const GDBusMethodInfo activate_method = {
+ -1, (gchar *) "Activate",
+ (GDBusArgInfo **) activate_in,
+ (GDBusArgInfo **) activate_out
+};
+
+static const GDBusMethodInfo open_method = {
+ -1, (gchar *) "Open",
+ (GDBusArgInfo **) open_in,
+ (GDBusArgInfo **) open_out
+};
+
+static const GDBusMethodInfo list_actions_method = {
+ -1, (gchar *) "ListActions",
+ (GDBusArgInfo **) list_actions_in,
+ (GDBusArgInfo **) list_actions_out
+};
+
+static const GDBusMethodInfo invoke_action_method = {
+ -1, (gchar *) "InvokeAction",
+ (GDBusArgInfo **) invoke_action_in,
+ (GDBusArgInfo **) invoke_action_out
+};
+
+static const GDBusMethodInfo cmdline_method = {
+ -1, (gchar *) "Cmdline",
+ (GDBusArgInfo **) cmdline_in,
+ (GDBusArgInfo **) cmdline_out
+};
+
+static const GDBusMethodInfo *methods[] = {
+ &activate_method, &open_method, &list_actions_method, &invoke_action_method, &cmdline_method, NULL
+};
+
+const GDBusInterfaceInfo org_gtk_Application = {
+ -1, (gchar *) "org.gtk.Application",
+ (GDBusMethodInfo **) methods
+};
diff --git a/gio/gapplicationimpl-dbus-private.h b/gio/gapplicationimpl-dbus-private.h
new file mode 100644
index 0000000..0181df7
--- /dev/null
+++ b/gio/gapplicationimpl-dbus-private.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt desrt ca>
+ */
+
+#ifndef __GAPPLICATIONIMPL_DBUS_PRIVATE_H__
+#define __GAPPLICATIONIMPL_DBUS_PRIVATE_H__
+
+#include "gdbusintrospection.h"
+
+G_GNUC_INTERNAL extern const GDBusInterfaceInfo org_gtk_Application;
+
+#endif
diff --git a/gio/gapplicationimpl-dbus.c b/gio/gapplicationimpl-dbus.c
new file mode 100644
index 0000000..e6e5c52
--- /dev/null
+++ b/gio/gapplicationimpl-dbus.c
@@ -0,0 +1,310 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Ryan Lortie <desrt desrt ca>
+ */
+
+#include "gapplicationimpl-dbus-private.h"
+#include "gfile.h"
+
+struct _GApplicationImpl
+{
+ GDBusConnection *session_bus;
+ const gchar *bus_name;
+ gchar *object_path;
+ guint object_id;
+ gpointer app;
+};
+
+static void
+g_application_impl_method_call (GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ GApplicationImpl *impl = user_data;
+
+ if (strcmp (method_name, "Activate") == 0)
+ {
+ GVariant *platform_data;
+
+ g_variant_get (parameters, "(a{sv})", &platform_data);
+ G_APPLICATION_GET_CLASS (impl->app)
+ ->emit_activate (impl->app, platform_data);
+ g_variant_unref (platform_data);
+ }
+
+ else if (strcmp (method_name, "Open") == 0)
+ {
+ GVariant *platform_data;
+ const gchar *hint;
+ GVariant *array;
+ GFile **files;
+ gint n, i;
+
+ g_variant_get (parameters, "(@ass a{sv})",
+ &array, &hint, &platform_data);
+
+ n = g_variant_n_children (array);
+ files = g_new (GFile *, n + 1);
+
+ for (i = 0; i < n; i++)
+ {
+ const gchar *uri;
+
+ g_variant_get_child (array, i, "&s", &uri);
+ files[i] = g_file_new_for_uri (uri);
+ }
+ g_variant_unref (array);
+ files[n] = NULL;
+
+ G_APPLICATION_GET_CLASS (impl->app)
+ ->emit_open (impl->app, files, n, hint, platform_data);
+
+ g_variant_unref (platform_data);
+
+ for (i = 0; i < n; i++)
+ g_object_unref (files[i]);
+ g_free (files);
+ }
+
+ else if (strcmp (method_name, "ListActions") == 0)
+ {
+ }
+
+ else if (strcmp (method_name, "InvokeAction") == 0)
+ {
+ }
+
+ else if (strcmp (method_name, "Cmdline") == 0)
+ {
+ GVariant *arguments, *platform_data;
+ //GApplicationInvocation *invocation;
+ const gchar *remote_path;
+
+ g_variant_get (parameters, "(&o aay@a{sv})",
+ &remote_path, &arguments, &platform_data);
+
+ //invocation = g_application_create_invocation (application,
+ // arguments,
+ // platform_data);
+ g_variant_unref (platform_data);
+ g_variant_unref (arguments);
+
+ /* XXX hook up the stuff... */
+
+ //g_application_emit_invocation (invocation);
+ //g_object_unref (invocation);
+ }
+
+ else
+ g_assert_not_reached ();
+}
+
+static gchar *
+application_path_from_appid (const gchar *appid)
+{
+ gchar *appid_path, *iter;
+
+ appid_path = g_strconcat ("/", appid, NULL);
+ for (iter = appid_path; *iter; iter++)
+ {
+ if (*iter == '.')
+ *iter = '/';
+ }
+
+ return appid_path;
+}
+
+void
+g_application_impl_init (GApplicationImpl *impl,
+ gpointer app)
+{
+ impl->app = app;
+}
+
+static void
+g_application_impl_set_id (GApplicationImpl *impl,
+ const gchar *appid)
+{
+ impl->bus_name = appid;
+ impl->object_path = application_path_from_appid (appid);
+}
+
+static void
+g_application_impl_destroy (GApplicationImpl *impl)
+{
+ if (impl->session_bus)
+ {
+ if (impl->object_id)
+ g_dbus_connection_unregister_object (impl->session_bus,
+ impl->object_id);
+
+ g_object_unref (impl->session_bus);
+ }
+ else
+ g_assert (impl->object_id == 0);
+
+ g_free (impl->object_path);
+}
+
+static gboolean
+g_application_impl_register (GApplicationImpl *impl,
+ gboolean *is_remote,
+ GCancellable *cancellable,
+ GError **error)
+{
+ const static GDBusInterfaceVTable vtable = {
+ g_application_impl_method_call
+ };
+ GVariant *reply;
+ guint32 rval;
+
+ g_print ("eh\n");
+
+ g_assert (impl->session_bus == NULL);
+
+ impl->session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION,
+ cancellable, error);
+
+ if (impl->session_bus == NULL)
+ return FALSE;
+
+ g_print ("reg %s %s\n", org_gtk_Application.name, impl->object_path);
+ impl->object_id = g_dbus_connection_register_object (impl->session_bus,
+ impl->object_path,
+ (GDBusInterfaceInfo *)
+ &org_gtk_Application,
+ &vtable,
+ impl, NULL,
+ error);
+
+ if (impl->object_id == 0)
+ {
+ g_object_unref (impl->session_bus);
+ impl->session_bus = NULL;
+
+ return FALSE;
+ }
+
+ reply = g_dbus_connection_call_sync (impl->session_bus,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus",
+ "RequestName",
+ g_variant_new ("(su)",
+ /* DBUS_NAME_FLAG_DO_NOT_QUEUE: 0x4 */
+ impl->bus_name, 0x4),
+ G_VARIANT_TYPE ("(u)"),
+ 0, -1, cancellable, error);
+
+ if (reply == NULL)
+ {
+ g_dbus_connection_unregister_object (impl->session_bus,
+ impl->object_id);
+ impl->object_id = 0;
+
+ g_object_unref (impl->session_bus);
+ impl->session_bus = NULL;
+
+ return FALSE;
+ }
+
+ g_variant_get (reply, "(u)", &rval);
+ g_variant_unref (reply);
+
+ /* DBUS_REQUEST_NAME_REPLY_EXISTS: 3 */
+ if ((*is_remote = (rval == 3)))
+ {
+ g_dbus_connection_unregister_object (impl->session_bus,
+ impl->object_id);
+ impl->object_id = 0;
+ }
+
+ return TRUE;
+}
+
+static void
+g_application_impl_activate (GApplicationImpl *impl,
+ GVariant *platform_data)
+{
+ g_dbus_connection_call (impl->session_bus,
+ impl->bus_name,
+ impl->object_path,
+ "org.gtk.Application",
+ "Activate",
+ g_variant_new ("(@a{sv})", platform_data),
+ NULL, 0, -1, NULL, NULL, NULL);
+}
+
+static void
+g_application_impl_open (GApplicationImpl *impl,
+ GFile **files,
+ gint n_files,
+ const gchar *hint,
+ GVariant *platform_data)
+{
+ GVariantBuilder builder;
+ gint i;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("(assa{sv})"));
+ g_variant_builder_open (&builder, G_VARIANT_TYPE_STRING_ARRAY);
+ for (i = 0; i < n_files; i++)
+ {
+ gchar *uri = g_file_get_uri (files[i]);
+ g_variant_builder_add (&builder, "s", uri);
+ g_free (uri);
+ }
+ g_variant_builder_close (&builder);
+ g_variant_builder_add (&builder, "s", hint);
+ g_variant_builder_add_value (&builder, platform_data);
+
+ g_dbus_connection_call (impl->session_bus,
+ impl->bus_name,
+ impl->object_path,
+ "org.gtk.Application",
+ "Open",
+ g_variant_builder_end (&builder),
+ NULL, 0, -1, NULL, NULL, NULL);
+}
+
+static void
+g_application_impl_action (GApplicationImpl *impl,
+ const gchar *action_name,
+ GVariant *parameters,
+ GVariant *platform_data)
+{
+}
+
+static int
+g_application_impl_cmdline (GApplicationImpl *impl,
+ GVariant *arguments,
+ GVariant *platform_data)
+{
+ return 1;
+}
+
+static void
+g_application_impl_flush (GApplicationImpl *impl)
+{
+ g_dbus_connection_flush_sync (impl->session_bus, NULL, NULL);
+}
diff --git a/gio/gapplicationinvocation.c b/gio/gapplicationinvocation.c
index f180465..fbe18f0 100644
--- a/gio/gapplicationinvocation.c
+++ b/gio/gapplicationinvocation.c
@@ -215,7 +215,8 @@ g_application_invocation_set_property (GObject *object, guint prop_id,
case PROP_PLATFORM_DATA:
g_assert (invocation->priv->platform_data == NULL);
invocation->priv->platform_data = g_value_dup_variant (value);
- grok_platform_data (invocation);
+ if (invocation->priv->platform_data != NULL)
+ grok_platform_data (invocation);
break;
default:
@@ -228,8 +229,9 @@ g_application_invocation_finalize (GObject *object)
{
GApplicationInvocation *invocation = G_APPLICATION_INVOCATION (object);
- remote_impl_exit (&invocation->priv->remote_impl,
- invocation->priv->exit_status);
+ if (IS_REMOTE (invocation))
+ remote_impl_exit (&invocation->priv->remote_impl,
+ invocation->priv->exit_status);
if (invocation->priv->platform_data)
g_variant_unref (invocation->priv->platform_data);
@@ -245,6 +247,10 @@ g_application_invocation_finalize (GObject *object)
static void
g_application_invocation_init (GApplicationInvocation *invocation)
{
+ invocation->priv =
+ G_TYPE_INSTANCE_GET_PRIVATE (invocation,
+ G_TYPE_APPLICATION_INVOCATION,
+ GApplicationInvocationPrivate);
}
static void
@@ -260,18 +266,22 @@ g_application_invocation_class_init (GApplicationInvocationClass *class)
g_param_spec_variant ("arguments", "commandline arguments",
"the commandline that caused this invocation",
G_VARIANT_TYPE_BYTESTRING_ARRAY, NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_PLATFORM_DATA,
g_param_spec_variant ("platform-data", "platform data",
"platform-specific data for the invocation",
G_VARIANT_TYPE ("a{sv}"), NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_IS_REMOTE,
g_param_spec_boolean ("is-remote", "is remote",
"TRUE if this is a remote invocation", FALSE,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ g_type_class_add_private (class, sizeof (GApplicationInvocationPrivate));
}
GVariant *
diff --git a/gio/gioenums.h b/gio/gioenums.h
index 8027cf6..8135ee0 100644
--- a/gio/gioenums.h
+++ b/gio/gioenums.h
@@ -1199,6 +1199,26 @@ typedef enum
G_DBUS_MESSAGE_BYTE_ORDER_LITTLE_ENDIAN = 'l'
} GDBusMessageByteOrder;
+/**
+ * GApplicationFlags:
+ * @G_APPLICATION_FLAGS_NONE: Default
+ * @G_APPLICATION_FLAGS_CAN_OPEN: This application can open files.
+ * @G_APPLICATION_FLAGS_REMOTE_CMDLINE: This application is interested
+ * in advanced handling of commandline invocations (ie: by sending the
+ * commandline to the remote instance).
+ *
+ * Flags used to define the behaviour of a #GApplication.
+ *
+ * Since: 2.26
+ **/
+typedef enum
+{
+ G_APPLICATION_FLAGS_NONE,
+ G_APPLICATION_FLAGS_CAN_OPEN = (1 << 0),
+ G_APPLICATION_FLAGS_REMOTE_CMDLINE = (1 << 1)
+} GApplicationFlags;
+
+
G_END_DECLS
#endif /* __GIO_ENUMS_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]