aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2011-01-31 12:11:14 +0800
committerMatthew Barnes <mbarnes@redhat.com>2011-03-25 02:55:24 +0800
commit5399f35bbce8f4e5775fa96b795c527002c48969 (patch)
treebc7c1975f639b8c829d44b9c6b6fb72f6a04368c
parent617e766a48fa928e450b1717b12b981129e5c1c4 (diff)
downloadgsoc2013-evolution-5399f35bbce8f4e5775fa96b795c527002c48969.tar.gz
gsoc2013-evolution-5399f35bbce8f4e5775fa96b795c527002c48969.tar.zst
gsoc2013-evolution-5399f35bbce8f4e5775fa96b795c527002c48969.zip
Port EShell to GtkApplication.
-rw-r--r--shell/e-shell.c306
-rw-r--r--shell/e-shell.h7
-rw-r--r--shell/main.c32
3 files changed, 182 insertions, 163 deletions
diff --git a/shell/e-shell.c b/shell/e-shell.c
index f3402dd101..d9dcb5de9a 100644
--- a/shell/e-shell.c
+++ b/shell/e-shell.c
@@ -47,6 +47,7 @@ struct _EShellPrivate {
GList *watched_windows;
EShellSettings *settings;
GConfClient *gconf_client;
+ GActionGroup *action_group;
GtkWidget *preferences_window;
/* Shell Backends */
@@ -109,10 +110,15 @@ static GDebugKey debug_keys[] = {
static gpointer default_shell;
static guint signals[LAST_SIGNAL];
+/* Forward Declarations */
+static void e_shell_initable_init (GInitableIface *interface);
+
G_DEFINE_TYPE_WITH_CODE (
EShell,
e_shell,
- UNIQUE_TYPE_APP,
+ GTK_TYPE_APPLICATION,
+ G_IMPLEMENT_INTERFACE (
+ G_TYPE_INITABLE, e_shell_initable_init)
G_IMPLEMENT_INTERFACE (
E_TYPE_EXTENSIBLE, NULL))
@@ -219,6 +225,57 @@ shell_window_weak_notify_cb (EShell *shell,
}
static void
+shell_action_new_window_cb (GSimpleAction *action,
+ GVariant *parameter,
+ EShell *shell)
+{
+ const gchar *view_name;
+
+ view_name = g_variant_get_string (parameter, NULL);
+ e_shell_create_shell_window (shell, view_name);
+}
+
+static void
+shell_action_quit_cb (GSimpleAction *action,
+ GVariant *parameter,
+ EShell *shell)
+{
+ e_shell_quit (shell, E_SHELL_QUIT_REMOTE_REQUEST);
+}
+
+static void
+shell_add_actions (GApplication *application)
+{
+ EShell *shell;
+ GSimpleActionGroup *action_group;
+ GSimpleAction *action;
+
+ /* Add actions that remote instances can invoke. */
+
+ action_group = g_simple_action_group_new ();
+
+ action = g_simple_action_new ("new-window", G_VARIANT_TYPE_STRING);
+ g_signal_connect (
+ action, "activate",
+ G_CALLBACK (shell_action_new_window_cb), application);
+ g_simple_action_group_insert (action_group, G_ACTION (action));
+ g_object_unref (action);
+
+ action = g_simple_action_new ("quit", NULL);
+ g_signal_connect (
+ action, "activate",
+ G_CALLBACK (shell_action_quit_cb), application);
+ g_simple_action_group_insert (action_group, G_ACTION (action));
+ g_object_unref (action);
+
+ shell = E_SHELL (application);
+ shell->priv->action_group = G_ACTION_GROUP (action_group);
+
+ g_application_set_action_group (
+ application, shell->priv->action_group);
+}
+
+static void
shell_ready_for_offline (EShell *shell,
EActivity *activity,
gboolean is_last_ref)
@@ -658,6 +715,11 @@ shell_dispose (GObject *object)
priv->gconf_client = NULL;
}
+ if (priv->action_group != NULL) {
+ g_object_unref (priv->action_group);
+ priv->action_group = NULL;
+ }
+
if (priv->preferences_window != NULL) {
g_object_unref (priv->preferences_window);
priv->preferences_window = NULL;
@@ -683,10 +745,6 @@ shell_finalize (GObject *object)
g_hash_table_destroy (priv->backends_by_name);
g_hash_table_destroy (priv->backends_by_scheme);
- /* Indicates a clean shut down to the next session. */
- if (!unique_app_is_running (UNIQUE_APP (object)))
- e_file_lock_destroy ();
-
g_list_foreach (priv->loaded_backends, (GFunc) g_object_unref, NULL);
g_list_free (priv->loaded_backends);
@@ -706,21 +764,34 @@ shell_constructed (GObject *object)
g_object_add_weak_pointer (object, &default_shell);
}
- if (!unique_app_is_running (UNIQUE_APP (object)))
- e_file_lock_create ();
-
/* Chain up to parent's constructed() method. */
G_OBJECT_CLASS (e_shell_parent_class)->constructed (object);
}
-static UniqueResponse
-shell_message_handle_activate (EShell *shell,
- UniqueMessageData *data)
+static void
+shell_startup (GApplication *application)
+{
+ e_file_lock_create ();
+
+ /* Destroy the lock file when the EShell is finalized
+ * to indicate a clean shut down to the next session. */
+ g_object_weak_ref (
+ G_OBJECT (application),
+ (GWeakNotify) e_file_lock_destroy, NULL);
+
+ /* Chain up to parent's startup() method. */
+ G_APPLICATION_CLASS (e_shell_parent_class)->startup (application);
+}
+
+static void
+shell_activate (GApplication *application)
{
+ EShell *shell;
GList *watched_windows;
- GdkScreen *screen;
- screen = unique_message_data_get_screen (data);
+ /* Do not chain up. Default method just emits a warning. */
+
+ shell = E_SHELL (application);
watched_windows = e_shell_get_watched_windows (shell);
/* Present the first EShellWindow, if found. */
@@ -728,9 +799,8 @@ shell_message_handle_activate (EShell *shell,
GtkWindow *window = GTK_WINDOW (watched_windows->data);
if (E_IS_SHELL_WINDOW (window)) {
- gtk_window_set_screen (window, screen);
gtk_window_present (window);
- return UNIQUE_RESPONSE_OK;
+ return;
}
watched_windows = g_list_next (watched_windows);
@@ -738,108 +808,55 @@ shell_message_handle_activate (EShell *shell,
/* No EShellWindow found, so create one. */
e_shell_create_shell_window (shell, NULL);
-
- return UNIQUE_RESPONSE_OK;
}
-static UniqueResponse
-shell_message_handle_new (EShell *shell,
- UniqueMessageData *data)
-{
- gchar *view_name;
-
- view_name = unique_message_data_get_text (data);
- e_shell_create_shell_window (shell, view_name);
- g_free (view_name);
-
- return UNIQUE_RESPONSE_OK;
-}
-
-static UniqueResponse
-shell_message_handle_open (EShell *shell,
- UniqueMessageData *data)
+static void
+shell_open (GApplication *application,
+ GFile **files,
+ gint n_files,
+ const gchar *hint)
{
+ EShell *shell;
gchar **uris;
+ gint ii;
- uris = unique_message_data_get_uris (data);
- if (uris && uris[0] && g_str_equal (uris[0], "--import")) {
- gint ii;
- GPtrArray *arr = g_ptr_array_new ();
+ /* Do not chain up. Default method just emits a warning. */
- /* skip the first argument */
- for (ii = 1; uris[ii] != NULL; ii++) {
- g_ptr_array_add (arr, uris[ii]);
- }
+ shell = E_SHELL (application);
+ uris = g_new0 (gchar *, n_files + 1);
- g_ptr_array_add (arr, NULL);
+ for (ii = 0; ii < n_files; ii++)
+ uris[ii] = g_file_get_uri (files[ii]);
- e_shell_handle_uris (shell, (gchar **)arr->pdata, TRUE);
+ e_shell_handle_uris (shell, uris, FALSE);
- g_ptr_array_free (arr, TRUE);
- } else {
- e_shell_handle_uris (shell, uris, FALSE);
- }
g_strfreev (uris);
-
- return UNIQUE_RESPONSE_OK;
}
-static UniqueResponse
-shell_message_handle_close (EShell *shell,
- UniqueMessageData *data)
+static void
+shell_window_destroyed (EShell *shell)
{
- UniqueResponse response;
-
- if (e_shell_quit (shell, E_SHELL_QUIT_REMOTE_REQUEST))
- response = UNIQUE_RESPONSE_OK;
- else
- response = UNIQUE_RESPONSE_CANCEL;
-
- return response;
+ if (e_shell_get_watched_windows (shell) == NULL)
+ gtk_main_quit ();
}
-static UniqueResponse
-shell_message_received (UniqueApp *app,
- gint command,
- UniqueMessageData *data,
- guint time_)
+static gboolean
+shell_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
{
- EShell *shell = E_SHELL (app);
-
- switch (command) {
- case UNIQUE_ACTIVATE:
- return shell_message_handle_activate (shell, data);
-
- case UNIQUE_NEW:
- return shell_message_handle_new (shell, data);
+ GApplication *application = G_APPLICATION (initable);
- case UNIQUE_OPEN:
- return shell_message_handle_open (shell, data);
-
- case UNIQUE_CLOSE:
- return shell_message_handle_close (shell, data);
-
- default:
- break;
- }
+ shell_add_actions (application);
- /* Chain up to parent's message_received() method. */
- return UNIQUE_APP_CLASS (e_shell_parent_class)->
- message_received (app, command, data, time_);
-}
-
-static void
-shell_window_destroyed (EShell *shell)
-{
- if (e_shell_get_watched_windows (shell) == NULL)
- gtk_main_quit ();
+ return g_application_register (application, cancellable, error);
}
static void
e_shell_class_init (EShellClass *class)
{
GObjectClass *object_class;
- UniqueAppClass *unique_app_class;
+ GApplicationClass *application_class;
g_type_class_add_private (class, sizeof (EShellPrivate));
@@ -850,8 +867,10 @@ e_shell_class_init (EShellClass *class)
object_class->finalize = shell_finalize;
object_class->constructed = shell_constructed;
- unique_app_class = UNIQUE_APP_CLASS (class);
- unique_app_class->message_received = shell_message_received;
+ application_class = G_APPLICATION_CLASS (class);
+ application_class->startup = shell_startup;
+ application_class->activate = shell_activate;
+ application_class->open = shell_open;
class->window_destroyed = shell_window_destroyed;
@@ -1162,6 +1181,12 @@ e_shell_class_init (EShellClass *class)
}
static void
+e_shell_initable_init (GInitableIface *interface)
+{
+ interface->init = shell_initable_init;
+}
+
+static void
e_shell_init (EShell *shell)
{
GHashTable *backends_by_name;
@@ -1347,8 +1372,8 @@ e_shell_get_canonical_name (EShell *shell,
g_return_val_if_fail (E_IS_SHELL (shell), NULL);
- /* Handle NULL name arguments silently. */
- if (name == NULL)
+ /* Handle NULL or empty name arguments silently. */
+ if (name == NULL || *name == '\0')
return NULL;
shell_backend = e_shell_get_backend_by_name (shell, name);
@@ -1455,16 +1480,12 @@ e_shell_create_shell_window (EShell *shell,
const gchar *view_name)
{
GtkWidget *shell_window;
- UniqueMessageData *data;
- UniqueApp *app;
GList *link;
g_return_val_if_fail (E_IS_SHELL (shell), NULL);
- app = UNIQUE_APP (shell);
-
- if (unique_app_is_running (app))
- goto unique;
+ if (g_application_get_is_remote (G_APPLICATION (shell)))
+ goto remote;
view_name = e_shell_get_canonical_name (shell, view_name);
@@ -1508,17 +1529,14 @@ e_shell_create_shell_window (EShell *shell,
return shell_window;
-unique: /* Send a message to the other Evolution process. */
-
- /* XXX Do something with UniqueResponse? */
+remote: /* Send a message to the other Evolution process. */
if (view_name != NULL) {
- data = unique_message_data_new ();
- unique_message_data_set_text (data, view_name, -1);
- unique_app_send_message (app, UNIQUE_NEW, data);
- unique_message_data_free (data);
+ g_action_group_activate_action (
+ shell->priv->action_group, "new-window",
+ g_variant_new_string (view_name));
} else
- unique_app_send_message (app, UNIQUE_ACTIVATE, NULL);
+ g_application_activate (G_APPLICATION (shell));
return NULL;
}
@@ -1538,18 +1556,15 @@ e_shell_handle_uris (EShell *shell,
gchar **uris,
gboolean do_import)
{
- UniqueApp *app;
- UniqueMessageData *data;
+ GFile **files;
guint n_handled = 0;
- gint ii;
+ guint length, ii;
g_return_val_if_fail (E_IS_SHELL (shell), FALSE);
g_return_val_if_fail (uris != NULL, FALSE);
- app = UNIQUE_APP (shell);
-
- if (unique_app_is_running (app))
- goto unique;
+ if (g_application_get_is_remote (G_APPLICATION (shell)))
+ goto remote;
if (do_import) {
n_handled = e_shell_utils_import_uris (shell, uris);
@@ -1569,34 +1584,23 @@ e_shell_handle_uris (EShell *shell,
return n_handled;
-unique: /* Send a message to the other Evolution process. */
+remote: /* Send a message to the other Evolution process. */
- /* XXX Do something with UniqueResponse? */
+ length = g_strv_length (uris);
- data = unique_message_data_new ();
- if (do_import) {
- GPtrArray *arr = g_ptr_array_new ();
+ files = g_new0 (GFile *, length + 1);
+ for (ii = 0; ii < length; ii++)
+ files[ii] = g_file_new_for_uri (uris[ii]);
- g_ptr_array_add (arr, (gpointer)"--import");
+ g_application_open (G_APPLICATION (shell), files, length, "");
- for (ii = 0; uris[ii] != NULL; ii++) {
- g_ptr_array_add (arr, uris[ii]);
- }
-
- g_ptr_array_add (arr, NULL);
-
- unique_message_data_set_uris (data, (gchar **)arr->pdata);
-
- g_ptr_array_free (arr, TRUE);
- } else {
- unique_message_data_set_uris (data, uris);
- }
- unique_app_send_message (app, UNIQUE_OPEN, data);
- unique_message_data_free (data);
+ for (ii = 0; ii < length; ii++)
+ g_object_unref (files[ii]);
+ g_free (files);
/* As far as we're concerned, all URIs have been handled. */
- return g_strv_length (uris);
+ return length;
}
/**
@@ -1655,6 +1659,12 @@ e_shell_watch_window (EShell *shell,
list = shell->priv->watched_windows;
+ /* XXX If my suggestion in [1] is accepted for GtkApplication
+ * then we can get rid of our own watched_windows list.
+ *
+ * [1] https://bugzilla.gnome.org/show_bug.cgi?id=624539
+ */
+
/* Ignore duplicates. */
if (g_list_find (list, window) != NULL)
return;
@@ -1662,7 +1672,7 @@ e_shell_watch_window (EShell *shell,
list = g_list_prepend (list, window);
shell->priv->watched_windows = list;
- unique_app_watch_window (UNIQUE_APP (shell), window);
+ gtk_application_add_window (GTK_APPLICATION (shell), window);
/* We use the window's own type name and memory
* address to form a unique window role for X11. */
@@ -1987,15 +1997,10 @@ gboolean
e_shell_quit (EShell *shell,
EShellQuitReason reason)
{
- UniqueApp *app;
- UniqueResponse response;
-
g_return_val_if_fail (E_IS_SHELL (shell), FALSE);
- app = UNIQUE_APP (shell);
-
- if (unique_app_is_running (app))
- goto unique;
+ if (g_application_get_is_remote (G_APPLICATION (shell)))
+ goto remote;
if (!shell_request_quit (shell, reason))
return FALSE;
@@ -2004,11 +2009,12 @@ e_shell_quit (EShell *shell,
return TRUE;
-unique: /* Send a message to the other Evolution process. */
+remote: /* Send a message to the other Evolution process. */
- response = unique_app_send_message (app, UNIQUE_CLOSE, NULL);
+ g_action_group_activate_action (
+ shell->priv->action_group, "quit", NULL);
- return (response == UNIQUE_RESPONSE_OK);
+ return TRUE;
}
/**
diff --git a/shell/e-shell.h b/shell/e-shell.h
index 22aef9252f..bbb11467fc 100644
--- a/shell/e-shell.h
+++ b/shell/e-shell.h
@@ -22,7 +22,6 @@
#ifndef E_SHELL_H
#define E_SHELL_H
-#include <unique/unique.h>
#include <gconf/gconf-client.h>
#include <e-util/e-activity.h>
@@ -90,12 +89,12 @@ typedef enum {
* functions below.
**/
struct _EShell {
- UniqueApp parent;
+ GtkApplication parent;
EShellPrivate *priv;
};
struct _EShellClass {
- UniqueAppClass parent_class;
+ GtkApplicationClass parent_class;
gboolean (*handle_uri) (EShell *shell,
const gchar *uri);
@@ -154,7 +153,7 @@ gboolean e_shell_quit (EShell *shell,
EShellQuitReason reason);
void e_shell_cancel_quit (EShell *shell);
-void e_shell_adapt_window_size (EShell *shell,
+void e_shell_adapt_window_size (EShell *shell,
GtkWindow *window);
void e_shell_set_startup_view (EShell *shell,
const gchar *view);
diff --git a/shell/main.c b/shell/main.c
index f9c9651e49..a27b6b9495 100644
--- a/shell/main.c
+++ b/shell/main.c
@@ -84,6 +84,8 @@
#include <libical/ical.h>
#endif
+#define APPLICATION_ID "org.gnome.Evolution"
+
#define SKIP_WARNING_DIALOG_KEY \
"/apps/evolution/shell/skip_warning_dialog"
@@ -257,7 +259,7 @@ idle_cb (gchar **uris)
}
/* If another Evolution process is running, we're done. */
- if (unique_app_is_running (UNIQUE_APP (shell)))
+ if (g_application_get_is_remote (G_APPLICATION (shell)))
gtk_main_quit ();
return FALSE;
@@ -324,7 +326,8 @@ quit_signal (gint sig)
g_print ("Received quit signal...\n");
shell = e_shell_get_default ();
- if (shell)
+
+ if (shell != NULL)
e_shell_quit (shell, E_SHELL_QUIT_OPTION);
}
@@ -411,10 +414,12 @@ create_default_shell (void)
{
EShell *shell;
GConfClient *client;
- gboolean online = TRUE;
+ GApplicationFlags flags;
const gchar *key;
+ gboolean online = TRUE;
+ gboolean is_meego = FALSE;
+ gboolean small_screen = FALSE;
GError *error = NULL;
- gboolean is_meego = FALSE, small_screen = FALSE;
client = gconf_client_get_default ();
@@ -457,9 +462,13 @@ create_default_shell (void)
g_clear_error (&error);
}
- shell = g_object_new (
- E_TYPE_SHELL,
- "name", "org.gnome.Evolution",
+ flags = G_APPLICATION_HANDLES_OPEN |
+ G_APPLICATION_HANDLES_COMMAND_LINE;
+
+ shell = g_initable_new (
+ E_TYPE_SHELL, NULL, &error,
+ "application-id", APPLICATION_ID,
+ "flags", flags,
"geometry", geometry,
"module-directory", EVOLUTION_MODULEDIR,
"meego-mode", is_meego,
@@ -468,6 +477,10 @@ create_default_shell (void)
"online", online,
NULL);
+ /* Failure to register is fatal. */
+ if (error != NULL)
+ g_error ("%s", error->message);
+
if (force_online)
e_shell_lock_network_available (shell);
@@ -571,9 +584,9 @@ main (gint argc, gchar **argv)
exit (1);
}
- #ifdef HAVE_ICAL_UNKNOWN_TOKEN_HANDLING
+#ifdef HAVE_ICAL_UNKNOWN_TOKEN_HANDLING
ical_set_unknown_token_handling_setting (ICAL_DISCARD_TOKEN);
- #endif
+#endif
#ifdef G_OS_WIN32
path = g_build_path (";", _e_get_bindir (), g_getenv ("PATH"), NULL);
@@ -622,6 +635,7 @@ main (gint argc, gchar **argv)
setlocale (LC_ALL, "C");
}
#endif
+
if (start_online && start_offline) {
g_printerr (
_("%s: --online and --offline cannot be used "