[epiphany] Add run in background option for webapp



commit 178a460f02a479e0b6f5147aba46c6b0dd1b7b35
Author: Jan-Michael Brummer <jan brummer tabos org>
Date:   Mon Jun 1 00:39:32 2020 +0200

    Add run in background option for webapp
    
    Fixes: https://gitlab.gnome.org/GNOME/epiphany/-/issues/673

 data/org.gnome.epiphany.gschema.xml    |  5 +++
 lib/ephy-prefs.h                       |  7 ++--
 src/ephy-header-bar.c                  |  5 +++
 src/ephy-shell.c                       | 65 +++++++++++++++++++++++++++++-----
 src/ephy-window.c                      |  5 +++
 src/resources/gtk/page-menu-popover.ui | 19 ++++++++++
 6 files changed, 95 insertions(+), 11 deletions(-)
---
diff --git a/data/org.gnome.epiphany.gschema.xml b/data/org.gnome.epiphany.gschema.xml
index b04ce5687..d719b29af 100644
--- a/data/org.gnome.epiphany.gschema.xml
+++ b/data/org.gnome.epiphany.gschema.xml
@@ -247,6 +247,11 @@
                        <summary>WebApp is mobile capable</summary>
                        <description>Whether to show buttons for navigation.</description>
                </key>
+               <key type="b" name="run-in-background">
+                       <default>false</default>
+                       <summary>Hide window on quit</summary>
+                       <description>If enabled, application window is hidden when closing 
window.</description>
+               </key>
        </schema>
        <schema id="org.gnome.Epiphany.state">
                <key type="s" name="download-dir">
diff --git a/lib/ephy-prefs.h b/lib/ephy-prefs.h
index e1abcfd10..ac0a87682 100644
--- a/lib/ephy-prefs.h
+++ b/lib/ephy-prefs.h
@@ -197,9 +197,10 @@ static const char * const ephy_prefs_web_schema[] = {
 #define EPHY_PREFS_SYNC_OPEN_TABS_ENABLED "sync-open-tabs-enabled"
 #define EPHY_PREFS_SYNC_OPEN_TABS_TIME    "sync-open-tabs-time"
 
-#define EPHY_PREFS_WEB_APP_SCHEMA          "org.gnome.Epiphany.webapp"
-#define EPHY_PREFS_WEB_APP_ADDITIONAL_URLS "additional-urls"
-#define EPHY_PREFS_WEB_APP_MOBILE_CAPABLE  "mobile-capable"
+#define EPHY_PREFS_WEB_APP_SCHEMA            "org.gnome.Epiphany.webapp"
+#define EPHY_PREFS_WEB_APP_ADDITIONAL_URLS   "additional-urls"
+#define EPHY_PREFS_WEB_APP_MOBILE_CAPABLE    "mobile-capable"
+#define EPHY_PREFS_WEB_APP_RUN_IN_BACKGROUND "run-in-background"
 
 static struct {
   const char *schema;
diff --git a/src/ephy-header-bar.c b/src/ephy-header-bar.c
index 8b8a67cde..d41a0ea7a 100644
--- a/src/ephy-header-bar.c
+++ b/src/ephy-header-bar.c
@@ -276,12 +276,17 @@ ephy_header_bar_constructed (GObject *object)
     gtk_widget_destroy (GTK_WIDGET (gtk_builder_get_object (builder, "import-export-separator")));
     gtk_widget_destroy (GTK_WIDGET (gtk_builder_get_object (builder, "import-export-menu")));
   } else if (ephy_is_running_inside_flatpak ()) {
+    gtk_widget_destroy (GTK_WIDGET (gtk_builder_get_object (builder, "run-in-background-separator")));
+    gtk_widget_destroy (GTK_WIDGET (gtk_builder_get_object (builder, "run-in-background-button")));
     gtk_widget_destroy (GTK_WIDGET (gtk_builder_get_object (builder, "save-as-application-separator")));
     gtk_widget_destroy (GTK_WIDGET (gtk_builder_get_object (builder, "save-as-application-button")));
     gtk_widget_destroy (GTK_WIDGET (gtk_builder_get_object (builder, "application-manager-button")));
 
     if (is_desktop_pantheon ())
       gtk_widget_destroy (GTK_WIDGET (gtk_builder_get_object (builder, "help-button")));
+  } else {
+    gtk_widget_destroy (GTK_WIDGET (gtk_builder_get_object (builder, "run-in-background-separator")));
+    gtk_widget_destroy (GTK_WIDGET (gtk_builder_get_object (builder, "run-in-background-button")));
   }
 
   header_bar->combined_stop_reload_button = GTK_WIDGET (gtk_builder_get_object (builder, 
"combined_stop_reload_button"));
diff --git a/src/ephy-shell.c b/src/ephy-shell.c
index 7e5831734..4aae6510a 100644
--- a/src/ephy-shell.c
+++ b/src/ephy-shell.c
@@ -121,6 +121,9 @@ ephy_shell_startup_continue (EphyShell               *shell,
   EphySession *session = ephy_shell_get_session (shell);
   gboolean new_window_option = (ctx->startup_mode == EPHY_STARTUP_NEW_WINDOW);
   GtkWindow *active_window = gtk_application_get_active_window (GTK_APPLICATION (shell));
+  EphyEmbedShellMode mode;
+
+  mode = ephy_embed_shell_get_mode (EPHY_EMBED_SHELL (shell));
 
   if (ctx->session_filename != NULL) {
     g_assert (session != NULL);
@@ -140,11 +143,13 @@ ephy_shell_startup_continue (EphyShell               *shell,
 
     ephy_shell_open_uris (shell, uris, ctx->startup_mode, ctx->user_time);
     g_free (homepage_url);
-  } else if (active_window && !ctx->arguments) {
-    /* If the application already has an active window and the --new-window */
-    /* option was not passed, then we should just present it */
+  } else if (active_window && (!ctx->arguments || mode == EPHY_EMBED_SHELL_MODE_APPLICATION)) {
+    /* If the application already has an active window and: */
+    /*   Option 1: the --new-window option was not passed */
+    /*   Option 2: mode is application */
+    /* then we should just present it */
     /* This can happen for example if the user starts a long download and then */
-    /* closes the browser.*/
+    /* closes the browser or the web app is running in background .*/
     /* The window will still remain active and presenting it will have a */
     /* session-resumed feel for the user. */
     gtk_window_present (active_window);
@@ -332,6 +337,18 @@ notification_clicked (GSimpleAction *action,
     webkit_notification_clicked (notification);
 }
 
+static void
+run_in_background_change_state (GSimpleAction *action,
+                                GVariant      *value,
+                                gpointer       user_data)
+{
+  gboolean active;
+
+  active = g_settings_get_boolean (EPHY_SETTINGS_WEB_APP, EPHY_PREFS_WEB_APP_RUN_IN_BACKGROUND);
+  g_simple_action_set_state (action, g_variant_new_boolean (!active));
+  g_settings_set_boolean (EPHY_SETTINGS_WEB_APP, EPHY_PREFS_WEB_APP_RUN_IN_BACKGROUND, !active);
+}
+
 static GActionEntry app_entries[] = {
   { "new-window", new_window, NULL, NULL, NULL },
   { "new-incognito", new_incognito_window, NULL, NULL, NULL },
@@ -358,6 +375,7 @@ static GActionEntry app_mode_app_entries[] = {
   { "preferences", show_preferences, NULL, NULL, NULL },
   { "about", show_about, NULL, NULL, NULL },
   { "quit", quit_application, NULL, NULL, NULL },
+  { "run-in-background", NULL, "b", "false", run_in_background_change_state},
 };
 
 static void
@@ -436,12 +454,22 @@ set_accel_for_action (EphyShell   *shell,
   gtk_application_set_accels_for_action (GTK_APPLICATION (shell), detailed_action_name, accels);
 }
 
+static gboolean
+run_in_background_get_mapping (GValue   *value,
+                               GVariant *variant,
+                               gpointer  user_data)
+{
+  g_value_set_variant (value, variant);
+  return TRUE;
+}
+
 static void
 ephy_shell_startup (GApplication *application)
 {
   EphyEmbedShell *embed_shell = EPHY_EMBED_SHELL (application);
   EphyShell *shell = EPHY_SHELL (application);
   EphyEmbedShellMode mode;
+  GAction *action;
 
   G_APPLICATION_CLASS (ephy_shell_parent_class)->startup (application);
 
@@ -484,6 +512,17 @@ ephy_shell_startup (GApplication *application)
     g_action_map_add_action_entries (G_ACTION_MAP (application),
                                      app_mode_app_entries, G_N_ELEMENTS (app_mode_app_entries),
                                      application);
+
+    action = g_action_map_lookup_action (G_ACTION_MAP (application), "run-in-background");
+    g_settings_bind_with_mapping (EPHY_SETTINGS_WEB_APP,
+                                  EPHY_PREFS_WEB_APP_RUN_IN_BACKGROUND,
+                                  G_SIMPLE_ACTION (action),
+                                  "state",
+                                  G_SETTINGS_BIND_GET | G_SETTINGS_BIND_GET_NO_CHANGES,
+                                  run_in_background_get_mapping,
+                                  NULL,
+                                  NULL,
+                                  NULL);
   }
 
   /* Actions that are available in both app mode and browser mode */
@@ -714,7 +753,8 @@ ephy_shell_get_lockdown (EphyShell *shell)
 static void
 ephy_shell_constructed (GObject *object)
 {
-  if (ephy_embed_shell_get_mode (EPHY_EMBED_SHELL (object)) != EPHY_EMBED_SHELL_MODE_BROWSER) {
+  if (ephy_embed_shell_get_mode (EPHY_EMBED_SHELL (object)) != EPHY_EMBED_SHELL_MODE_BROWSER &&
+      ephy_embed_shell_get_mode (EPHY_EMBED_SHELL (object)) != EPHY_EMBED_SHELL_MODE_APPLICATION) {
     GApplicationFlags flags;
 
     flags = g_application_get_flags (G_APPLICATION (object));
@@ -1175,10 +1215,19 @@ _ephy_shell_create_instance (EphyEmbedShellMode mode)
 
   g_assert (ephy_shell == NULL);
 
-  if (mode == EPHY_EMBED_SHELL_MODE_APPLICATION)
-    id = g_strconcat (APPLICATION_ID, ".WebApp", NULL);
-  else
+  if (mode == EPHY_EMBED_SHELL_MODE_APPLICATION) {
+    const char *profile_dir = ephy_profile_dir ();
+    g_autofree char *basename = g_path_get_basename (profile_dir);
+    g_auto (GStrv) split = g_strsplit_set (basename, "-", -1);
+    guint len = g_strv_length (split);
+
+    if (len > 0)
+      id = g_strconcat (APPLICATION_ID, ".WebApp-", split[len - 1], NULL);
+    else
+      id = g_strconcat (APPLICATION_ID, ".WebApp", NULL);
+  } else {
     id = g_strdup (APPLICATION_ID);
+  }
 
   ephy_shell = EPHY_SHELL (g_object_new (EPHY_TYPE_SHELL,
                                          "application-id", id,
diff --git a/src/ephy-window.c b/src/ephy-window.c
index 005918320..9ef73392e 100644
--- a/src/ephy-window.c
+++ b/src/ephy-window.c
@@ -678,6 +678,11 @@ static gboolean
 ephy_window_delete_event (GtkWidget   *widget,
                           GdkEventAny *event)
 {
+  if ((ephy_embed_shell_get_mode (ephy_embed_shell_get_default ()) == EPHY_EMBED_SHELL_MODE_APPLICATION) && 
g_settings_get_boolean (EPHY_SETTINGS_WEB_APP, EPHY_PREFS_WEB_APP_RUN_IN_BACKGROUND)) {
+    gtk_widget_hide (widget);
+    return TRUE;
+  }
+
   if (!ephy_window_close (EPHY_WINDOW (widget)))
     return TRUE;
 
diff --git a/src/resources/gtk/page-menu-popover.ui b/src/resources/gtk/page-menu-popover.ui
index dedb3566e..e06a61c83 100644
--- a/src/resources/gtk/page-menu-popover.ui
+++ b/src/resources/gtk/page-menu-popover.ui
@@ -157,6 +157,25 @@
               <class name="page-menu-contents"/>
             </style>
 
+            <!-- FRAGILE: These buttons are manually removed for non app mode in ephy-header-bar.c. -->
+            <child>
+              <object class="GtkSeparator" id="run-in-background-separator">
+                <property name="orientation">horizontal</property>
+                <property name="margin-top">6</property>
+                <property name="margin-bottom">6</property>
+                <property name="visible">True</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkModelButton" id="run-in-background-button">
+                <property name="can_focus">True</property>
+                <property name="text" translatable="yes">_Run in Background</property>
+                <property name="action-name">app.run-in-background</property>
+                <property name="action-target">true</property>
+                <property name="visible">True</property>
+              </object>
+            </child>
+
             <!-- FRAGILE: These buttons are manually removed for app mode in ephy-header-bar.c. -->
             <child>
               <object class="GtkSeparator" id="new-window-separator">


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