[epiphany] Run downloads in background if window is closed



commit e0363898fd4752f967f8d565bdc9e20fbf626b1f
Author: Jan-Michael Brummer <jan brummer tabos org>
Date:   Sun May 12 12:00:02 2019 +0200

    Run downloads in background if window is closed
    
    Fixes: https://gitlab.gnome.org/GNOME/epiphany/issues/322

 embed/ephy-downloads-manager.c |  8 +++++
 src/ephy-action-bar-end.c      | 11 +++++++
 src/ephy-shell.c               | 47 +++++++++++++++++++++++++++
 src/ephy-shell.h               |  4 +++
 src/ephy-window.c              | 72 ++++++++++++++++++++++++++++++------------
 5 files changed, 121 insertions(+), 21 deletions(-)
---
diff --git a/embed/ephy-downloads-manager.c b/embed/ephy-downloads-manager.c
index c40af0242..b9e4675e3 100644
--- a/embed/ephy-downloads-manager.c
+++ b/embed/ephy-downloads-manager.c
@@ -29,6 +29,7 @@ enum {
   DOWNLOAD_REMOVED,
 
   ESTIMATED_PROGRESS_CHANGED,
+  SHOW_DOWNLOADS,
 
   LAST_SIGNAL
 };
@@ -131,6 +132,13 @@ ephy_downloads_manager_class_init (EphyDownloadsManagerClass *klass)
                   G_SIGNAL_RUN_LAST,
                   0, NULL, NULL, NULL,
                   G_TYPE_NONE, 0);
+
+  signals[SHOW_DOWNLOADS] =
+    g_signal_new ("show-downloads",
+                  EPHY_TYPE_DOWNLOADS_MANAGER,
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL, NULL,
+                  G_TYPE_NONE, 0);
 }
 
 static void
diff --git a/src/ephy-action-bar-end.c b/src/ephy-action-bar-end.c
index 497b83c40..d02498c2f 100644
--- a/src/ephy-action-bar-end.c
+++ b/src/ephy-action-bar-end.c
@@ -211,6 +211,14 @@ downloads_estimated_progress_cb (EphyDownloadsManager *manager,
   gtk_widget_queue_draw (gtk_button_get_image (GTK_BUTTON (action_bar_end->downloads_button)));
 }
 
+static void
+show_downloads_cb (EphyDownloadsManager *manager,
+                   EphyActionBarEnd     *action_bar_end)
+{
+  if (gtk_widget_get_mapped (GTK_WIDGET (action_bar_end)))
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (action_bar_end->downloads_button), TRUE);
+}
+
 static void
 ephy_action_bar_end_class_init (EphyActionBarEndClass *klass)
 {
@@ -274,6 +282,9 @@ ephy_action_bar_end_init (EphyActionBarEnd *action_bar_end)
   g_signal_connect_object (downloads_manager, "estimated-progress-changed",
                            G_CALLBACK (downloads_estimated_progress_cb),
                            object, 0);
+  g_signal_connect_object (downloads_manager, "show-downloads",
+                           G_CALLBACK (show_downloads_cb),
+                           object, 0);
 }
 
 EphyActionBarEnd *
diff --git a/src/ephy-shell.c b/src/ephy-shell.c
index 2917371e8..9dfe26758 100644
--- a/src/ephy-shell.c
+++ b/src/ephy-shell.c
@@ -63,6 +63,8 @@ struct _EphyShell {
   EphyShellStartupContext *local_startup_context;
   EphyShellStartupContext *remote_startup_context;
   GSList *open_uris_idle_ids;
+
+  gchar *open_notification_id;
 };
 
 static EphyShell *ephy_shell = NULL;
@@ -244,6 +246,22 @@ quit_application (GSimpleAction *action,
   window_cmd_quit (NULL, NULL, NULL);
 }
 
+static void
+show_downloads (GSimpleAction *action,
+                GVariant      *parameter,
+                gpointer       user_data)
+{
+  GtkWindow *window;
+  EphyDownloadsManager *manager = ephy_embed_shell_get_downloads_manager (EPHY_EMBED_SHELL 
(ephy_shell_get_default ()));
+
+  window = gtk_application_get_active_window (GTK_APPLICATION (ephy_shell));
+  g_application_withdraw_notification (G_APPLICATION (ephy_shell), ephy_shell->open_notification_id);
+  g_clear_pointer (&ephy_shell->open_notification_id, g_free);
+
+  gtk_widget_show (GTK_WIDGET (window));
+  g_signal_emit_by_name (manager, "show-downloads", NULL);
+}
+
 static GActionEntry app_entries[] = {
   { "new-window", new_window, NULL, NULL, NULL },
   { "new-incognito", new_incognito_window, NULL, NULL, NULL },
@@ -255,6 +273,7 @@ static GActionEntry app_entries[] = {
   { "help", show_help, NULL, NULL, NULL },
   { "about", show_about, NULL, NULL, NULL },
   { "quit", quit_application, NULL, NULL, NULL },
+  { "show-downloads", show_downloads, NULL, NULL, NULL },
 };
 
 static GActionEntry non_incognito_extra_app_entries[] = {
@@ -457,6 +476,11 @@ ephy_shell_activate (GApplication *application)
     g_signal_connect (web_context, "automation-started", G_CALLBACK (automation_started_cb), shell);
   }
 
+  if (shell->open_notification_id) {
+    g_application_withdraw_notification (G_APPLICATION (shell), shell->open_notification_id);
+    g_clear_pointer (&shell->open_notification_id, g_free);
+  }
+
   if (shell->remote_startup_context == NULL) {
     EphySession *session = ephy_shell_get_session (shell);
 
@@ -689,6 +713,11 @@ ephy_shell_dispose (GObject *object)
   g_clear_object (&shell->history_manager);
   g_clear_object (&shell->open_tabs_manager);
 
+  if (shell->open_notification_id) {
+    g_application_withdraw_notification (G_APPLICATION (shell), shell->open_notification_id);
+    g_clear_pointer (&shell->open_notification_id, g_free);
+  }
+
   g_slist_free_full (shell->open_uris_idle_ids, remove_open_uris_idle_cb);
   shell->open_uris_idle_ids = NULL;
 
@@ -1057,6 +1086,11 @@ ephy_shell_close_all_windows (EphyShell *shell)
       retval = FALSE;
   }
 
+  if (shell->open_notification_id) {
+    g_application_withdraw_notification (G_APPLICATION (shell), shell->open_notification_id);
+    g_clear_pointer (&shell->open_notification_id, g_free);
+  }
+
   return retval;
 }
 
@@ -1210,3 +1244,16 @@ ephy_shell_open_uris (EphyShell        *shell,
   shell->open_uris_idle_ids = g_slist_prepend (shell->open_uris_idle_ids, GUINT_TO_POINTER (id));
 }
 
+void
+ephy_shell_send_notification (EphyShell     *shell,
+                              gchar         *id,
+                              GNotification *notification)
+{
+  if (ephy_shell->open_notification_id) {
+    g_application_withdraw_notification (G_APPLICATION (ephy_shell), ephy_shell->open_notification_id);
+    g_clear_pointer (&ephy_shell->open_notification_id, g_free);
+  }
+
+  shell->open_notification_id = g_strdup (id);
+  g_application_send_notification (G_APPLICATION (shell), id, notification);
+}
diff --git a/src/ephy-shell.h b/src/ephy-shell.h
index b6c1b28f6..63366bc96 100644
--- a/src/ephy-shell.h
+++ b/src/ephy-shell.h
@@ -123,4 +123,8 @@ EphyShellStartupContext *ephy_shell_startup_context_new   (EphyStartupMode
 
 void                     _ephy_shell_create_instance      (EphyEmbedShellMode mode);
 
+void                     ephy_shell_send_notification     (EphyShell        *shell,
+                                                           gchar            *id,
+                                                           GNotification    *notification);
+
 G_END_DECLS
diff --git a/src/ephy-window.c b/src/ephy-window.c
index 423d55e3d..0877a3881 100644
--- a/src/ephy-window.c
+++ b/src/ephy-window.c
@@ -273,23 +273,6 @@ confirm_close_with_modified_forms (EphyWindow *window)
   return response == GTK_RESPONSE_ACCEPT;
 }
 
-static gboolean
-confirm_close_with_downloads (EphyWindow *window)
-{
-  GtkWidget *dialog;
-  int response;
-
-  dialog = construct_confirm_close_dialog (window,
-                                           _("There are ongoing downloads."),
-                                           _("If you quit, the downloads will be cancelled"),
-                                           _("Quit and cancel downloads"));
-  response = gtk_dialog_run (GTK_DIALOG (dialog));
-
-  gtk_widget_destroy (dialog);
-
-  return response == GTK_RESPONSE_ACCEPT;
-}
-
 static gboolean
 confirm_close_with_multiple_tabs (EphyWindow *window)
 {
@@ -2859,6 +2842,27 @@ tab_has_modified_forms_timeout_cb (TabHasModifiedFormsData *data)
   return G_SOURCE_REMOVE;
 }
 
+static void
+run_downloads_in_background (EphyWindow *window,
+                             int         num)
+{
+  g_autoptr(GNotification) notification = NULL;
+  g_autofree char *body = NULL;
+
+  notification = g_notification_new (_("Download operation"));
+  g_notification_set_default_action (notification, "app.show-downloads");
+  g_notification_add_button (notification, _("Show details"), "app.show-downloads");
+
+  body = g_strdup_printf (ngettext ("%d download operation active",
+                                    "%d download operations active",
+                                    num), num);
+  g_notification_set_body (notification, body);
+
+  ephy_shell_send_notification (ephy_shell_get_default (), "progress", notification);
+
+  gtk_widget_hide (GTK_WIDGET (window));
+}
+
 static void
 notebook_page_close_request_cb (EphyNotebook *notebook,
                                 EphyEmbed    *embed,
@@ -2879,9 +2883,11 @@ notebook_page_close_request_cb (EphyNotebook *notebook,
     if (ephy_shell_get_n_windows (ephy_shell_get_default ()) == 1) {
       EphyDownloadsManager *manager = ephy_embed_shell_get_downloads_manager (EPHY_EMBED_SHELL 
(ephy_shell_get_default ()));
 
-      if (ephy_downloads_manager_has_active_downloads (manager) &&
-          !confirm_close_with_downloads (window))
+      if (ephy_downloads_manager_has_active_downloads (manager)) {
+        GList *list = ephy_downloads_manager_get_downloads (manager);
+        run_downloads_in_background (window, g_list_length (list));
         return;
+      }
     }
   }
 
@@ -3510,6 +3516,24 @@ is_browser_default (void)
   return FALSE;
 }
 
+static void
+download_completed_cb (EphyDownload *download,
+                       gpointer      user_data)
+{
+  EphyShell *shell = ephy_shell_get_default ();
+  GtkWindow *window;
+
+  if (ephy_shell_get_n_windows (shell) != 1)
+    return;
+
+  window = gtk_application_get_active_window (GTK_APPLICATION (shell));
+  if (gtk_widget_is_visible (GTK_WIDGET (window)))
+    return;
+
+  if (ephy_shell_close_all_windows (shell))
+    g_application_quit (G_APPLICATION (shell));
+}
+
 static void
 ephy_window_constructed (GObject *object)
 {
@@ -3722,6 +3746,7 @@ ephy_window_class_init (EphyWindowClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+  EphyDownloadsManager *manager;
 
   object_class->constructed = ephy_window_constructed;
   object_class->dispose = ephy_window_dispose;
@@ -3753,6 +3778,9 @@ ephy_window_class_init (EphyWindowClass *klass)
                                                        EPHY_WINDOW_CHROME_DEFAULT,
                                                        G_PARAM_READWRITE |
                                                        G_PARAM_STATIC_STRINGS));
+
+  manager = ephy_embed_shell_get_downloads_manager (EPHY_EMBED_SHELL (ephy_shell_get_default ()));
+  g_signal_connect (manager, "download-completed", G_CALLBACK (download_completed_cb), NULL);
 }
 
 static void
@@ -4158,8 +4186,10 @@ ephy_window_close (EphyWindow *window)
     EphyDownloadsManager *manager = ephy_embed_shell_get_downloads_manager (EPHY_EMBED_SHELL 
(ephy_shell_get_default ()));
     EphySession *session;
 
-    if (ephy_downloads_manager_has_active_downloads (manager) &&
-        !confirm_close_with_downloads (window)) {
+    if (ephy_downloads_manager_has_active_downloads (manager)) {
+      GList *list = ephy_downloads_manager_get_downloads (manager);
+      run_downloads_in_background (window, g_list_length (list));
+
       /* stop window close */
       return FALSE;
     }


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