aboutsummaryrefslogtreecommitdiffstats
path: root/shell
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@src.gnome.org>2009-01-29 06:28:57 +0800
committerMatthew Barnes <mbarnes@src.gnome.org>2009-01-29 06:28:57 +0800
commit70fce0bbb0712dc70a15c481c0b65d68a98a4ff7 (patch)
tree51b39245f74e32ac2878e4f65492e895a1ad0eb8 /shell
parent533d59e2cd30ba79a99a71907ffdda65505e633a (diff)
downloadgsoc2013-evolution-70fce0bbb0712dc70a15c481c0b65d68a98a4ff7.tar
gsoc2013-evolution-70fce0bbb0712dc70a15c481c0b65d68a98a4ff7.tar.gz
gsoc2013-evolution-70fce0bbb0712dc70a15c481c0b65d68a98a4ff7.tar.bz2
gsoc2013-evolution-70fce0bbb0712dc70a15c481c0b65d68a98a4ff7.tar.lz
gsoc2013-evolution-70fce0bbb0712dc70a15c481c0b65d68a98a4ff7.tar.xz
gsoc2013-evolution-70fce0bbb0712dc70a15c481c0b65d68a98a4ff7.tar.zst
gsoc2013-evolution-70fce0bbb0712dc70a15c481c0b65d68a98a4ff7.zip
When invoking Evolution with URIs on the command-line (e.g. mailto:),
terminate after all the windows for those URIs have been closed. svn path=/branches/kill-bonobo/; revision=37157
Diffstat (limited to 'shell')
-rw-r--r--shell/e-shell-window-private.c2
-rw-r--r--shell/e-shell-window.c19
-rw-r--r--shell/e-shell.c167
-rw-r--r--shell/e-shell.h6
-rw-r--r--shell/main.c15
-rw-r--r--shell/test/e-test-shell-module.c11
6 files changed, 128 insertions, 92 deletions
diff --git a/shell/e-shell-window-private.c b/shell/e-shell-window-private.c
index 53f7c28c64..02aac6cf10 100644
--- a/shell/e-shell-window-private.c
+++ b/shell/e-shell-window-private.c
@@ -340,6 +340,8 @@ e_shell_window_private_constructed (EShellWindow *shell_window)
shell = e_shell_window_get_shell (shell_window);
shell_settings = e_shell_get_shell_settings (shell);
+ e_shell_watch_window (shell, GTK_WINDOW (shell_window));
+
/* Create the switcher actions before we set the initial
* shell view, because the shell view relies on them for
* default settings during construction. */
diff --git a/shell/e-shell-window.c b/shell/e-shell-window.c
index 82727fecdd..ecc30cb9b5 100644
--- a/shell/e-shell-window.c
+++ b/shell/e-shell-window.c
@@ -132,17 +132,22 @@ static void
shell_window_update_close_action_cb (EShellWindow *shell_window)
{
EShell *shell;
- GList *shell_windows;
- gboolean sensitive;
+ GList *watched_windows;
+ gint n_shell_windows = 0;
shell = e_shell_window_get_shell (shell_window);
- shell_windows = e_shell_get_shell_windows (shell);
- g_return_if_fail (shell_windows != NULL);
+ watched_windows = e_shell_get_watched_windows (shell);
- /* Disable Close Window if there's only one window.
+ /* Count the shell windows. */
+ while (watched_windows != NULL) {
+ if (E_IS_SHELL_WINDOW (watched_windows->data))
+ n_shell_windows++;
+ watched_windows = g_list_next (watched_windows);
+ }
+
+ /* Disable Close Window if there's only one shell window.
* Helps prevent users from accidentally quitting. */
- sensitive = (g_list_length (shell_windows) > 1);
- gtk_action_set_sensitive (ACTION (CLOSE), sensitive);
+ gtk_action_set_sensitive (ACTION (CLOSE), n_shell_windows > 1);
}
static void
diff --git a/shell/e-shell.c b/shell/e-shell.c
index 160d637d54..e2d7761965 100644
--- a/shell/e-shell.c
+++ b/shell/e-shell.c
@@ -38,7 +38,7 @@
((obj), E_TYPE_SHELL, EShellPrivate))
struct _EShellPrivate {
- GList *active_windows;
+ GList *watched_windows;
EShellSettings *settings;
/* Shell Modules */
@@ -101,12 +101,21 @@ shell_parse_debug_string (EShell *shell)
e_shell_settings_enable_debug (shell->priv->settings);
}
+static void
+shell_notify_online_mode_cb (EShell *shell)
+{
+ gboolean online;
+
+ online = e_shell_get_online_mode (shell);
+ e_passwords_set_online (online);
+}
+
static gboolean
shell_window_delete_event_cb (EShell *shell,
- EShellWindow *shell_window)
+ GtkWindow *window)
{
/* If other windows are open we can safely close this one. */
- if (g_list_length (shell->priv->active_windows) > 1)
+ if (g_list_length (shell->priv->watched_windows) > 1)
return FALSE;
/* Otherwise we initiate application shutdown. */
@@ -116,16 +125,16 @@ shell_window_delete_event_cb (EShell *shell,
static gboolean
shell_window_focus_in_event_cb (EShell *shell,
GdkEventFocus *event,
- EShellWindow *shell_window)
+ GtkWindow *window)
{
GList *list, *link;
- /* Keep the active windows list sorted by most recently focused,
+ /* Keep the watched windows list sorted by most recently focused,
* so the first item in the list should always be the currently
- * focused shell window. */
+ * focused window. */
- list = shell->priv->active_windows;
- link = g_list_find (list, shell_window);
+ list = shell->priv->watched_windows;
+ link = g_list_find (list, window);
g_return_val_if_fail (link != NULL, FALSE);
if (link != list) {
@@ -133,29 +142,20 @@ shell_window_focus_in_event_cb (EShell *shell,
list = g_list_concat (link, list);
}
- shell->priv->active_windows = list;
+ shell->priv->watched_windows = list;
return FALSE;
}
static void
-shell_notify_online_mode_cb (EShell *shell)
-{
- gboolean online;
-
- online = e_shell_get_online_mode (shell);
- e_passwords_set_online (online);
-}
-
-static void
shell_window_weak_notify_cb (EShell *shell,
GObject *where_the_object_was)
{
- GList *active_windows;
+ GList *list;
- active_windows = shell->priv->active_windows;
- active_windows = g_list_remove (active_windows, where_the_object_was);
- shell->priv->active_windows = active_windows;
+ list = shell->priv->watched_windows;
+ list = g_list_remove (list, where_the_object_was);
+ shell->priv->watched_windows = list;
g_signal_emit (shell, signals[WINDOW_DESTROYED], 0);
}
@@ -380,7 +380,7 @@ shell_shutdown_timeout (EShell *shell)
* the act of destroying a shell window will modify the active
* windows list, which would otherwise derail the iteration. */
if (proceed) {
- list = g_list_copy (shell->priv->active_windows);
+ list = g_list_copy (shell->priv->watched_windows);
g_list_foreach (list, (GFunc) gtk_widget_destroy, NULL);
g_list_free (list);
@@ -748,9 +748,9 @@ shell_class_init (EShellClass *class)
/**
* EShell::window-created
* @shell: the #EShell which emitted the signal
- * @shell_window: the newly created #EShellWindow
+ * @window: the newly created #GtkWindow
*
- * Emitted when a new #EShellWindow is created.
+ * Emitted when @shell begins watching a newly created window.
**/
signals[WINDOW_CREATED] = g_signal_new (
"window-created",
@@ -759,7 +759,7 @@ shell_class_init (EShellClass *class)
0, NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
- E_TYPE_SHELL_WINDOW);
+ GTK_TYPE_WINDOW);
/**
* EShell::window-destroyed
@@ -896,6 +896,9 @@ e_shell_get_type (void)
*
* Returns the #EShell created by <function>main()</function>.
*
+ * Try to obtain the #EShell from elsewhere if you can. This function
+ * is intended as a temporary workaround for when that proves difficult.
+ *
* Returns: the #EShell singleton
**/
EShell *
@@ -925,26 +928,6 @@ e_shell_get_shell_modules (EShell *shell)
}
/**
- * e_shell_get_shell_windows:
- * @shell: an #EShell
- *
- * Returns a list of active #EShellWindow instances that were created by
- * e_shell_create_shell_window(). The list is sorted by the most recently
- * focused window, such that the first instance is the currently focused
- * window. (Useful for choosing a parent for a transient window.) The
- * list is owned by @shell and should not be modified or freed.
- *
- * Returns: a list of active #EShellWindow instances
- **/
-GList *
-e_shell_get_shell_windows (EShell *shell)
-{
- g_return_val_if_fail (E_IS_SHELL (shell), NULL);
-
- return shell->priv->active_windows;
-}
-
-/**
* e_shell_get_canonical_name:
* @shell: an #EShell
* @name: the name or alias of an #EShellModule
@@ -1052,7 +1035,6 @@ GtkWidget *
e_shell_create_shell_window (EShell *shell,
const gchar *view_name)
{
- GList *active_windows;
GtkWidget *shell_window;
UniqueMessageData *data;
UniqueApp *app;
@@ -1085,25 +1067,6 @@ e_shell_create_shell_window (EShell *shell,
}
shell_window = e_shell_window_new (shell, shell->priv->safe_mode);
- unique_app_watch_window (app, GTK_WINDOW (shell_window));
-
- active_windows = shell->priv->active_windows;
- active_windows = g_list_prepend (active_windows, shell_window);
- shell->priv->active_windows = active_windows;
-
- g_signal_connect_swapped (
- shell_window, "delete-event",
- G_CALLBACK (shell_window_delete_event_cb), shell);
-
- g_signal_connect_swapped (
- shell_window, "focus-in-event",
- G_CALLBACK (shell_window_focus_in_event_cb), shell);
-
- g_object_weak_ref (
- G_OBJECT (shell_window), (GWeakNotify)
- shell_window_weak_notify_cb, shell);
-
- g_signal_emit (shell, signals[WINDOW_CREATED], 0, shell_window);
gtk_widget_show (shell_window);
@@ -1135,7 +1098,7 @@ unique: /* Send a message to the other Evolution process. */
**/
guint
e_shell_handle_uris (EShell *shell,
- const gchar **uris)
+ gchar **uris)
{
UniqueApp *app;
UniqueMessageData *data;
@@ -1163,11 +1126,10 @@ e_shell_handle_uris (EShell *shell,
unique: /* Send a message to the other Evolution process. */
- /* XXX Do something with UniqueResponse?
- * XXX set_uris() should take a "const" URI list. */
+ /* XXX Do something with UniqueResponse? */
data = unique_message_data_new ();
- unique_message_data_set_uris (data, (gchar **) uris);
+ unique_message_data_set_uris (data, uris);
unique_app_send_message (app, UNIQUE_OPEN, data);
unique_message_data_free (data);
@@ -1175,6 +1137,71 @@ unique: /* Send a message to the other Evolution process. */
}
/**
+ * e_shell_watch_window:
+ * @shell: an #EShell
+ * @window: a #GtkWindow
+ *
+ * Makes @shell "watch" a newly created toplevel window, and emits the
+ * #EShell::window-created signal. All #EShellWindow<!-- -->s should be
+ * watched, along with any editor or viewer windows that may be shown in
+ * response to e_shell_handle_uris(). When the last watched window is
+ * closed, Evolution terminates.
+ **/
+void
+e_shell_watch_window (EShell *shell,
+ GtkWindow *window)
+{
+ GList *list;
+
+ g_return_if_fail (E_IS_SHELL (shell));
+ g_return_if_fail (GTK_IS_WINDOW (window));
+
+ list = shell->priv->watched_windows;
+
+ /* Ignore duplicates. */
+ if (g_list_find (list, window) != NULL)
+ return;
+
+ list = g_list_prepend (list, window);
+ shell->priv->watched_windows = list;
+
+ unique_app_watch_window (UNIQUE_APP (shell), window);
+
+ g_signal_connect_swapped (
+ window, "delete-event",
+ G_CALLBACK (shell_window_delete_event_cb), shell);
+
+ g_signal_connect_swapped (
+ window, "focus-in-event",
+ G_CALLBACK (shell_window_focus_in_event_cb), shell);
+
+ g_object_weak_ref (
+ G_OBJECT (window), (GWeakNotify)
+ shell_window_weak_notify_cb, shell);
+
+ g_signal_emit (shell, signals[WINDOW_CREATED], 0, window);
+}
+
+/**
+ * e_shell_get_watched_windows:
+ * @shell: an #EShell
+ *
+ * Returns a list of windows being watched by @shell. The list is sorted
+ * by the most recently focused window, such that the first instance is the
+ * currently focused window. (Useful for choosing a parent for a transient
+ * window.) The list is owned by @shell and should not be modified or freed.
+ *
+ * Returns: a list of watched windows
+ **/
+GList *
+e_shell_get_watched_windows (EShell *shell)
+{
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
+
+ return shell->priv->watched_windows;
+}
+
+/**
* e_shell_send_receive:
* @shell: an #EShell
* @parent: the parent #GtkWindow
diff --git a/shell/e-shell.h b/shell/e-shell.h
index 9e30550283..3f23779ee7 100644
--- a/shell/e-shell.h
+++ b/shell/e-shell.h
@@ -78,7 +78,6 @@ struct _EShellClass {
GType e_shell_get_type (void);
EShell * e_shell_get_default (void);
GList * e_shell_get_shell_modules (EShell *shell);
-GList * e_shell_get_shell_windows (EShell *shell);
const gchar * e_shell_get_canonical_name (EShell *shell,
const gchar *name);
EShellModule * e_shell_get_module_by_name (EShell *shell,
@@ -89,7 +88,10 @@ EShellSettings *e_shell_get_shell_settings (EShell *shell);
GtkWidget * e_shell_create_shell_window (EShell *shell,
const gchar *view_name);
guint e_shell_handle_uris (EShell *shell,
- const gchar **uris);
+ gchar **uris);
+void e_shell_watch_window (EShell *shell,
+ GtkWindow *window);
+GList * e_shell_get_watched_windows (EShell *shell);
void e_shell_send_receive (EShell *shell,
GtkWindow *parent);
gboolean e_shell_get_network_available (EShell *shell);
diff --git a/shell/main.c b/shell/main.c
index 670b24d1a2..ce1b467754 100644
--- a/shell/main.c
+++ b/shell/main.c
@@ -306,7 +306,6 @@ static gboolean
idle_cb (gchar **uris)
{
EShell *shell;
- guint ii;
#ifdef KILL_PROCESS_CMD
kill_old_dataserver ();
@@ -314,23 +313,21 @@ idle_cb (gchar **uris)
shell = e_shell_get_default ();
- /* These calls do the right thing when there's another
- * Evolution process running. */
+ /* These calls do the right thing when another Evolution
+ * process is running. */
if (uris != NULL && *uris != NULL)
e_shell_handle_uris (shell, uris);
else
e_shell_create_shell_window (shell, requested_view);
- if (unique_app_is_running (UNIQUE_APP (shell))) {
+ /* If another Evolution process is running, we're done. */
+ if (unique_app_is_running (UNIQUE_APP (shell)))
gtk_main_quit ();
- return FALSE;
- }
/* This must be done after EShell has loaded all the modules.
* For example the mail module makes the global variable `session`
* which is being used by several EPlugins */
-
- if (uris == NULL && !disable_eplugin)
+ else if (uris == NULL && !disable_eplugin)
e_plugin_load_plugins_with_missing_symbols ();
return FALSE;
@@ -471,7 +468,7 @@ set_paths (void)
static void
shell_window_destroyed_cb (EShell *shell)
{
- if (e_shell_get_shell_windows (shell) == NULL)
+ if (e_shell_get_watched_windows (shell) == NULL)
gtk_main_quit ();
}
diff --git a/shell/test/e-test-shell-module.c b/shell/test/e-test-shell-module.c
index fc489fa3b0..a7d2389fb7 100644
--- a/shell/test/e-test-shell-module.c
+++ b/shell/test/e-test-shell-module.c
@@ -115,20 +115,23 @@ test_module_send_receive_cb (EShellModule *shell_module,
static void
test_module_window_created_cb (EShellModule *shell_module,
- EShellWindow *shell_window)
+ GtkWindow *window)
{
const gchar *module_name;
- g_debug ("%s (window=%p)", G_STRFUNC, shell_window);
+ g_debug ("%s (%s)", G_STRFUNC, G_OBJECT_TYPE_NAME (window));
+
+ if (!E_IS_SHELL_WINDOW (window))
+ return;
module_name = G_TYPE_MODULE (shell_module)->name;
e_shell_window_register_new_item_actions (
- shell_window, module_name,
+ E_SHELL_WINDOW (window), module_name,
item_entries, G_N_ELEMENTS (item_entries));
e_shell_window_register_new_source_actions (
- shell_window, module_name,
+ E_SHELL_WINDOW (window), module_name,
source_entries, G_N_ELEMENTS (source_entries));
}