aboutsummaryrefslogtreecommitdiffstats
path: root/modules/startup-wizard
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2011-06-19 11:51:42 +0800
committerRodrigo Moya <rodrigo@gnome-db.org>2011-06-30 00:42:30 +0800
commitb8fab0371da99ea001ae3f023a6b7b849c2c6f56 (patch)
tree507fd6bf1b82eb276d7e16caeb5ecc351c8a0cf2 /modules/startup-wizard
parent1ac735b14d892f848efb4c0461c071fa2d594657 (diff)
downloadgsoc2013-evolution-b8fab0371da99ea001ae3f023a6b7b849c2c6f56.tar.gz
gsoc2013-evolution-b8fab0371da99ea001ae3f023a6b7b849c2c6f56.tar.zst
gsoc2013-evolution-b8fab0371da99ea001ae3f023a6b7b849c2c6f56.zip
Allow the startup-wizard to be delayed.
This works similar to the offline and shutdown procedure in EShell. We broadcast a "load-accounts" EShell event with an EActivity. The EActivity has a toggle reference which we use as a counting semaphore. If another module needs to handle the event asynchronously, it should reference the EActivity until its async operation completes, then drop the reference. Once the signal handlers finish and only the toggle reference remains, we then proceed with the Evolution Setup Assistant. All of this is in preparation for GNOME Online Accounts integration. For the moment, nothing listens for the "load-accounts" EShell event, so there should be no change in Evolution Setup Assistant behavior.
Diffstat (limited to 'modules/startup-wizard')
-rw-r--r--modules/startup-wizard/evolution-startup-wizard.c94
1 files changed, 93 insertions, 1 deletions
diff --git a/modules/startup-wizard/evolution-startup-wizard.c b/modules/startup-wizard/evolution-startup-wizard.c
index 7917557f8d..cd2a363195 100644
--- a/modules/startup-wizard/evolution-startup-wizard.c
+++ b/modules/startup-wizard/evolution-startup-wizard.c
@@ -534,6 +534,9 @@ startup_wizard_run (EStartupWizard *extension)
const gchar *startup_view;
gboolean express_mode;
+ /* Accounts should now be loaded if there were any to load.
+ * Check, and proceed with the Evolution Setup Assistant. */
+
shell = startup_wizard_get_shell (extension);
express_mode = e_shell_get_express_mode (shell);
startup_view = e_shell_get_startup_view (shell);
@@ -560,6 +563,95 @@ startup_wizard_run (EStartupWizard *extension)
}
static void
+startup_wizard_load_accounts_done (GMainLoop *loop,
+ EActivity *activity,
+ gboolean is_last_ref)
+{
+ /* All asynchronous account loading operations should
+ * be complete now, so we can terminate the main loop. */
+ if (is_last_ref)
+ g_main_loop_quit (loop);
+}
+
+static void
+startup_wizard_load_accounts (EStartupWizard *extension)
+{
+ EShell *shell;
+ EActivity *activity;
+ GMainContext *context;
+ GMainLoop *loop;
+ GSource *source;
+
+ /* This works similar to the offline and shutdown procedure in
+ * EShell. We broadcast a "load-accounts" EShell event with an
+ * EActivity. The EActivity has a toggle reference which we use
+ * as a counting semaphore. If another module needs to handle
+ * the event asynchronously, it should reference the EActivity
+ * until its async operation completes, then drop the reference.
+ * Once the signal handlers finish and only the toggle reference
+ * remains, we then proceed with the Evolution Setup Assistant. */
+
+ shell = startup_wizard_get_shell (extension);
+
+ /* Start a temporary main loop so asynchronous account loading
+ * operations can signal completion from an idle callback. We push
+ * our own GMainContext as the thread-default so we don't trigger
+ * other GSources that have already been attached to the current
+ * thread-default context, such as the idle callback in main.c. */
+ context = g_main_context_new ();
+ loop = g_main_loop_new (context, TRUE);
+ g_main_context_push_thread_default (context);
+
+ activity = e_activity_new ();
+ e_activity_set_text (activity, _("Loading accounts..."));
+
+ /* Drop our normal (non-toggle) EActivity reference from an
+ * idle callback. If nothing else references the EActivity
+ * then it will be a very short-lived main loop. */
+ source = g_idle_source_new ();
+ g_source_set_callback (
+ source, (GSourceFunc) gtk_false,
+ activity, (GDestroyNotify) g_object_unref);
+ g_source_attach (source, context);
+ g_source_unref (source);
+
+ /* Add a toggle reference to the EActivity which,
+ * when triggered, will terminate the main loop. */
+ g_object_add_toggle_ref (
+ G_OBJECT (activity), (GToggleNotify)
+ startup_wizard_load_accounts_done, loop);
+
+ /* Broadcast the "load-accounts" event. */
+ e_shell_event (shell, "load-accounts", activity);
+
+ /* And now we wait... */
+ g_main_loop_run (loop);
+
+ /* Increment the reference count so we can safely emit
+ * a signal without triggering the toggle reference. */
+ g_object_ref (activity);
+
+ e_activity_set_state (activity, E_ACTIVITY_COMPLETED);
+
+ g_object_remove_toggle_ref (
+ G_OBJECT (activity), (GToggleNotify)
+ startup_wizard_load_accounts_done, loop);
+
+ /* Finalize the activity. */
+ g_object_unref (activity);
+
+ /* Finalize the main loop. */
+ g_main_loop_unref (loop);
+
+ /* Pop our GMainContext off the thread-default stack. */
+ g_main_context_pop_thread_default (context);
+ g_main_context_unref (context);
+
+ /* Proceed with the Evolution Setup Assistant. */
+ startup_wizard_run (extension);
+}
+
+static void
startup_wizard_dispose (GObject *object)
{
EStartupWizard *extension;
@@ -598,7 +690,7 @@ startup_wizard_constructed (GObject *object)
g_signal_connect_swapped (
shell, "event::ready-to-start",
- G_CALLBACK (startup_wizard_run), extension);
+ G_CALLBACK (startup_wizard_load_accounts), extension);
/* Chain up to parent's constructed() method. */
G_OBJECT_CLASS (e_startup_wizard_parent_class)->constructed (object);