[gnome-shell] AppDisplay: don't show a "New Window" menu item if not possible



commit 3182aba744e7d64ecf71dfdbb5f5b1fa663325dc
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Sun Jan 19 18:05:16 2014 +0100

    AppDisplay: don't show a "New Window" menu item if not possible
    
    If the application reports itself as single window (through
    an explicit indication in the desktop file or some heuristics),
    not show a "New window" item that doesn't actually open a new window.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=722554

 js/ui/appDisplay.js |   14 ++++++----
 src/shell-app.c     |   66 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/shell-app.h     |    1 +
 3 files changed, 75 insertions(+), 6 deletions(-)
---
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index 524635c..253d4c4 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -1628,12 +1628,14 @@ const AppIconMenu = new Lang.Class({
         if (!this._source.app.is_window_backed()) {
             this._appendSeparator();
 
-            this._newWindowMenuItem = this._appendMenuItem(_("New Window"));
-            this._newWindowMenuItem.connect('activate', Lang.bind(this, function() {
-                this._source.app.open_new_window(-1);
-                this.emit('activate-window', null);
-            }));
-            this._appendSeparator();
+            if (this._source.app.can_open_new_window()) {
+                this._newWindowMenuItem = this._appendMenuItem(_("New Window"));
+                this._newWindowMenuItem.connect('activate', Lang.bind(this, function() {
+                    this._source.app.open_new_window(-1);
+                    this.emit('activate-window', null);
+                }));
+                this._appendSeparator();
+            }
 
             let appInfo = this._source.app.get_app_info();
             let actions = appInfo.list_actions();
diff --git a/src/shell-app.c b/src/shell-app.c
index 6529025..4714696 100644
--- a/src/shell-app.c
+++ b/src/shell-app.c
@@ -706,6 +706,72 @@ shell_app_open_new_window (ShellApp      *app,
 }
 
 /**
+ * shell_app_can_open_new_window:
+ * @app: a #ShellApp
+ *
+ * Returns %TRUE if the app supports opening a new window through
+ * shell_app_open_new_window() (ie, if calling that function will
+ * result in actually opening a new window and not something else,
+ * like presenting the most recently active one)
+ */
+gboolean
+shell_app_can_open_new_window (ShellApp *app)
+{
+  ShellAppRunningState *state;
+
+  /* Apps that are not running can always open new windows, because
+     activating them would open the first one */
+  if (!app->running_state)
+    return TRUE;
+
+  state = app->running_state;
+
+  /* If the app has an explicit new-window action, then it can
+
+     (or it should be able to - we don't actually call the action
+     because we need to trigger startup notification, so it still
+     depends on what the app decides to do for Activate vs ActivateAction)
+  */
+  if (g_action_group_has_action (G_ACTION_GROUP (state->muxer), "app.new-window"))
+    return TRUE;
+
+  /* If the app doesn't have a desktop file, then nothing is possible */
+  if (!app->info)
+    return FALSE;
+
+  /* If the app is explicitly telling us, then we know for sure */
+  if (g_desktop_app_info_has_key (G_DESKTOP_APP_INFO (app->info),
+                                  "X-GNOME-SingleWindow"))
+    return !g_desktop_app_info_get_boolean (G_DESKTOP_APP_INFO (app->info),
+                                            "X-GNOME-SingleWindow");
+
+  /* If this is a unique GtkApplication, and we don't have a new-window, then
+     probably we can't
+
+     We don't consider non-unique GtkApplications here to handle cases like
+     evince, which don't export a new-window action because each window is in
+     a different process. In any case, in a non-unique GtkApplication each
+     Activate() knows nothing about the other instances, so it will show a
+     new window.
+  */
+  if (state->remote_menu)
+    {
+      const char *application_id;
+      application_id = meta_window_get_gtk_application_id (state->windows->data);
+      if (application_id != NULL)
+        return FALSE;
+      else
+        return TRUE;
+    }
+
+  /* In all other cases, we don't have a reliable source of information
+     or a decent heuristic, so we err on the compatibility side and say
+     yes.
+  */
+  return TRUE;
+}
+
+/**
  * shell_app_get_state:
  * @app: a #ShellApp
  *
diff --git a/src/shell-app.h b/src/shell-app.h
index 120385c..4cf7572 100644
--- a/src/shell-app.h
+++ b/src/shell-app.h
@@ -56,6 +56,7 @@ void shell_app_activate_full (ShellApp      *app,
 
 void shell_app_open_new_window (ShellApp *app,
                                 int       workspace);
+gboolean shell_app_can_open_new_window (ShellApp *app);
 
 ShellAppState shell_app_get_state (ShellApp *app);
 


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