[evolution] I#1499 - EShell: Allow override credentials prompt parent window



commit 0b5ac78d661bec864e86e7dbec427abb713407f9
Author: Milan Crha <mcrha redhat com>
Date:   Mon May 24 20:34:25 2021 +0200

    I#1499 - EShell: Allow override credentials prompt parent window
    
    And use that to set it when sending a message in a composer.
    
    Closes https://gitlab.gnome.org/GNOME/evolution/-/issues/1499

 src/mail/em-composer-utils.c | 26 ++++++++++++++++++
 src/shell/e-shell.c          | 65 +++++++++++++++++++++++++++++++++++++++++---
 src/shell/e-shell.h          |  3 ++
 3 files changed, 90 insertions(+), 4 deletions(-)
---
diff --git a/src/mail/em-composer-utils.c b/src/mail/em-composer-utils.c
index 58c95017d1..94ec241b7d 100644
--- a/src/mail/em-composer-utils.c
+++ b/src/mail/em-composer-utils.c
@@ -73,6 +73,7 @@ struct _AsyncContext {
        CamelMimeMessage *message;
        EMailSession *session;
        EMsgComposer *composer;
+       ESource *transport_source;
        EActivity *activity;
        gchar *folder_uri;
        gchar *message_uid;
@@ -113,6 +114,7 @@ async_context_free (AsyncContext *async_context)
        g_clear_object (&async_context->message);
        g_clear_object (&async_context->session);
        g_clear_object (&async_context->composer);
+       g_clear_object (&async_context->transport_source);
        g_clear_object (&async_context->activity);
 
        g_free (async_context->folder_uri);
@@ -612,6 +614,14 @@ composer_send_completed (GObject *source_object,
 
        async_context = (AsyncContext *) user_data;
 
+       if (async_context->transport_source) {
+               EShell *shell;
+
+               shell = e_msg_composer_get_shell (async_context->composer);
+
+               e_shell_set_auth_prompt_parent (shell, async_context->transport_source, NULL);
+       }
+
        activity = async_context->activity;
 
        e_mail_session_send_to_finish (
@@ -729,6 +739,7 @@ em_utils_composer_real_send (EMsgComposer *composer,
                             EMailSession *session)
 {
        AsyncContext *async_context;
+       CamelService *transport;
        GCancellable *cancellable;
        GSettings *settings;
 
@@ -765,6 +776,21 @@ em_utils_composer_real_send (EMsgComposer *composer,
        async_context->composer = g_object_ref (composer);
        async_context->activity = g_object_ref (activity);
 
+       transport = e_mail_session_ref_transport_for_message (session, message);
+
+       if (transport) {
+               EShell *shell;
+
+               shell = e_msg_composer_get_shell (composer);
+
+               async_context->transport_source = e_source_registry_ref_source (e_shell_get_registry (shell), 
camel_service_get_uid (transport));
+
+               if (async_context->transport_source)
+                       e_shell_set_auth_prompt_parent (shell, async_context->transport_source, GTK_WINDOW 
(composer));
+
+               g_object_unref (transport);
+       }
+
        cancellable = e_activity_get_cancellable (activity);
 
        e_mail_session_send_to (
diff --git a/src/shell/e-shell.c b/src/shell/e-shell.c
index 36f3078021..6df184c181 100644
--- a/src/shell/e-shell.c
+++ b/src/shell/e-shell.c
@@ -60,6 +60,8 @@ struct _EShellPrivate {
        GHashTable *backends_by_name;
        GHashTable *backends_by_scheme;
 
+       GHashTable *auth_prompt_parents;     /* gchar *ESource::uid ~> gpointer ( only remembered, not 
referenced, GtkWindow * )*/
+
        gboolean preparing_for_online;
        gpointer preparing_for_line_change;  /* weak pointer */
        gpointer preparing_for_quit;         /* weak pointer */
@@ -74,6 +76,7 @@ struct _EShellPrivate {
        gulong backend_died_handler_id;
        gulong allow_auth_prompt_handler_id;
        gulong get_dialog_parent_handler_id;
+       gulong get_dialog_parent_full_handler_id;
        gulong credentials_required_handler_id;
 
        guint auto_reconnect : 1;
@@ -1400,22 +1403,37 @@ shell_credentials_required_cb (ESourceRegistry *registry,
 }
 
 static GtkWindow *
-shell_get_dialog_parent_cb (ECredentialsPrompter *prompter,
-                           EShell *shell)
+shell_get_dialog_parent_full_cb (ECredentialsPrompter *prompter,
+                                ESource *auth_source,
+                                EShell *shell)
 {
        GList *windows, *link;
+       GtkWindow *override = NULL, *adept = NULL;
 
        g_return_val_if_fail (E_IS_SHELL (shell), NULL);
 
+       if (auth_source)
+               override = g_hash_table_lookup (shell->priv->auth_prompt_parents, e_source_get_uid 
(auth_source));
+
        windows = gtk_application_get_windows (GTK_APPLICATION (shell));
        for (link = windows; link; link = g_list_next (link)) {
                GtkWindow *window = link->data;
 
-               if (E_IS_SHELL_WINDOW (window))
+               if (!adept && E_IS_SHELL_WINDOW (window))
+                       adept = window;
+
+               if (override == window || (!override && adept))
                        return window;
        }
 
-       return NULL;
+       return adept;
+}
+
+static GtkWindow *
+shell_get_dialog_parent_cb (ECredentialsPrompter *prompter,
+                           EShell *shell)
+{
+       return shell_get_dialog_parent_full_cb (prompter, NULL, shell);
 }
 
 static void
@@ -1608,6 +1626,13 @@ shell_dispose (GObject *object)
                priv->get_dialog_parent_handler_id = 0;
        }
 
+       if (priv->get_dialog_parent_full_handler_id > 0) {
+               g_signal_handler_disconnect (
+                       priv->credentials_prompter,
+                       priv->get_dialog_parent_full_handler_id);
+               priv->get_dialog_parent_full_handler_id = 0;
+       }
+
        g_clear_object (&priv->registry);
        g_clear_object (&priv->credentials_prompter);
        g_clear_object (&priv->client_cache);
@@ -1633,6 +1658,7 @@ shell_finalize (GObject *object)
 
        g_hash_table_destroy (priv->backends_by_name);
        g_hash_table_destroy (priv->backends_by_scheme);
+       g_hash_table_destroy (priv->auth_prompt_parents);
 
        g_list_foreach (priv->loaded_backends, (GFunc) g_object_unref, NULL);
        g_list_free (priv->loaded_backends);
@@ -1794,6 +1820,10 @@ shell_initable_init (GInitable *initable,
                shell->priv->credentials_prompter, "get-dialog-parent",
                G_CALLBACK (shell_get_dialog_parent_cb), shell);
 
+       shell->priv->get_dialog_parent_full_handler_id = g_signal_connect (
+               shell->priv->credentials_prompter, "get-dialog-parent-full",
+               G_CALLBACK (shell_get_dialog_parent_full_cb), shell);
+
        handler_id = g_signal_connect (
                shell->priv->client_cache, "backend-died",
                G_CALLBACK (shell_backend_died_cb), shell);
@@ -2153,6 +2183,7 @@ e_shell_init (EShell *shell)
        shell->priv->preferences_window = e_preferences_window_new (shell);
        shell->priv->backends_by_name = backends_by_name;
        shell->priv->backends_by_scheme = backends_by_scheme;
+       shell->priv->auth_prompt_parents = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
        shell->priv->safe_mode = e_file_lock_exists ();
        shell->priv->requires_shutdown = FALSE;
 
@@ -2935,3 +2966,29 @@ e_shell_requires_shutdown (EShell *shell)
 
        return shell->priv->requires_shutdown;
 }
+
+/**
+ * e_shell_set_auth_prompt_parent:
+ * @shell: an #EShell
+ * @source: an #ESource
+ * @parent: (nullable): a #GtkWindow
+ *
+ * Sets an override for a credential prompt parent window.
+ *
+ * Since: 3.42
+ **/
+void
+e_shell_set_auth_prompt_parent (EShell *shell,
+                               ESource *source,
+                               GtkWindow *parent)
+{
+       g_return_if_fail (E_IS_SHELL (shell));
+       g_return_if_fail (E_IS_SOURCE (source));
+       g_return_if_fail (e_source_get_uid (source));
+
+       if (parent) {
+               g_hash_table_insert (shell->priv->auth_prompt_parents, g_strdup (e_source_get_uid (source)), 
parent);
+       } else {
+               g_hash_table_remove (shell->priv->auth_prompt_parents, e_source_get_uid (source));
+       }
+}
diff --git a/src/shell/e-shell.h b/src/shell/e-shell.h
index 510d627db1..66efecb35c 100644
--- a/src/shell/e-shell.h
+++ b/src/shell/e-shell.h
@@ -147,6 +147,9 @@ gboolean    e_shell_quit                    (EShell *shell,
                                                 EShellQuitReason reason);
 void           e_shell_cancel_quit             (EShell *shell);
 gboolean       e_shell_requires_shutdown       (EShell *shell);
+void           e_shell_set_auth_prompt_parent  (EShell *shell,
+                                                ESource *source,
+                                                GtkWindow *parent);
 
 G_END_DECLS
 


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