[epiphany/mcatanzaro/#1733: 2/4] Fix double download destination prompt when saving images/pages




commit 2e9eb58e4b7db7e089d3c9775ce519c3207d8ac0
Author: Michael Catanzaro <mcatanzaro redhat com>
Date:   Tue Apr 5 13:33:42 2022 -0500

    Fix double download destination prompt when saving images/pages
    
    When the "ask on download" setting is enabled, we currently show both
    the normal download destination confirmation dialog and also the save
    file chooser displayed by the context menu implementation, so the user
    selects the download location twice. Oops. To avoid this, let's convert
    EphyDownload to only display its confirmation dialog if the
    filename-suggested signal handler does not set a destination. Then,
    the context menu implementation can use a GMainLoop to spin the default
    main context until the user has finished interacting with the native
    file chooser, so that it has time to set the download destination before
    returning from the save dialog.
    
    Fixes #1748

 embed/ephy-download.c | 28 ++++++++++++++++++----------
 src/popup-commands.c  | 11 +++++++++++
 2 files changed, 29 insertions(+), 10 deletions(-)
---
diff --git a/embed/ephy-download.c b/embed/ephy-download.c
index cb03f3828..18631a4e9 100644
--- a/embed/ephy-download.c
+++ b/embed/ephy-download.c
@@ -74,6 +74,8 @@ enum {
 
 static guint signals[LAST_SIGNAL];
 
+static gboolean run_download_confirmation_dialog (EphyDownload *download, const char *suggested_filename);
+
 static void
 ephy_download_get_property (GObject    *object,
                             guint       property_id,
@@ -613,9 +615,16 @@ download_decide_destination_cb (WebKitDownload *wk_download,
 
   g_signal_emit (download, signals[FILENAME_SUGGESTED], 0, suggested_filename);
 
+  /* If the signal handler provided a destination, then don't show the
+   * confirmation dialog.
+   */
   if (webkit_download_get_destination (wk_download))
     return TRUE;
 
+  if (!ephy_is_running_inside_sandbox () &&
+      g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_ASK_ON_DOWNLOAD))
+    return run_download_confirmation_dialog (download, suggested_filename);
+
   return set_destination_uri_for_suggested_filename (download, suggested_filename);
 }
 
@@ -753,6 +762,7 @@ typedef struct {
   GFile *directory;
   GtkLabel *directory_label;
   GMainLoop *nested_loop;
+  gboolean result;
 } SuggestedFilenameData;
 
 static void
@@ -773,8 +783,10 @@ filename_suggested_dialog_cb (GtkDialog             *dialog,
                                          data->download);
 
     g_settings_set_string (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_LAST_DOWNLOAD_DIRECTORY, folder_path);
+    data->result = TRUE;
   } else {
     ephy_download_cancel (data->download);
+    data->result = FALSE;
   }
 
   gtk_widget_destroy (GTK_WIDGET (dialog));
@@ -822,10 +834,9 @@ filename_suggested_button_cb (GtkButton             *button,
   gtk_native_dialog_show (GTK_NATIVE_DIALOG (chooser));
 }
 
-static void
-filename_suggested_cb (EphyDownload *download,
-                       const char   *suggested_filename,
-                       gpointer      user_data)
+static gboolean
+run_download_confirmation_dialog (EphyDownload *download,
+                                  const char   *suggested_filename)
 {
   GApplication *application;
   GtkWidget *dialog = NULL;
@@ -916,6 +927,7 @@ filename_suggested_cb (EphyDownload *download,
     data.directory = g_file_new_for_path (directory_path);
   data.directory_label = GTK_LABEL (button_label);
   data.nested_loop = g_main_loop_new (NULL, FALSE);
+  data.result = FALSE;
 
   display_name = ephy_file_get_display_name (data.directory);
   gtk_label_set_label (data.directory_label, display_name);
@@ -941,6 +953,8 @@ filename_suggested_cb (EphyDownload *download,
   g_main_loop_unref (data.nested_loop);
   g_object_unref (data.directory);
   g_free (data.suggested_filename);
+
+  return data.result;
 }
 
 EphyDownload *
@@ -990,12 +1004,6 @@ ephy_download_new (WebKitDownload *download)
                            G_CALLBACK (download_decide_destination_cb),
                            ephy_download, 0);
 
-  if (!ephy_is_running_inside_sandbox () && g_settings_get_boolean (EPHY_SETTINGS_WEB, 
EPHY_PREFS_WEB_ASK_ON_DOWNLOAD)) {
-    g_signal_connect (ephy_download, "filename-suggested",
-                      G_CALLBACK (filename_suggested_cb),
-                      NULL);
-  }
-
   return ephy_download;
 }
 
diff --git a/src/popup-commands.c b/src/popup-commands.c
index 516f9c5c0..f316af8fa 100644
--- a/src/popup-commands.c
+++ b/src/popup-commands.c
@@ -147,6 +147,7 @@ typedef struct {
   char *title;
   EphyWindow *window;
   EphyDownload *download;
+  GMainLoop *nested_loop;
 } SavePropertyURLData;
 
 static void
@@ -185,9 +186,12 @@ filename_confirmed_cb (GtkFileChooser      *dialog,
                      g_object_unref);
   }
 
+  g_main_loop_quit (data->nested_loop);
+
   g_free (data->title);
   g_object_unref (data->window);
   g_object_unref (data->download);
+  g_main_loop_unref (data->nested_loop);
   g_free (data);
 }
 
@@ -226,6 +230,12 @@ filename_suggested_cb (EphyDownload        *download,
   g_signal_connect (dialog, "response",
                     G_CALLBACK (filename_confirmed_cb), data);
   gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog));
+
+  /* We have to set a download destination before this signal handler completes,
+   * so we'll spin the default main context until the dialog is finished.
+   * https://bugs.webkit.org/show_bug.cgi?id=238748
+   */
+  g_main_loop_run (data->nested_loop);
 }
 
 static void
@@ -247,6 +257,7 @@ save_property_url (const char *title,
   data->title = g_strdup (title);
   data->window = g_object_ref (window);
   data->download = download;
+  data->nested_loop = g_main_loop_new (NULL, FALSE);
   g_signal_connect (download, "filename-suggested",
                     G_CALLBACK (filename_suggested_cb),
                     data);


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