aboutsummaryrefslogtreecommitdiffstats
path: root/shell
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2011-09-04 21:48:24 +0800
committerMatthew Barnes <mbarnes@redhat.com>2011-10-06 20:16:21 +0800
commit224f26b84d9c12b0dd1d337f51c14b6ebb901007 (patch)
treec88109d0fe00df4b14dcf1ce641cd5ed91013f0f /shell
parentda3e201c064f877c884befc0a0b434619b056e09 (diff)
downloadgsoc2013-evolution-224f26b84d9c12b0dd1d337f51c14b6ebb901007.tar
gsoc2013-evolution-224f26b84d9c12b0dd1d337f51c14b6ebb901007.tar.gz
gsoc2013-evolution-224f26b84d9c12b0dd1d337f51c14b6ebb901007.tar.bz2
gsoc2013-evolution-224f26b84d9c12b0dd1d337f51c14b6ebb901007.tar.lz
gsoc2013-evolution-224f26b84d9c12b0dd1d337f51c14b6ebb901007.tar.xz
gsoc2013-evolution-224f26b84d9c12b0dd1d337f51c14b6ebb901007.tar.zst
gsoc2013-evolution-224f26b84d9c12b0dd1d337f51c14b6ebb901007.zip
GtkApplication has some new EShell-like features.
I pushed a few EShell features up to GtkApplication for GTK+ 3.2, so we can now trim off the redundancies in EShell. 1) GtkApplication has a new "window-added" signal which replaces EShell's own "window-created" signal. 2) GtkApplication has a new "window-removed" signal which replaces EShell's own "window-destroyed" signal. 3) gtk_application_get_windows() now returns a list of windows sorted by most recently focused, replacing e_shell_get_watched_windows(). 4) GtkApplication now provides enough hooks to subclasses that we can remove e_shell_watch_window() and call gtk_application_add_window() directly.
Diffstat (limited to 'shell')
-rw-r--r--shell/e-shell-utils.c4
-rw-r--r--shell/e-shell-window-private.c2
-rw-r--r--shell/e-shell-window.c29
-rw-r--r--shell/e-shell.c274
-rw-r--r--shell/e-shell.h6
-rw-r--r--shell/test/e-test-shell-backend.c14
6 files changed, 91 insertions, 238 deletions
diff --git a/shell/e-shell-utils.c b/shell/e-shell-utils.c
index 740960f555..05722a0319 100644
--- a/shell/e-shell-utils.c
+++ b/shell/e-shell-utils.c
@@ -306,7 +306,9 @@ e_shell_utils_import_uris (EShell *shell,
assistant, "finished",
G_CALLBACK (gtk_widget_destroy), NULL);
- e_shell_watch_window (shell, GTK_WINDOW (assistant));
+ gtk_application_add_window (
+ GTK_APPLICATION (shell),
+ GTK_WINDOW (assistant));
gtk_widget_show (assistant);
} else
diff --git a/shell/e-shell-window-private.c b/shell/e-shell-window-private.c
index 105e45e6a6..2b86bb1ec3 100644
--- a/shell/e-shell-window-private.c
+++ b/shell/e-shell-window-private.c
@@ -475,7 +475,7 @@ e_shell_window_private_constructed (EShellWindow *shell_window)
e_plugin_ui_register_manager (ui_manager, id, shell_window);
e_plugin_ui_enable_manager (ui_manager, id);
- e_shell_watch_window (shell, window);
+ gtk_application_add_window (GTK_APPLICATION (shell), window);
}
void
diff --git a/shell/e-shell-window.c b/shell/e-shell-window.c
index 8e9f39c5ce..1a969de8c9 100644
--- a/shell/e-shell-window.c
+++ b/shell/e-shell-window.c
@@ -125,17 +125,20 @@ static void
shell_window_update_close_action_cb (EShellWindow *shell_window)
{
EShell *shell;
- GList *watched_windows;
+ GtkApplication *application;
+ GList *list;
gint n_shell_windows = 0;
shell = e_shell_window_get_shell (shell_window);
- watched_windows = e_shell_get_watched_windows (shell);
+
+ application = GTK_APPLICATION (shell);
+ list = gtk_application_get_windows (application);
/* Count the shell windows. */
- while (watched_windows != NULL) {
- if (E_IS_SHELL_WINDOW (watched_windows->data))
+ while (list != NULL) {
+ if (E_IS_SHELL_WINDOW (list->data))
n_shell_windows++;
- watched_windows = g_list_next (watched_windows);
+ list = g_list_next (list);
}
/* Disable Close Window if there's only one shell window.
@@ -171,14 +174,14 @@ shell_window_set_shell (EShellWindow *shell_window,
array = shell_window->priv->signal_handler_ids;
handler_id = g_signal_connect_swapped (
- shell, "window-created",
+ shell, "window-added",
G_CALLBACK (shell_window_update_close_action_cb),
shell_window);
g_array_append_val (array, handler_id);
handler_id = g_signal_connect_swapped (
- shell, "window-destroyed",
+ shell, "window-removed",
G_CALLBACK (shell_window_update_close_action_cb),
shell_window);
@@ -1510,9 +1513,9 @@ e_shell_window_set_toolbar_visible (EShellWindow *shell_window,
* Registers a list of #GtkAction<!-- -->s to appear in
* @shell_window<!-- -->'s "New" menu and toolbar button. This
* function should be called from an #EShell<!-- -->'s
- * #EShell::window-created signal handler. The #EShellBackend calling
- * this function should pass its own name for the @backend_name argument
- * (i.e. the <structfield>name</structfield> field from its own
+ * #GtkApplication::window-added signal handler. The #EShellBackend
+ * calling this function should pass its own name for the @backend_name
+ * argument (i.e. the <structfield>name</structfield> field from its own
* #EShellBackendInfo).
*
* The registered #GtkAction<!-- -->s should be for creating individual
@@ -1597,9 +1600,9 @@ e_shell_window_register_new_item_actions (EShellWindow *shell_window,
* Registers a list of #GtkAction<!-- -->s to appear in
* @shell_window<!-- -->'s "New" menu and toolbar button. This
* function should be called from an #EShell<!-- -->'s
- * #EShell::window-created signal handler. The #EShellBackend calling
- * this function should pass its own name for the @backend_name argument
- * (i.e. the <structfield>name</structfield> field from its own
+ * #GtkApplication::window-added signal handler. The #EShellBackend
+ * calling this function should pass its own name for the @backend_name
+ * argument (i.e. the <structfield>name</structfield> field from its own
* #EShellBackendInfo).
*
* The registered #GtkAction<!-- -->s should be for creating item
diff --git a/shell/e-shell.c b/shell/e-shell.c
index dce7b21070..8aaefd302e 100644
--- a/shell/e-shell.c
+++ b/shell/e-shell.c
@@ -52,7 +52,6 @@
struct _EShellPrivate {
GQueue alerts;
- GList *watched_windows;
EShellSettings *settings;
GConfClient *gconf_client;
GActionGroup *action_group;
@@ -102,8 +101,6 @@ enum {
PREPARE_FOR_ONLINE,
PREPARE_FOR_QUIT,
QUIT_REQUESTED,
- WINDOW_CREATED,
- WINDOW_DESTROYED,
LAST_SIGNAL
};
@@ -166,86 +163,37 @@ shell_notify_online_cb (EShell *shell)
}
static gboolean
-shell_window_delete_event_cb (EShell *shell,
- GtkWindow *window)
+shell_window_delete_event_cb (GtkWindow *window,
+ GdkEvent *event,
+ GtkApplication *application)
{
/* If other windows are open we can safely close this one. */
- if (g_list_length (shell->priv->watched_windows) > 1)
+ if (g_list_length (gtk_application_get_windows (application)) > 1)
return FALSE;
/* Otherwise we initiate application quit. */
- e_shell_quit (shell, E_SHELL_QUIT_LAST_WINDOW);
+ e_shell_quit (E_SHELL (application), E_SHELL_QUIT_LAST_WINDOW);
return TRUE;
}
-static gboolean
-shell_window_focus_in_event_cb (EShell *shell,
- GdkEventFocus *event,
- GtkWindow *window)
-{
- GList *list, *link;
-
- /* Keep the watched windows list sorted by most recently focused,
- * so the first item in the list should always be the currently
- * focused window. */
-
- list = shell->priv->watched_windows;
- link = g_list_find (list, window);
- g_return_val_if_fail (link != NULL, FALSE);
-
- if (link != list) {
- list = g_list_remove_link (list, link);
- list = g_list_concat (link, list);
- }
-
- shell->priv->watched_windows = list;
-
- return FALSE;
-}
-
-static gboolean
-shell_emit_window_destroyed_cb (EShell *shell)
-{
- g_signal_emit (shell, signals[WINDOW_DESTROYED], 0);
-
- g_object_unref (shell);
-
- return FALSE;
-}
-
-static void
-shell_window_weak_notify_cb (EShell *shell,
- GObject *where_the_object_was)
-{
- GList *list;
-
- list = shell->priv->watched_windows;
- list = g_list_remove (list, where_the_object_was);
- shell->priv->watched_windows = list;
-
- /* Let the watched window finish finalizing itself before we
- * emit the "window-destroyed" signal, which may trigger the
- * application to initiate shutdown. */
- g_idle_add (
- (GSourceFunc) shell_emit_window_destroyed_cb,
- g_object_ref (shell));
-}
-
static void
shell_action_new_window_cb (GSimpleAction *action,
GVariant *parameter,
EShell *shell)
{
- GList *watched_windows;
+ GtkApplication *application;
+ GList *list;
const gchar *view_name;
+ application = GTK_APPLICATION (shell);
+ list = gtk_application_get_windows (application);
+
view_name = g_variant_get_string (parameter, NULL);
- watched_windows = e_shell_get_watched_windows (shell);
/* Present the first EShellWindow showing 'view_name'. */
- while (watched_windows != NULL) {
- GtkWindow *window = GTK_WINDOW (watched_windows->data);
+ while (list != NULL) {
+ GtkWindow *window = GTK_WINDOW (list->data);
if (E_IS_SHELL_WINDOW (window)) {
const gchar *active_view;
@@ -258,7 +206,7 @@ shell_action_new_window_cb (GSimpleAction *action,
}
}
- watched_windows = g_list_next (watched_windows);
+ list = g_list_next (list);
}
/* No suitable EShellWindow found, so create one. */
@@ -437,11 +385,14 @@ shell_ready_for_quit (EShell *shell,
EActivity *activity,
gboolean is_last_ref)
{
+ GtkApplication *application;
GList *list;
if (!is_last_ref)
return;
+ application = GTK_APPLICATION (shell);
+
/* Increment the reference count so we can safely emit
* a signal without triggering the toggle reference. */
g_object_ref (activity);
@@ -459,7 +410,7 @@ shell_ready_for_quit (EShell *shell,
* of the watched windows list because the act of destroying a
* watched window will modify the watched windows list, which
* would derail the iteration. */
- list = g_list_copy (e_shell_get_watched_windows (shell));
+ list = g_list_copy (gtk_application_get_windows (application));
g_list_foreach (list, (GFunc) gtk_widget_destroy, NULL);
g_list_free (list);
}
@@ -467,12 +418,15 @@ shell_ready_for_quit (EShell *shell,
static void
shell_prepare_for_quit (EShell *shell)
{
+ GtkApplication *application;
GList *list, *iter;
/* Are preparations already in progress? */
if (shell->priv->preparing_for_quit != NULL)
return;
+ application = GTK_APPLICATION (shell);
+
shell->priv->preparing_for_quit = e_activity_new ();
e_activity_set_text (
@@ -494,7 +448,7 @@ shell_prepare_for_quit (EShell *shell)
g_object_unref (shell->priv->preparing_for_quit);
/* Desensitize all watched windows to prevent user action. */
- list = e_shell_get_watched_windows (shell);
+ list = gtk_application_get_windows (application);
for (iter = list; iter != NULL; iter = iter->next)
gtk_widget_set_sensitive (GTK_WIDGET (iter->data), FALSE);
}
@@ -837,43 +791,50 @@ shell_startup (GApplication *application)
static void
shell_activate (GApplication *application)
{
- EShell *shell;
- GList *watched_windows;
+ GList *list;
/* Do not chain up. Default method just emits a warning. */
- shell = E_SHELL (application);
- watched_windows = e_shell_get_watched_windows (shell);
+ list = gtk_application_get_windows (GTK_APPLICATION (application));
/* Present the first EShellWindow, if found. */
- while (watched_windows != NULL) {
- GtkWindow *window = GTK_WINDOW (watched_windows->data);
+ while (list != NULL) {
+ GtkWindow *window = GTK_WINDOW (list->data);
if (E_IS_SHELL_WINDOW (window)) {
gtk_window_present (window);
return;
}
- watched_windows = g_list_next (watched_windows);
+ list = g_list_next (list);
}
/* No EShellWindow found, so create one. */
- e_shell_create_shell_window (shell, NULL);
+ e_shell_create_shell_window (E_SHELL (application), NULL);
}
static void
-shell_quit_mainloop (GApplication *application)
+shell_window_added (GtkApplication *application,
+ GtkWindow *window)
{
- /* XXX Don't allow GApplication to quit the main loop.
- * We'll do that ourselves until GtkApplication gets
- * a signal equivalent to EShell::window-destroyed. */
-}
+ gchar *role;
-static void
-shell_window_destroyed (EShell *shell)
-{
- if (e_shell_get_watched_windows (shell) == NULL)
- gtk_main_quit ();
+ /* Chain up to parent's window_added() method. */
+ GTK_APPLICATION_CLASS (e_shell_parent_class)->
+ window_added (application, window);
+
+ g_signal_connect (
+ window, "delete-event",
+ G_CALLBACK (shell_window_delete_event_cb), application);
+
+ /* We use the window's own type name and memory
+ * address to form a unique window role for X11. */
+ role = g_strdup_printf (
+ "%s-%" G_GINTPTR_FORMAT,
+ G_OBJECT_TYPE_NAME (window),
+ (gintptr) window);
+ gtk_window_set_role (window, role);
+ g_free (role);
}
static gboolean
@@ -893,6 +854,7 @@ e_shell_class_init (EShellClass *class)
{
GObjectClass *object_class;
GApplicationClass *application_class;
+ GtkApplicationClass *gtk_application_class;
g_type_class_add_private (class, sizeof (EShellPrivate));
@@ -906,9 +868,9 @@ e_shell_class_init (EShellClass *class)
application_class = G_APPLICATION_CLASS (class);
application_class->startup = shell_startup;
application_class->activate = shell_activate;
- application_class->quit_mainloop = shell_quit_mainloop;
- class->window_destroyed = shell_window_destroyed;
+ gtk_application_class = GTK_APPLICATION_CLASS (class);
+ gtk_application_class->window_added = shell_window_added;
/**
* EShell:express-mode
@@ -1182,38 +1144,6 @@ e_shell_class_init (EShellClass *class)
g_cclosure_marshal_VOID__ENUM,
G_TYPE_NONE, 1,
E_TYPE_SHELL_QUIT_REASON);
-
- /**
- * EShell::window-created
- * @shell: the #EShell which emitted the signal
- * @window: the newly created #GtkWindow
- *
- * Emitted when @shell begins watching a newly created window.
- **/
- signals[WINDOW_CREATED] = g_signal_new (
- "window-created",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EShellClass, window_created),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1,
- GTK_TYPE_WINDOW);
-
- /**
- * EShell::window-destroyed
- * @shell: the #EShell which emitted the signal
- *
- * Emitted when a watched is destroyed.
- **/
- signals[WINDOW_DESTROYED] = g_signal_new (
- "window-destroyed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EShellClass, window_destroyed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
}
static void
@@ -1478,9 +1408,9 @@ e_shell_get_gconf_client (EShell *shell)
* @shell: an #EShell
* @view_name: name of the initial shell view, or %NULL
*
- * Creates a new #EShellWindow and emits the #EShell::window-created
- * signal. Use this function instead of e_shell_window_new() so that
- * @shell can track the window.
+ * Creates a new #EShellWindow. Use this function instead of
+ * e_shell_window_new() so that @shell can properly configure
+ * the window.
*
* Returns: a new #EShellWindow
**/
@@ -1616,18 +1546,21 @@ void
e_shell_submit_alert (EShell *shell,
EAlert *alert)
{
+ GtkApplication *application;
GList *list, *iter;
g_return_if_fail (E_IS_SHELL (shell));
g_return_if_fail (E_IS_ALERT (alert));
+ application = GTK_APPLICATION (shell);
+
g_queue_push_tail (&shell->priv->alerts, g_object_ref (alert));
g_signal_connect_swapped (
alert, "response",
G_CALLBACK (shell_alert_response_cb), shell);
- list = e_shell_get_watched_windows (shell);
+ list = gtk_application_get_windows (application);
/* Submit the alert to all available EShellWindows. */
for (iter = list; iter != NULL; iter = g_list_next (iter))
@@ -1637,92 +1570,11 @@ e_shell_submit_alert (EShell *shell,
}
/**
- * 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;
- gchar *role;
-
- g_return_if_fail (E_IS_SHELL (shell));
- g_return_if_fail (GTK_IS_WINDOW (window));
-
- 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;
-
- list = g_list_prepend (list, window);
- shell->priv->watched_windows = list;
-
- 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. */
- role = g_strdup_printf (
- "%s-%" G_GINTPTR_FORMAT,
- G_OBJECT_TYPE_NAME (window),
- (gintptr) window);
- gtk_window_set_role (window, role);
- g_free (role);
-
- 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_get_active_window:
* @shell: an #EShell or %NULL to use the default shell
*
* Returns the most recently focused watched window, according to
- * e_shell_get_watched_windows(). Convenient for finding a parent
+ * gtk_application_get_windows(). Convenient for finding a parent
* for a transient window.
*
* Note the returned window is not necessarily an #EShellWindow.
@@ -1732,22 +1584,24 @@ e_shell_get_watched_windows (EShell *shell)
GtkWindow *
e_shell_get_active_window (EShell *shell)
{
- GList *watched_windows;
+ GtkApplication *application;
+ GList *list;
if (shell == NULL)
shell = e_shell_get_default ();
g_return_val_if_fail (E_IS_SHELL (shell), NULL);
- watched_windows = e_shell_get_watched_windows (shell);
+ application = GTK_APPLICATION (shell);
+ list = gtk_application_get_windows (application);
- if (!watched_windows)
+ if (list == NULL)
return NULL;
/* Sanity check */
- g_return_val_if_fail (GTK_IS_WINDOW (watched_windows->data), NULL);
+ g_return_val_if_fail (GTK_IS_WINDOW (list->data), NULL);
- return GTK_WINDOW (watched_windows->data);
+ return GTK_WINDOW (list->data);
}
/**
diff --git a/shell/e-shell.h b/shell/e-shell.h
index ede071e2e3..5110dd4a9c 100644
--- a/shell/e-shell.h
+++ b/shell/e-shell.h
@@ -106,9 +106,6 @@ struct _EShellClass {
EActivity *activity);
void (*quit_requested) (EShell *shell,
EShellQuitReason reason);
- void (*window_created) (EShell *shell,
- GtkWindow *window);
- void (*window_destroyed) (EShell *shell);
};
GType e_shell_get_type (void);
@@ -130,9 +127,6 @@ guint e_shell_handle_uris (EShell *shell,
gboolean do_import);
void e_shell_submit_alert (EShell *shell,
EAlert *alert);
-void e_shell_watch_window (EShell *shell,
- GtkWindow *window);
-GList * e_shell_get_watched_windows (EShell *shell);
GtkWindow * e_shell_get_active_window (EShell *shell);
gboolean e_shell_get_meego_mode (EShell *shell);
gboolean e_shell_get_express_mode (EShell *shell);
diff --git a/shell/test/e-test-shell-backend.c b/shell/test/e-test-shell-backend.c
index a30cb8a7b5..79f4aa876f 100644
--- a/shell/test/e-test-shell-backend.c
+++ b/shell/test/e-test-shell-backend.c
@@ -97,8 +97,8 @@ test_shell_backend_handle_uri_cb (EShellBackend *shell_backend,
}
static void
-test_shell_backend_window_created_cb (EShellBackend *shell_backend,
- GtkWindow *window)
+test_shell_backend_window_added_cb (EShellBackend *shell_backend,
+ GtkWindow *window)
{
const gchar *backend_name;
@@ -119,7 +119,7 @@ test_shell_backend_window_created_cb (EShellBackend *shell_backend,
}
static void
-test_shell_backend_window_destroyed_cb (EShellBackend *shell_backend)
+test_shell_backend_window_removed_cb (EShellBackend *shell_backend)
{
g_debug ("%s", G_STRFUNC);
}
@@ -139,13 +139,13 @@ test_shell_backend_constructed (GObject *object)
shell_backend);
g_signal_connect_swapped (
- shell, "window-created",
- G_CALLBACK (test_shell_backend_window_created_cb),
+ shell, "window-added",
+ G_CALLBACK (test_shell_backend_window_added_cb),
shell_backend);
g_signal_connect_swapped (
- shell, "window-destroyed",
- G_CALLBACK (test_shell_backend_window_destroyed_cb),
+ shell, "window-removed",
+ G_CALLBACK (test_shell_backend_window_removed_cb),
shell_backend);
/* Chain up to parent's constructed() method. */