[evolution/wip/webkit2] The first part to make EHTMLEditor created asynchronously



commit 406bc5855d3e42328945e2ee234484c58d98d966
Author: Milan Crha <mcrha redhat com>
Date:   Thu Jul 7 20:13:48 2016 +0200

    The first part to make EHTMLEditor created asynchronously
    
    ...thus the EWebKitEditor has time to create and connect web_extension,
    before the changes to it are requested.
    
    More similar changes will follow, up to EMsgComposer and other usages of it.

 e-util/Makefile.am                      |    2 +
 e-util/e-content-editor.c               |   67 +++++++---
 e-util/e-content-editor.h               |   10 ++-
 e-util/e-html-editor.c                  |   83 ++++++++++--
 e-util/e-html-editor.h                  |    4 +
 e-util/e-mail-signature-editor.c        |  110 ++++++++++++++--
 e-util/e-mail-signature-editor.h        |    9 +-
 e-util/e-mail-signature-manager.c       |   62 ++++++++--
 e-util/e-simple-async-result.c          |  221 +++++++++++++++++++++++++++++++
 e-util/e-simple-async-result.h          |   90 +++++++++++++
 e-util/e-util.h                         |    1 +
 e-util/test-html-editor-units-utils.c   |   56 ++++++--
 e-util/test-html-editor.c               |   22 +++-
 mail/e-mail-config-identity-page.c      |   26 +++-
 mail/e-mail-notes.c                     |   93 +++++++++++---
 modules/webkit-editor/e-webkit-editor.c |   40 ++++++
 16 files changed, 803 insertions(+), 93 deletions(-)
---
diff --git a/e-util/Makefile.am b/e-util/Makefile.am
index 125534b..4c9db7b 100644
--- a/e-util/Makefile.am
+++ b/e-util/Makefile.am
@@ -272,6 +272,7 @@ evolution_util_include_HEADERS =  \
        e-selection-model.h \
        e-selection.h \
        e-send-options.h \
+       e-simple-async-result.h \
        e-sorter-array.h \
        e-sorter.h \
        e-source-combo-box.h \
@@ -546,6 +547,7 @@ libevolution_util_la_SOURCES = \
        e-selection-model.c \
        e-selection.c \
        e-send-options.c \
+       e-simple-async-result.c \
        e-sorter-array.c \
        e-sorter.c \
        e-source-combo-box.c \
diff --git a/e-util/e-content-editor.c b/e-util/e-content-editor.c
index 11db68f..f53b393 100644
--- a/e-util/e-content-editor.c
+++ b/e-util/e-content-editor.c
@@ -20,7 +20,6 @@
 
 #include <glib.h>
 #include <glib-object.h>
-#include <glib/gi18n-lib.h>
 
 #include <libedataserver/libedataserver.h>
 
@@ -55,7 +54,7 @@ e_content_editor_default_init (EContentEditorInterface *iface)
                iface,
                g_param_spec_boolean (
                        "can-copy",
-                       _("Can Copy"),
+                       "Can Copy",
                        NULL,
                        FALSE,
                        G_PARAM_READABLE |
@@ -71,7 +70,7 @@ e_content_editor_default_init (EContentEditorInterface *iface)
                iface,
                g_param_spec_boolean (
                        "can-cut",
-                       _("Can Cut"),
+                       "Can Cut",
                        NULL,
                        FALSE,
                        G_PARAM_READABLE |
@@ -88,7 +87,7 @@ e_content_editor_default_init (EContentEditorInterface *iface)
                iface,
                g_param_spec_boolean (
                        "can-paste",
-                       _("Can Paste"),
+                       "Can Paste",
                        NULL,
                        FALSE,
                        G_PARAM_READABLE |
@@ -104,7 +103,7 @@ e_content_editor_default_init (EContentEditorInterface *iface)
                iface,
                g_param_spec_boolean (
                        "can-redo",
-                       _("Can Redo"),
+                       "Can Redo",
                        NULL,
                        FALSE,
                        G_PARAM_READABLE |
@@ -120,7 +119,7 @@ e_content_editor_default_init (EContentEditorInterface *iface)
                iface,
                g_param_spec_boolean (
                        "can-undo",
-                       _("Can Undo"),
+                       "Can Undo",
                        NULL,
                        FALSE,
                        G_PARAM_READABLE |
@@ -135,11 +134,10 @@ e_content_editor_default_init (EContentEditorInterface *iface)
                iface,
                g_param_spec_boolean (
                        "editable",
-                       _("Editable"),
-                       _("Wheter editor is editable"),
+                       "Editable",
+                       "Wheter editor is editable",
                        TRUE,
                        G_PARAM_READWRITE |
-                       G_PARAM_CONSTRUCT |
                        G_PARAM_STATIC_STRINGS));
 
        /**
@@ -151,8 +149,8 @@ e_content_editor_default_init (EContentEditorInterface *iface)
                iface,
                g_param_spec_boolean (
                        "changed",
-                       _("Changed property"),
-                       _("Whether editor changed"),
+                       "Changed property",
+                       "Whether editor changed",
                        FALSE,
                        G_PARAM_READWRITE |
                        G_PARAM_STATIC_STRINGS));
@@ -166,11 +164,10 @@ e_content_editor_default_init (EContentEditorInterface *iface)
                iface,
                g_param_spec_boolean (
                        "html-mode",
-                       _("HTML Mode"),
-                       _("Edit HTML or plain text"),
+                       "HTML Mode",
+                       "Edit HTML or plain text",
                        TRUE,
                        G_PARAM_READWRITE |
-                       G_PARAM_CONSTRUCT |
                        G_PARAM_STATIC_STRINGS));
 
        /**
@@ -454,9 +451,9 @@ e_content_editor_default_init (EContentEditorInterface *iface)
                G_TYPE_BOOLEAN, 0);
 
        /**
-        * EContentEditor:is-ready
+        * EContentEditor:load-finished
         *
-        * Emitted when the content editor is ready.
+        * Emitted when the content editor has finished loading.
         */
        signals[LOAD_FINISHED] = g_signal_new (
                "load-finished",
@@ -1243,7 +1240,35 @@ e_content_editor_is_underline (EContentEditor *editor)
 }
 
 /**
- * e_content_editor_initialize:
+ * e_content_editor_setup_editor:
+ * @content_editor: an #EContentEditor
+ * @callback: an #EContentEditorInitializedCallback function
+ * @user_data: data to pass to @callback
+ *
+ * Initilizes the @content_editor. Once the initialization is done,
+ * the @callback is called with the passed @user_data.
+ *
+ * Since: 3.22
+ **/
+void
+e_content_editor_initialize (EContentEditor *content_editor,
+                            EContentEditorInitializedCallback callback,
+                            gpointer user_data)
+{
+       EContentEditorInterface *iface;
+
+       g_return_if_fail (E_IS_CONTENT_EDITOR (content_editor));
+       g_return_if_fail (callback != NULL);
+
+       iface = E_CONTENT_EDITOR_GET_IFACE (content_editor);
+       g_return_if_fail (iface != NULL);
+       g_return_if_fail (iface->initialize != NULL);
+
+       iface->initialize (content_editor, callback, user_data);
+}
+
+/**
+ * e_content_editor_setup_editor:
  * @content_editor: an #EContentEditor
  * @html_editor: an #EHTMLEditor
  *
@@ -1254,8 +1279,8 @@ e_content_editor_is_underline (EContentEditor *editor)
  * Since: 3.22
  **/
 void
-e_content_editor_initialize (EContentEditor *content_editor,
-                            EHTMLEditor *html_editor)
+e_content_editor_setup_editor (EContentEditor *content_editor,
+                              EHTMLEditor *html_editor)
 {
        EContentEditorInterface *iface;
 
@@ -1265,8 +1290,8 @@ e_content_editor_initialize (EContentEditor *content_editor,
        iface = E_CONTENT_EDITOR_GET_IFACE (content_editor);
        g_return_if_fail (iface != NULL);
 
-       if (iface->initialize)
-               iface->initialize (content_editor, html_editor);
+       if (iface->setup_editor)
+               iface->setup_editor (content_editor, html_editor);
 }
 
 void
diff --git a/e-util/e-content-editor.h b/e-util/e-content-editor.h
index 47dc742..93194ff 100644
--- a/e-util/e-content-editor.h
+++ b/e-util/e-content-editor.h
@@ -39,10 +39,16 @@ struct _EHTMLEditor;
 #define E_TYPE_CONTENT_EDITOR e_content_editor_get_type ()
 G_DECLARE_INTERFACE (EContentEditor, e_content_editor, E, CONTENT_EDITOR, GtkWidget)
 
+typedef void (*EContentEditorInitializedCallback)      (EContentEditor *content_editor,
+                                                        gpointer user_data);
+
 struct _EContentEditorInterface {
        GTypeInterface parent_interface;
 
        void            (*initialize)                   (EContentEditor *content_editor,
+                                                        EContentEditorInitializedCallback callback,
+                                                        gpointer user_data);
+       void            (*setup_editor)                 (EContentEditor *content_editor,
                                                         struct _EHTMLEditor *html_editor);
        void            (*update_styles)                (EContentEditor *editor);
        void            (*insert_content)               (EContentEditor *editor,
@@ -510,8 +516,10 @@ void               e_content_editor_set_underline  (EContentEditor *editor,
 gboolean       e_content_editor_is_underline   (EContentEditor *editor);
 
 /* Methods */
-
 void           e_content_editor_initialize     (EContentEditor *content_editor,
+                                                EContentEditorInitializedCallback callback,
+                                                gpointer user_data);
+void           e_content_editor_setup_editor   (EContentEditor *content_editor,
                                                 struct _EHTMLEditor *html_editor);
 void           e_content_editor_update_styles  (EContentEditor *editor);
 void           e_content_editor_insert_content (EContentEditor *editor,
diff --git a/e-util/e-html-editor.c b/e-util/e-html-editor.c
index 3af14ba..88d546c 100644
--- a/e-util/e-html-editor.c
+++ b/e-util/e-html-editor.c
@@ -34,6 +34,7 @@
 #include "e-html-editor-private.h"
 #include "e-content-editor.h"
 #include "e-misc-utils.h"
+#include "e-simple-async-result.h"
 
 #define E_HTML_EDITOR_GET_PRIVATE(obj) \
        (G_TYPE_INSTANCE_GET_PRIVATE \
@@ -592,7 +593,6 @@ static void
 html_editor_constructed (GObject *object)
 {
        EHTMLEditor *editor = E_HTML_EDITOR (object);
-       EContentEditor *cnt_editor;
        EHTMLEditorPrivate *priv = editor->priv;
        GtkWidget *widget;
        GtkToolbar *toolbar;
@@ -708,17 +708,6 @@ html_editor_constructed (GObject *object)
        priv->color_combo_box = g_object_ref (widget);
        gtk_widget_show_all (GTK_WIDGET (tool_item));
 
-       cnt_editor = e_html_editor_get_content_editor (editor);
-       e_binding_bind_property (
-               priv->color_combo_box, "current-color",
-               cnt_editor, "font-color",
-               G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
-       e_binding_bind_property (
-               cnt_editor, "editable",
-               priv->color_combo_box, "sensitive",
-               G_BINDING_SYNC_CREATE);
-       editor_actions_bind (editor);
-
        tool_item = gtk_tool_item_new ();
        widget = e_action_combo_box_new_with_action (
                GTK_RADIO_ACTION (ACTION (SIZE_PLUS_ZERO)));
@@ -909,6 +898,74 @@ e_html_editor_new (void)
        return g_object_new (E_TYPE_HTML_EDITOR, NULL);
 }
 
+static void
+e_html_editor_content_editor_initialized (EContentEditor *content_editor,
+                                         gpointer user_data)
+{
+       ESimpleAsyncResult *async_result = user_data;
+       EHTMLEditor *html_editor;
+
+       g_return_if_fail (E_IS_SIMPLE_ASYNC_RESULT (async_result));
+
+       html_editor = e_simple_async_result_get_user_data (async_result);
+       g_return_if_fail (E_IS_HTML_EDITOR (html_editor));
+       g_return_if_fail (content_editor == e_html_editor_get_content_editor (html_editor));
+
+       e_binding_bind_property (
+               html_editor->priv->color_combo_box, "current-color",
+               content_editor, "font-color",
+               G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
+       e_binding_bind_property (
+               content_editor, "editable",
+               html_editor->priv->color_combo_box, "sensitive",
+               G_BINDING_SYNC_CREATE);
+       editor_actions_bind (html_editor);
+
+       g_object_set (G_OBJECT (content_editor),
+               "halign", GTK_ALIGN_FILL,
+               "hexpand", TRUE,
+               "valign", GTK_ALIGN_FILL,
+               "vexpand", TRUE,
+               "changed", FALSE,
+               NULL);
+
+       e_simple_async_result_complete (async_result);
+
+       g_object_unref (async_result);
+}
+
+void
+e_html_editor_new_async (GAsyncReadyCallback callback,
+                        gpointer user_data)
+{
+       EHTMLEditor *html_editor;
+       EContentEditor *content_editor;
+       ESimpleAsyncResult *async_result;
+
+       g_return_if_fail (callback != NULL);
+
+       html_editor = g_object_new (E_TYPE_HTML_EDITOR, NULL);
+       async_result = e_simple_async_result_new (NULL, callback, user_data, e_html_editor_new_async);
+       e_simple_async_result_set_user_data (async_result, html_editor, g_object_unref);
+
+       content_editor = e_html_editor_get_content_editor (html_editor);
+       e_content_editor_initialize (content_editor, e_html_editor_content_editor_initialized, async_result);
+}
+
+GtkWidget *
+e_html_editor_new_finish (GAsyncResult *result,
+                         GError **error)
+{
+       ESimpleAsyncResult *eresult;
+
+       g_return_val_if_fail (E_IS_SIMPLE_ASYNC_RESULT (result), NULL);
+       g_return_val_if_fail (g_async_result_is_tagged (result, e_html_editor_new_async), NULL);
+
+       eresult = E_SIMPLE_ASYNC_RESULT (result);
+
+       return e_simple_async_result_steal_user_data (eresult);
+}
+
 /**
  * e_html_editor_get_content_editor:
  * @editor: an #EHTMLEditor
@@ -950,7 +1007,7 @@ e_html_editor_get_content_editor (EHTMLEditor *editor)
                }
 
                if (editor->priv->use_content_editor)
-                       e_content_editor_initialize (editor->priv->use_content_editor, editor);
+                       e_content_editor_setup_editor (editor->priv->use_content_editor, editor);
        }
 
        return editor->priv->use_content_editor;
diff --git a/e-util/e-html-editor.h b/e-util/e-html-editor.h
index 1546dd9..ea94dd8 100644
--- a/e-util/e-html-editor.h
+++ b/e-util/e-html-editor.h
@@ -71,6 +71,10 @@ struct _EHTMLEditorClass {
 
 GType          e_html_editor_get_type          (void) G_GNUC_CONST;
 GtkWidget *    e_html_editor_new               (void);
+void           e_html_editor_new_async         (GAsyncReadyCallback callback,
+                                                gpointer user_data);
+GtkWidget *    e_html_editor_new_finish        (GAsyncResult *result,
+                                                GError **error);
 EContentEditor *
                e_html_editor_get_content_editor
                                                (EHTMLEditor *editor);
diff --git a/e-util/e-mail-signature-editor.c b/e-util/e-mail-signature-editor.c
index 1b0d489..28ebb53 100644
--- a/e-util/e-mail-signature-editor.c
+++ b/e-util/e-mail-signature-editor.c
@@ -24,6 +24,7 @@
 #include "e-alert-dialog.h"
 #include "e-alert-sink.h"
 #include "e-alert-bar.h"
+#include "e-simple-async-result.h"
 
 #define E_MAIL_SIGNATURE_EDITOR_GET_PRIVATE(obj) \
        (G_TYPE_INSTANCE_GET_PRIVATE \
@@ -330,6 +331,16 @@ static GtkActionEntry entries[] = {
 };
 
 static void
+mail_signature_editor_set_editor (EMailSignatureEditor *editor,
+                                 EHTMLEditor *html_editor)
+{
+       g_return_if_fail (E_IS_HTML_EDITOR (html_editor));
+       g_return_if_fail (editor->priv->editor == NULL);
+
+       editor->priv->editor = g_object_ref (html_editor);
+}
+
+static void
 mail_signature_editor_set_registry (EMailSignatureEditor *editor,
                                     ESourceRegistry *registry)
 {
@@ -379,6 +390,12 @@ mail_signature_editor_set_property (GObject *object,
                                     GParamSpec *pspec)
 {
        switch (property_id) {
+               case PROP_EDITOR:
+                       mail_signature_editor_set_editor (
+                               E_MAIL_SIGNATURE_EDITOR (object),
+                               g_value_get_object (value));
+                       return;
+
                case PROP_REGISTRY:
                        mail_signature_editor_set_registry (
                                E_MAIL_SIGNATURE_EDITOR (object),
@@ -672,7 +689,8 @@ e_mail_signature_editor_class_init (EMailSignatureEditorClass *class)
                        NULL,
                        NULL,
                        E_TYPE_HTML_EDITOR,
-                       G_PARAM_READABLE |
+                       G_PARAM_READWRITE |
+                       G_PARAM_CONSTRUCT_ONLY |
                        G_PARAM_STATIC_STRINGS));
 
        g_object_class_install_property (
@@ -715,23 +733,95 @@ static void
 e_mail_signature_editor_init (EMailSignatureEditor *editor)
 {
        editor->priv = E_MAIL_SIGNATURE_EDITOR_GET_PRIVATE (editor);
+}
+
+typedef struct _CreateEditorData {
+       ESourceRegistry *registry;
+       ESource *source;
+} CreateEditorData;
+
+static void
+create_editor_data_free (gpointer ptr)
+{
+       CreateEditorData *ced = ptr;
 
-       editor->priv->editor = g_object_ref_sink (e_html_editor_new ());
+       if (ced) {
+               g_clear_object (&ced->registry);
+               g_clear_object (&ced->source);
+               g_free (ced);
+       }
 }
 
-GtkWidget *
+static void
+mail_signature_editor_html_editor_created_cb (GObject *source_object,
+                                             GAsyncResult *async_result,
+                                             gpointer user_data)
+{
+       GtkWidget *html_editor, *signature_editor;
+       ESimpleAsyncResult *eresult = user_data;
+       CreateEditorData *ced;
+       GError *error = NULL;
+
+       g_return_if_fail (E_IS_SIMPLE_ASYNC_RESULT (eresult));
+
+       ced = e_simple_async_result_get_user_data (eresult);
+       g_return_if_fail (ced != NULL);
+
+       html_editor = e_html_editor_new_finish (async_result, &error);
+       if (error) {
+               g_warning ("%s: Failed to create HTML editor: %s", G_STRFUNC, error->message);
+               g_clear_error (&error);
+       }
+
+       signature_editor = g_object_new (E_TYPE_MAIL_SIGNATURE_EDITOR,
+               "registry", ced->registry,
+               "source", ced->source,
+               "editor", html_editor,
+               NULL);
+
+       e_simple_async_result_set_op_pointer (eresult, signature_editor);
+
+       e_simple_async_result_complete (eresult);
+
+       g_object_unref (eresult);
+}
+
+void
 e_mail_signature_editor_new (ESourceRegistry *registry,
-                             ESource *source)
+                            ESource *source,
+                            GAsyncReadyCallback callback,
+                            gpointer user_data)
 {
-       g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+       ESimpleAsyncResult *eresult;
+       CreateEditorData *ced;
+
+       g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
 
        if (source != NULL)
-               g_return_val_if_fail (E_IS_SOURCE (source), NULL);
+               g_return_if_fail (E_IS_SOURCE (source));
+
+       ced = g_new0 (CreateEditorData, 1);
+       ced->registry = g_object_ref (registry);
+       ced->source = source ? g_object_ref (source) : NULL;
+
+       eresult = e_simple_async_result_new (NULL, callback, user_data, e_mail_signature_editor_new);
+       e_simple_async_result_set_user_data (eresult, ced, create_editor_data_free);
+
+       e_html_editor_new_async (mail_signature_editor_html_editor_created_cb, eresult);
+}
+
+GtkWidget *
+e_mail_signature_editor_new_finish (GAsyncResult *result,
+                                   GError **error)
+{
+       ESimpleAsyncResult *eresult;
+
+       g_return_val_if_fail (E_IS_SIMPLE_ASYNC_RESULT (result), NULL);
+       g_return_val_if_fail (g_async_result_is_tagged (result, e_mail_signature_editor_new), NULL);
+
+       eresult = E_SIMPLE_ASYNC_RESULT (result);
 
-       return g_object_new (
-               E_TYPE_MAIL_SIGNATURE_EDITOR,
-               "registry", registry,
-               "source", source, NULL);
+       return e_simple_async_result_get_op_pointer (eresult);
 }
 
 EHTMLEditor *
diff --git a/e-util/e-mail-signature-editor.h b/e-util/e-mail-signature-editor.h
index 1b8622d..5cb4b72 100644
--- a/e-util/e-mail-signature-editor.h
+++ b/e-util/e-mail-signature-editor.h
@@ -63,8 +63,13 @@ struct _EMailSignatureEditorClass {
 
 GType          e_mail_signature_editor_get_type
                                                (void) G_GNUC_CONST;
-GtkWidget *    e_mail_signature_editor_new     (ESourceRegistry *registry,
-                                                ESource *source);
+void           e_mail_signature_editor_new     (ESourceRegistry *registry,
+                                                ESource *source,
+                                                GAsyncReadyCallback callback,
+                                                gpointer user_data);
+GtkWidget *    e_mail_signature_editor_new_finish
+                                               (GAsyncResult *result,
+                                                GError **error);
 EHTMLEditor *  e_mail_signature_editor_get_editor
                                                (EMailSignatureEditor *editor);
 EFocusTracker *        e_mail_signature_editor_get_focus_tracker
diff --git a/e-util/e-mail-signature-manager.c b/e-util/e-mail-signature-manager.c
index e6d4d5d..f9a83f0 100644
--- a/e-util/e-mail-signature-manager.c
+++ b/e-util/e-mail-signature-manager.c
@@ -385,25 +385,46 @@ mail_signature_manager_constructed (GObject *object)
 }
 
 static void
-mail_signature_manager_add_signature (EMailSignatureManager *manager)
+mail_signature_manager_editor_created_add_signature_cb (GObject *source_object,
+                                                       GAsyncResult *result,
+                                                       gpointer user_data)
 {
+       EMailSignatureManager *manager = user_data;
        EHTMLEditor *editor;
        EContentEditor *cnt_editor;
-       ESourceRegistry *registry;
        GtkWidget *widget;
+       GError *error = NULL;
 
-       registry = e_mail_signature_manager_get_registry (manager);
+       g_return_if_fail (E_IS_MAIL_SIGNATURE_MANAGER (manager));
 
-       widget = e_mail_signature_editor_new (registry, NULL);
+       widget = e_mail_signature_editor_new_finish (result, &error);
+       if (error) {
+               g_warning ("%s: Failed to create signature editor: %s", G_STRFUNC, error->message);
+               g_clear_error (&error);
+               g_clear_object (&manager);
+               return;
+       }
 
-       editor = e_mail_signature_editor_get_editor (
-               E_MAIL_SIGNATURE_EDITOR (widget));
+       editor = e_mail_signature_editor_get_editor (E_MAIL_SIGNATURE_EDITOR (widget));
        cnt_editor = e_html_editor_get_content_editor (editor);
        e_content_editor_set_html_mode (cnt_editor, manager->priv->prefer_html);
 
        mail_signature_manager_emit_editor_created (manager, widget);
 
        gtk_widget_grab_focus (manager->priv->tree_view);
+
+       g_clear_object (&manager);
+}
+
+static void
+mail_signature_manager_add_signature (EMailSignatureManager *manager)
+{
+       ESourceRegistry *registry;
+
+       registry = e_mail_signature_manager_get_registry (manager);
+
+       e_mail_signature_editor_new (registry, NULL,
+               mail_signature_manager_editor_created_add_signature_cb, g_object_ref (manager));
 }
 
 static void
@@ -435,12 +456,35 @@ mail_signature_manager_editor_created (EMailSignatureManager *manager,
 }
 
 static void
+mail_signature_manager_editor_created_edit_signature_cb (GObject *source_object,
+                                                        GAsyncResult *result,
+                                                        gpointer user_data)
+{
+       EMailSignatureManager *manager = user_data;
+       GtkWidget *widget;
+       GError *error = NULL;
+
+       g_return_if_fail (E_IS_MAIL_SIGNATURE_MANAGER (manager));
+
+       widget = e_mail_signature_editor_new_finish (result, &error);
+       if (error) {
+               g_warning ("%s: Failed to create signature editor: %s", G_STRFUNC, error->message);
+               g_clear_error (&error);
+               g_clear_object (&manager);
+               return;
+       }
+
+       mail_signature_manager_emit_editor_created (manager, widget);
+
+       g_clear_object (&manager);
+}
+
+static void
 mail_signature_manager_edit_signature (EMailSignatureManager *manager)
 {
        EMailSignatureTreeView *tree_view;
        ESourceMailSignature *extension;
        ESourceRegistry *registry;
-       GtkWidget *editor;
        ESource *source;
        GFileInfo *file_info;
        GFile *file;
@@ -476,8 +520,8 @@ mail_signature_manager_edit_signature (EMailSignatureManager *manager)
        if (g_file_info_get_attribute_boolean (file_info, attribute))
                goto script;
 
-       editor = e_mail_signature_editor_new (registry, source);
-       mail_signature_manager_emit_editor_created (manager, editor);
+       e_mail_signature_editor_new (registry, source,
+               mail_signature_manager_editor_created_edit_signature_cb, g_object_ref (manager));
 
        goto exit;
 
diff --git a/e-util/e-simple-async-result.c b/e-util/e-simple-async-result.c
new file mode 100644
index 0000000..76e6cf6
--- /dev/null
+++ b/e-util/e-simple-async-result.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * 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.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gio/gio.h>
+
+#include "e-simple-async-result.h"
+
+struct _ESimpleAsyncResultPrivate {
+       GObject *source_object;
+       GAsyncReadyCallback callback;
+       gpointer callback_user_data;
+       gpointer source_tag;
+
+       gpointer user_data;
+       GDestroyNotify destroy_user_data;
+
+       gpointer op_pointer;
+};
+
+static void e_simple_async_result_iface_init (GAsyncResultIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (ESimpleAsyncResult, e_simple_async_result, G_TYPE_OBJECT,
+       G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT, e_simple_async_result_iface_init))
+
+static gpointer
+e_simple_async_result_iface_get_user_data (GAsyncResult *result)
+{
+       ESimpleAsyncResult *eresult;
+
+       g_return_val_if_fail (E_IS_SIMPLE_ASYNC_RESULT (result), NULL);
+
+       eresult = E_SIMPLE_ASYNC_RESULT (result);
+
+       return eresult->priv->callback_user_data;
+}
+
+static GObject *
+e_simple_async_result_iface_get_source_object (GAsyncResult *result)
+{
+       ESimpleAsyncResult *eresult;
+
+       g_return_val_if_fail (E_IS_SIMPLE_ASYNC_RESULT (result), NULL);
+
+       eresult = E_SIMPLE_ASYNC_RESULT (result);
+
+       return eresult->priv->source_object;
+}
+
+static gboolean
+e_simple_async_result_iface_is_tagged (GAsyncResult *result,
+                                      gpointer source_tag)
+{
+       ESimpleAsyncResult *eresult;
+
+       g_return_val_if_fail (E_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
+
+       eresult = E_SIMPLE_ASYNC_RESULT (result);
+
+       return eresult && eresult->priv->source_tag == source_tag;
+}
+
+static void
+e_simple_async_result_iface_init (GAsyncResultIface *iface)
+{
+       iface->get_user_data = e_simple_async_result_iface_get_user_data;
+       iface->get_source_object = e_simple_async_result_iface_get_source_object;
+       iface->is_tagged = e_simple_async_result_iface_is_tagged;
+}
+
+static void
+e_simple_async_result_finalize (GObject *object)
+{
+       ESimpleAsyncResult *result = E_SIMPLE_ASYNC_RESULT (object);
+
+       if (result->priv->user_data && result->priv->destroy_user_data)
+               result->priv->destroy_user_data (result->priv->user_data);
+
+       result->priv->destroy_user_data = NULL;
+       result->priv->user_data = NULL;
+
+       g_clear_object (&result->priv->source_object);
+
+       /* Chain up to parent's method */
+       G_OBJECT_CLASS (e_simple_async_result_parent_class)->finalize (object);
+}
+
+static void
+e_simple_async_result_class_init (ESimpleAsyncResultClass *class)
+{
+       GObjectClass *object_class;
+
+       g_type_class_add_private (class, sizeof (ESimpleAsyncResultPrivate));
+
+       object_class = G_OBJECT_CLASS (class);
+       object_class->finalize = e_simple_async_result_finalize;
+}
+
+static void
+e_simple_async_result_init (ESimpleAsyncResult *result)
+{
+       result->priv = G_TYPE_INSTANCE_GET_PRIVATE (result, E_TYPE_SIMPLE_ASYNC_RESULT, 
ESimpleAsyncResultPrivate);
+}
+
+ESimpleAsyncResult *
+e_simple_async_result_new (GObject *source_object,
+                          GAsyncReadyCallback callback,
+                          gpointer user_data,
+                          gpointer source_tag)
+{
+       ESimpleAsyncResult *result;
+
+       g_return_val_if_fail (callback != NULL, NULL);
+       if (source_object)
+               g_return_val_if_fail (G_IS_OBJECT (source_object), NULL);
+
+       result = g_object_new (E_TYPE_SIMPLE_ASYNC_RESULT, NULL);
+
+       result->priv->source_object = source_object ? g_object_ref (source_object) : NULL;
+       result->priv->callback = callback;
+       result->priv->callback_user_data = user_data;
+       result->priv->source_tag = source_tag;
+
+       return result;
+}
+
+void
+e_simple_async_result_set_user_data (ESimpleAsyncResult *result,
+                                    gpointer user_data,
+                                    GDestroyNotify destroy_user_data)
+{
+       ESimpleAsyncResult *eresult;
+
+       g_return_if_fail (E_IS_SIMPLE_ASYNC_RESULT (result));
+
+       eresult = E_SIMPLE_ASYNC_RESULT (result);
+
+       if (eresult->priv->user_data == user_data)
+               return;
+
+       if (eresult->priv->user_data && eresult->priv->destroy_user_data)
+               eresult->priv->destroy_user_data (eresult->priv->user_data);
+
+       eresult->priv->user_data = user_data;
+       eresult->priv->destroy_user_data = destroy_user_data;
+}
+
+gpointer
+e_simple_async_result_get_user_data (ESimpleAsyncResult *result)
+{
+       ESimpleAsyncResult *eresult;
+
+       g_return_val_if_fail (E_IS_SIMPLE_ASYNC_RESULT (result), NULL);
+
+       eresult = E_SIMPLE_ASYNC_RESULT (result);
+
+       return eresult->priv->user_data;
+}
+
+gpointer
+e_simple_async_result_steal_user_data (ESimpleAsyncResult *result)
+{
+       ESimpleAsyncResult *eresult;
+       gpointer user_data;
+
+       g_return_val_if_fail (E_IS_SIMPLE_ASYNC_RESULT (result), NULL);
+
+       eresult = E_SIMPLE_ASYNC_RESULT (result);
+
+       user_data = eresult->priv->user_data;
+
+       eresult->priv->user_data = NULL;
+       eresult->priv->destroy_user_data = NULL;
+
+       return user_data;
+}
+
+void
+e_simple_async_result_set_op_pointer (ESimpleAsyncResult *result,
+                                     gpointer ptr)
+{
+       g_return_if_fail (E_IS_SIMPLE_ASYNC_RESULT (result));
+
+       result->priv->op_pointer = ptr;
+}
+
+gpointer
+e_simple_async_result_get_op_pointer (ESimpleAsyncResult *result)
+{
+       g_return_val_if_fail (E_IS_SIMPLE_ASYNC_RESULT (result), NULL);
+
+       return result->priv->op_pointer;
+}
+
+void
+e_simple_async_result_complete (ESimpleAsyncResult *result)
+{
+       g_return_if_fail (E_IS_SIMPLE_ASYNC_RESULT (result));
+
+       g_object_ref (result);
+
+       result->priv->callback (result->priv->source_object, G_ASYNC_RESULT (result), 
result->priv->callback_user_data);
+
+       g_object_unref (result);
+}
diff --git a/e-util/e-simple-async-result.h b/e-util/e-simple-async-result.h
new file mode 100644
index 0000000..3800de1
--- /dev/null
+++ b/e-util/e-simple-async-result.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * 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.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#if !defined (__E_UTIL_H_INSIDE__) && !defined (LIBEUTIL_COMPILATION)
+#error "Only <e-util/e-util.h> should be included directly."
+#endif
+
+#ifndef E_SIMPLE_ASYNC_RESULT_H
+#define E_SIMPLE_ASYNC_RESULT_H
+
+#include <gio/gio.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SIMPLE_ASYNC_RESULT \
+       (e_simple_async_result_get_type ())
+#define E_SIMPLE_ASYNC_RESULT(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST \
+       ((obj), E_TYPE_SIMPLE_ASYNC_RESULT, ESimpleAsyncResult))
+#define E_SIMPLE_ASYNC_RESULT_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_CAST \
+       ((cls), E_TYPE_SIMPLE_ASYNC_RESULT, ESimpleAsyncResultClass))
+#define E_IS_SIMPLE_ASYNC_RESULT(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE \
+       ((obj), E_TYPE_SIMPLE_ASYNC_RESULT))
+#define E_IS_SIMPLE_ASYNC_RESULT_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_TYPE \
+       ((cls), E_TYPE_SIMPLE_ASYNC_RESULT))
+#define E_SIMPLE_ASYNC_RESULT_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS \
+       ((obj), E_TYPE_SIMPLE_ASYNC_RESULT, ESimpleAsyncResultClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ESimpleAsyncResult ESimpleAsyncResult;
+typedef struct _ESimpleAsyncResultClass ESimpleAsyncResultClass;
+typedef struct _ESimpleAsyncResultPrivate ESimpleAsyncResultPrivate;
+
+/**
+ * ESimpleAsyncResult:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
+struct _ESimpleAsyncResult {
+       GObject parent;
+
+       ESimpleAsyncResultPrivate *priv;
+};
+
+struct _ESimpleAsyncResultClass {
+       GObjectClass parent_class;
+};
+
+GType          e_simple_async_result_get_type  (void) G_GNUC_CONST;
+ESimpleAsyncResult *
+               e_simple_async_result_new       (GObject *source_object,
+                                                GAsyncReadyCallback callback,
+                                                gpointer user_data,
+                                                gpointer source_tag);
+void           e_simple_async_result_set_user_data
+                                               (ESimpleAsyncResult *result,
+                                                gpointer user_data,
+                                                GDestroyNotify destroy_user_data);
+gpointer       e_simple_async_result_get_user_data
+                                               (ESimpleAsyncResult *result);
+gpointer       e_simple_async_result_steal_user_data
+                                               (ESimpleAsyncResult *result);
+void           e_simple_async_result_set_op_pointer
+                                               (ESimpleAsyncResult *result,
+                                                gpointer ptr);
+gpointer       e_simple_async_result_get_op_pointer
+                                               (ESimpleAsyncResult *result);
+void           e_simple_async_result_complete  (ESimpleAsyncResult *result);
+
+G_END_DECLS
+
+#endif /* E_SIMPLE_ASYNC_RESULT_H */
diff --git a/e-util/e-util.h b/e-util/e-util.h
index 885f475..8b3d163 100644
--- a/e-util/e-util.h
+++ b/e-util/e-util.h
@@ -190,6 +190,7 @@
 #include <e-util/e-selection-model.h>
 #include <e-util/e-selection.h>
 #include <e-util/e-send-options.h>
+#include <e-util/e-simple-async-result.h>
 #include <e-util/e-sorter-array.h>
 #include <e-util/e-sorter.h>
 #include <e-util/e-source-combo-box.h>
diff --git a/e-util/test-html-editor-units-utils.c b/e-util/test-html-editor-units-utils.c
index b2a08d3..d8f08ea 100644
--- a/e-util/test-html-editor-units-utils.c
+++ b/e-util/test-html-editor-units-utils.c
@@ -125,20 +125,38 @@ test_utils_web_process_crashed_cb (WebKitWebView *web_view,
        return FALSE;
 }
 
-void
-test_utils_fixture_set_up (TestFixture *fixture,
-                          gconstpointer user_data)
+typedef struct _CreateData {
+       gpointer async_data;
+       TestFixture *fixture;
+} CreateData;
+
+static void
+test_utils_html_editor_created_cb (GObject *source_object,
+                                  GAsyncResult *result,
+                                  gpointer user_data)
 {
+       CreateData *create_data = user_data;
+       TestFixture *fixture;
        EContentEditor *cnt_editor;
        GSettings *settings;
-       gpointer async_data;
+       GtkWidget *html_editor;
+       GError *error = NULL;
+
+       g_return_if_fail (create_data != NULL);
+
+       fixture = create_data->fixture;
+
+       html_editor = e_html_editor_new_finish (result, &error);
+       if (error) {
+               g_warning ("%s: Failed to create editor: %s", G_STRFUNC, error->message);
+               g_clear_error (&error);
+               return;
+       }
 
        settings = e_util_ref_settings ("org.gnome.evolution.mail");
 
+       fixture->editor = E_HTML_EDITOR (html_editor);
        fixture->prompt_on_composer_mode_switch = g_settings_get_boolean (settings, 
"prompt-on-composer-mode-switch");
-       fixture->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-       fixture->editor = E_HTML_EDITOR (e_html_editor_new ());
-       fixture->undo_stack = NULL;
 
        g_object_set (G_OBJECT (fixture->editor),
                "halign", GTK_ALIGN_FILL,
@@ -163,17 +181,31 @@ test_utils_fixture_set_up (TestFixture *fixture,
                "height-request", 150,
                NULL);
 
-       async_data = test_utils_async_call_prepare ();
-
        g_signal_connect (cnt_editor, "web-process-crashed",
                G_CALLBACK (test_utils_web_process_crashed_cb), NULL);
-       g_signal_connect_swapped (cnt_editor, "notify::web-extension",
-               G_CALLBACK (test_utils_async_call_finish), async_data);
 
        gtk_window_set_focus (GTK_WINDOW (fixture->window), GTK_WIDGET (cnt_editor));
        gtk_widget_show (fixture->window);
 
-       test_utils_async_call_wait (async_data, 5);
+       test_utils_async_call_finish (create_data->async_data);
+}
+
+void
+test_utils_fixture_set_up (TestFixture *fixture,
+                          gconstpointer user_data)
+{
+       CreateData create_data;
+
+       fixture->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+       fixture->editor = E_HTML_EDITOR (e_html_editor_new ());
+       fixture->undo_stack = NULL;
+
+       create_data.async_data = test_utils_async_call_prepare ();
+       create_data.fixture = fixture;
+
+       e_html_editor_new_async (test_utils_html_editor_created_cb, &create_data);
+
+       test_utils_async_call_wait (create_data.async_data, 5);
 }
 
 void
diff --git a/e-util/test-html-editor.c b/e-util/test-html-editor.c
index 72ca1e9..ca31315 100644
--- a/e-util/test-html-editor.c
+++ b/e-util/test-html-editor.c
@@ -440,7 +440,9 @@ editor_destroyed_cb (GtkWidget *editor)
 }
 
 static void
-create_new_editor (void)
+create_new_editor_cb (GObject *source_object,
+                     GAsyncResult *result,
+                     gpointer user_data)
 {
        GtkActionGroup *action_group;
        GtkUIManager *manager;
@@ -450,9 +452,15 @@ create_new_editor (void)
        EContentEditor *cnt_editor;
        GError *error = NULL;
 
-       glob_editors++;
+       widget = e_html_editor_new_finish (result, &error);
+       if (error) {
+               g_warning ("%s: Failed to create HTML editor: %s", G_STRFUNC, error->message);
+               g_clear_error (&error);
+               editor_destroyed_cb (NULL);
+               return;
+       }
 
-       editor = E_HTML_EDITOR (e_html_editor_new ());
+       editor = E_HTML_EDITOR (widget);
        cnt_editor = e_html_editor_get_content_editor (editor);
 
        g_object_set (G_OBJECT (editor),
@@ -541,6 +549,14 @@ create_new_editor (void)
        gtk_ui_manager_ensure_update (manager);
 }
 
+static void
+create_new_editor (void)
+{
+       glob_editors++;
+
+       e_html_editor_new_async (create_new_editor_cb, NULL);
+}
+
 gint
 main (gint argc,
       gchar **argv)
diff --git a/mail/e-mail-config-identity-page.c b/mail/e-mail-config-identity-page.c
index 8b1a8fe..5baa5f5 100644
--- a/mail/e-mail-config-identity-page.c
+++ b/mail/e-mail-config-identity-page.c
@@ -80,17 +80,35 @@ mail_config_identity_page_is_email (const gchar *email_address)
 }
 
 static void
+mail_config_identity_page_signature_editor_created_cb (GObject *source_object,
+                                                      GAsyncResult *result,
+                                                      gpointer user_data)
+{
+       GtkWidget *editor;
+       GError *error = NULL;
+
+       g_return_if_fail (result != NULL);
+
+       editor = e_mail_signature_editor_new_finish (result, &error);
+       if (error) {
+               g_warning ("%s: Failed to create signature editor: %s", G_STRFUNC, error->message);
+               g_clear_error (&error);
+       } else {
+               gtk_window_set_position (GTK_WINDOW (editor), GTK_WIN_POS_CENTER);
+               gtk_widget_show (editor);
+       }
+}
+
+static void
 mail_config_identity_page_add_signature_cb (GtkButton *button,
                                             EMailConfigIdentityPage *page)
 {
        ESourceRegistry *registry;
-       GtkWidget *editor;
 
        registry = e_mail_config_identity_page_get_registry (page);
 
-       editor = e_mail_signature_editor_new (registry, NULL);
-       gtk_window_set_position (GTK_WINDOW (editor), GTK_WIN_POS_CENTER);
-       gtk_widget_show (editor);
+       e_mail_signature_editor_new (registry, NULL,
+               mail_config_identity_page_signature_editor_created_cb, NULL);
 }
 
 static void
diff --git a/mail/e-mail-notes.c b/mail/e-mail-notes.c
index 0119edf..9a60246 100644
--- a/mail/e-mail-notes.c
+++ b/mail/e-mail-notes.c
@@ -901,9 +901,10 @@ e_mail_notes_editor_init (EMailNotesEditor *notes_editor)
 }
 
 static EMailNotesEditor *
-e_mail_notes_editor_new (GtkWindow *parent,
-                        CamelFolder *folder,
-                        const gchar *uid)
+e_mail_notes_editor_new_with_editor (EHTMLEditor *html_editor,
+                                    GtkWindow *parent,
+                                    CamelFolder *folder,
+                                    const gchar *uid)
 {
        const gchar *ui =
                "<ui>\n"
@@ -975,9 +976,9 @@ e_mail_notes_editor_new (GtkWindow *parent,
 
        content = widget;
 
-       widget = e_html_editor_new ();
+       widget = GTK_WIDGET (html_editor);
 
-       notes_editor->editor = E_HTML_EDITOR (widget);
+       notes_editor->editor = html_editor;
        cnt_editor = e_html_editor_get_content_editor (notes_editor->editor);
        ui_manager = e_html_editor_get_ui_manager (notes_editor->editor);
 
@@ -1014,6 +1015,12 @@ e_mail_notes_editor_new (GtkWindow *parent,
        gtk_widget_show (widget);
 
        widget = GTK_WIDGET (notes_editor->editor);
+       g_object_set (G_OBJECT (widget),
+               "halign", GTK_ALIGN_FILL,
+               "hexpand", TRUE,
+               "valign", GTK_ALIGN_FILL,
+               "vexpand", TRUE,
+               NULL);
        gtk_box_pack_start (GTK_BOX (content), widget, TRUE, TRUE, 0);
        gtk_widget_show (widget);
 
@@ -1067,29 +1074,79 @@ e_mail_notes_editor_new (GtkWindow *parent,
        return notes_editor;
 }
 
+typedef struct _AsyncData {
+       GtkWindow *parent;
+       CamelFolder *folder;
+       gchar *uid;
+} AsyncData;
+
+static void
+async_data_free (gpointer ptr)
+{
+       AsyncData *ad = ptr;
+
+       if (ad) {
+               g_clear_object (&ad->parent);
+               g_clear_object (&ad->folder);
+               g_free (ad->uid);
+               g_free (ad);
+       }
+}
+
+static void
+e_mail_notes_editor_ready_cb (GObject *source_object,
+                             GAsyncResult *result,
+                             gpointer user_data)
+{
+       AsyncData *ad = user_data;
+       GtkWidget *html_editor;
+       GError *error = NULL;
+
+       g_return_if_fail (result != NULL);
+       g_return_if_fail (ad != NULL);
+
+       html_editor = e_html_editor_new_finish (result, &error);
+       if (error) {
+               g_warning ("%s: Failed to create HTML editor: %s", G_STRFUNC, error->message);
+               g_clear_error (&error);
+       } else {
+               EMailNotesEditor *notes_editor;
+               EActivityBar *activity_bar;
+               EActivity *activity;
+
+               notes_editor = e_mail_notes_editor_new_with_editor (E_HTML_EDITOR (html_editor),
+                       ad->parent, ad->folder, ad->uid);
+
+               activity_bar = e_html_editor_get_activity_bar (notes_editor->editor);
+               activity = e_alert_sink_submit_thread_job (E_ALERT_SINK (notes_editor->editor),
+                       _("Retrieving message..."), "mail:no-retrieve-message", NULL,
+                       e_mail_notes_retrieve_message_thread,
+                       g_object_ref (notes_editor), e_mail_notes_retrieve_message_done);
+               e_activity_bar_set_activity (activity_bar, activity);
+               g_clear_object (&activity);
+
+               gtk_widget_show (GTK_WIDGET (notes_editor));
+       }
+
+       async_data_free (ad);
+}
+
 void
 e_mail_notes_edit (GtkWindow *parent,
                   CamelFolder *folder,
                   const gchar *uid)
 {
-       EMailNotesEditor *notes_editor;
-       EActivityBar *activity_bar;
-       EActivity *activity;
+       AsyncData *ad;
 
        g_return_if_fail (CAMEL_IS_FOLDER (folder));
        g_return_if_fail (uid != NULL);
 
-       notes_editor = e_mail_notes_editor_new (parent, folder, uid);
-
-       activity_bar = e_html_editor_get_activity_bar (notes_editor->editor);
-       activity = e_alert_sink_submit_thread_job (E_ALERT_SINK (notes_editor->editor),
-               _("Retrieving message..."), "mail:no-retrieve-message", NULL,
-               e_mail_notes_retrieve_message_thread,
-               g_object_ref (notes_editor), e_mail_notes_retrieve_message_done);
-       e_activity_bar_set_activity (activity_bar, activity);
-       g_clear_object (&activity);
+       ad = g_new0 (AsyncData, 1);
+       ad->parent = parent ? g_object_ref (parent) : NULL;
+       ad->folder = g_object_ref (folder);
+       ad->uid = g_strdup (uid);
 
-       gtk_widget_show (GTK_WIDGET (notes_editor));
+       e_html_editor_new_async (e_mail_notes_editor_ready_cb, ad);
 }
 
 gboolean
diff --git a/modules/webkit-editor/e-webkit-editor.c b/modules/webkit-editor/e-webkit-editor.c
index 8058cef..c049a93 100644
--- a/modules/webkit-editor/e-webkit-editor.c
+++ b/modules/webkit-editor/e-webkit-editor.c
@@ -65,6 +65,9 @@ enum {
 };
 
 struct _EWebKitEditorPrivate {
+       EContentEditorInitializedCallback initialized_callback;
+       gpointer initialized_user_data;
+
        GDBusProxy *web_extension;
        guint web_extension_watch_name_id;
        guint web_extension_selection_changed_cb_id;
@@ -470,6 +473,13 @@ web_extension_proxy_created_cb (GDBusProxy *proxy,
                g_warning ("Error creating web extension proxy: %s\n", error->message);
                g_error_free (error);
 
+               if (wk_editor->priv->initialized_callback) {
+                       wk_editor->priv->initialized_callback (E_CONTENT_EDITOR (wk_editor), 
wk_editor->priv->initialized_user_data);
+
+                       wk_editor->priv->initialized_callback = NULL;
+                       wk_editor->priv->initialized_user_data = NULL;
+               }
+
                return;
        }
 
@@ -527,6 +537,13 @@ web_extension_proxy_created_cb (GDBusProxy *proxy,
        }
 
        g_object_notify (G_OBJECT (wk_editor), "web-extension");
+
+       if (wk_editor->priv->initialized_callback) {
+               wk_editor->priv->initialized_callback (E_CONTENT_EDITOR (wk_editor), 
wk_editor->priv->initialized_user_data);
+
+               wk_editor->priv->initialized_callback = NULL;
+               wk_editor->priv->initialized_user_data = NULL;
+       }
 }
 
 static void
@@ -767,6 +784,28 @@ webkit_editor_show_inspector (EWebKitEditor *wk_editor)
 }
 
 static void
+webkit_editor_initialize (EContentEditor *content_editor,
+                         EContentEditorInitializedCallback callback,
+                         gpointer user_data)
+{
+       EWebKitEditor *wk_editor;
+
+       g_return_if_fail (E_IS_WEBKIT_EDITOR (content_editor));
+       g_return_if_fail (callback != NULL);
+
+       wk_editor = E_WEBKIT_EDITOR (content_editor);
+
+       if (wk_editor->priv->web_extension) {
+               callback (content_editor, user_data);
+       } else {
+               g_return_if_fail (wk_editor->priv->initialized_callback == NULL);
+
+               wk_editor->priv->initialized_callback = callback;
+               wk_editor->priv->initialized_user_data = user_data;
+       }
+}
+
+static void
 webkit_editor_update_styles (EContentEditor *editor)
 {
        EWebKitEditor *wk_editor;
@@ -6021,6 +6060,7 @@ e_webkit_editor_init (EWebKitEditor *wk_editor)
 static void
 e_webkit_editor_content_editor_init (EContentEditorInterface *iface)
 {
+       iface->initialize = webkit_editor_initialize;
        iface->update_styles = webkit_editor_update_styles;
        iface->insert_content = webkit_editor_insert_content;
        iface->get_content = webkit_editor_get_content;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]