[gnome-shell] Don't switch to a workspace when dragging it to launch on that workspace



commit 0d32017ffc6813546ba68c484c3902213df9bd84
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Sun Jan 30 16:09:58 2011 -0500

    Don't switch to a workspace when dragging it to launch on that workspace
    
    With workspace thumbnails, we don't switch workspaces when dragging windows
    between workspaces or adding new workspaces, so we also shouldn't switch
    on launch.
    
     * Add workspace parameters to shell_doc_system_open(),
       shell_app_activate, shell_app_open_new_window()
    
     * Pass a 'params' object when activating items in the overview with
       two currently defined parameters: workspace and timestamp. (timestamp
       is only implemented where it is easy and doesn't require interface
       changes - using the global current timestamp for the shell is almost
       always right or at least good enough.)
    
    https://bugzilla.gnome.org/show_bug.cgi?id=640996

 js/misc/docInfo.js          |    4 +-
 js/ui/appDisplay.js         |   29 ++++++++++++++++--------
 js/ui/docDisplay.js         |    8 +++++-
 js/ui/endSessionDialog.js   |    2 +-
 js/ui/placeDisplay.js       |   51 +++++++++++++++++++++++++++++++-----------
 js/ui/search.js             |    2 +-
 js/ui/searchDisplay.js      |    6 ++--
 js/ui/workspace.js          |    4 +-
 js/ui/workspaceThumbnail.js |    4 +-
 src/shell-app.c             |   23 ++++++++++++++++---
 src/shell-app.h             |    6 +++-
 src/shell-doc-system.c      |   16 +++++++++----
 src/shell-doc-system.h      |    3 +-
 13 files changed, 109 insertions(+), 49 deletions(-)
---
diff --git a/js/misc/docInfo.js b/js/misc/docInfo.js
index a9332d9..8ec375a 100644
--- a/js/misc/docInfo.js
+++ b/js/misc/docInfo.js
@@ -29,8 +29,8 @@ DocInfo.prototype = {
         return St.TextureCache.get_default().load_recent_thumbnail(size, this.recentInfo);
     },
 
-    launch : function() {
-        Shell.DocSystem.get_default().open(this.recentInfo);
+    launch : function(workspaceIndex) {
+        Shell.DocSystem.get_default().open(this.recentInfo, workspaceIndex);
     },
 
     matchTerms: function(terms) {
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index 4372030..3df634f 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -223,14 +223,20 @@ BaseAppSearchProvider.prototype = {
                  'icon': app.create_icon_texture(Search.RESULT_ICON_SIZE)};
     },
 
-    activateResult: function(id) {
+    activateResult: function(id, params) {
+        params = Params.parse(params, { workspace: null,
+                                        timestamp: null });
+
         let app = this._appSys.get_app(id);
-        app.activate();
+        app.activate(params.workspace ? params.workspace.index() : -1);
     },
 
-    dragActivateResult: function(id) {
+    dragActivateResult: function(id, params) {
+        params = Params.parse(params, { workspace: null,
+                                        timestamp: null });
+
         let app = this._appSys.get_app(id);
-        app.open_new_window();
+        app.open_new_window(params.workspace ? params.workspace.get_index() : -1);
     }
 };
 
@@ -401,7 +407,7 @@ AppWellIcon.prototype = {
             let launchWorkspace = global.screen.get_workspace_by_index(global.screen.n_workspaces - 1);
             launchWorkspace.activate(global.get_current_time());
             this.emit('launching');
-            this.app.open_new_window();
+            this.app.open_new_window(-1);
             Main.overview.hide();
         }
         return false;
@@ -486,9 +492,9 @@ AppWellIcon.prototype = {
 
         if (modifiers & Clutter.ModifierType.CONTROL_MASK
             && this.app.state == Shell.AppState.RUNNING) {
-            this.app.open_new_window();
+            this.app.open_new_window(-1);
         } else {
-            this.app.activate();
+            this.app.activate(-1);
         }
         Main.overview.hide();
     },
@@ -498,8 +504,11 @@ AppWellIcon.prototype = {
         return this._menu.menuEventFilter(event);
     },
 
-    shellWorkspaceLaunch : function() {
-        this.app.open_new_window();
+    shellWorkspaceLaunch : function(params) {
+        params = Params.parse(params, { workspace: null,
+                                        timestamp: null });
+
+        this.app.open_new_window(params.workspace ? params.workspace.index() : -1);
     },
 
     getDragActor: function() {
@@ -668,7 +677,7 @@ AppIconMenu.prototype = {
             let metaWindow = child._window;
             this.emit('activate-window', metaWindow);
         } else if (child == this._newWindowMenuItem) {
-            this._source.app.open_new_window();
+            this._source.app.open_new_window(-1);
             this.emit('activate-window', null);
         } else if (child == this._toggleFavoriteMenuItem) {
             let favs = AppFavorites.getAppFavorites();
diff --git a/js/ui/docDisplay.js b/js/ui/docDisplay.js
index d2afe04..2e77f8c 100644
--- a/js/ui/docDisplay.js
+++ b/js/ui/docDisplay.js
@@ -4,6 +4,7 @@ const Gettext = imports.gettext.domain('gnome-shell');
 const _ = Gettext.gettext;
 
 const DocInfo = imports.misc.docInfo;
+const Params = imports.misc.params;
 const Search = imports.ui.search;
 
 
@@ -28,9 +29,12 @@ DocSearchProvider.prototype = {
                  'icon': docInfo.createIcon(Search.RESULT_ICON_SIZE)};
     },
 
-    activateResult: function(id) {
+    activateResult: function(id, params) {
+        params = Params.parse(params, { workspace: null,
+                                        timestamp: null });
+
         let docInfo = this._docManager.lookupByUri(id);
-        docInfo.launch();
+        docInfo.launch(params.workspace ? params.workspace.index() : -1);
     },
 
     getInitialResultSet: function(terms) {
diff --git a/js/ui/endSessionDialog.js b/js/ui/endSessionDialog.js
index 6b85bd8..be64427 100644
--- a/js/ui/endSessionDialog.js
+++ b/js/ui/endSessionDialog.js
@@ -171,7 +171,7 @@ ListItem.prototype = {
 
     _onClicked: function() {
         this.emit('activate');
-        this._app.activate();
+        this._app.activate(-1);
     }
 };
 Signals.addSignalMethods(ListItem.prototype);
diff --git a/js/ui/placeDisplay.js b/js/ui/placeDisplay.js
index b8745b2..04ce63c 100644
--- a/js/ui/placeDisplay.js
+++ b/js/ui/placeDisplay.js
@@ -12,6 +12,7 @@ const _ = Gettext.gettext;
 
 const DND = imports.ui.dnd;
 const Main = imports.ui.main;
+const Params = imports.misc.params;
 const Search = imports.ui.search;
 const Util = imports.misc.util;
 
@@ -58,6 +59,21 @@ PlaceInfo.prototype = {
     }
 };
 
+// Helper function to translate launch parameters into a GAppLaunchContext
+function _makeLaunchContext(params)
+{
+    params = Params.parse(params, { workspace: null,
+                                    timestamp: null });
+
+    let launchContext = global.create_app_launch_context();
+    if (params.workspace != null)
+        launchContext.set_desktop(params.workspace.index());
+    if (params.timestamp != null)
+        launchContext.set_timestamp(params.timestamp);
+
+    return launchContext;
+}
+
 function PlaceDeviceInfo(mount) {
     this._init(mount);
 }
@@ -77,9 +93,9 @@ PlaceDeviceInfo.prototype = {
         return St.TextureCache.get_default().load_gicon(null, icon, size);
     },
 
-    launch: function() {
+    launch: function(param) {
         Gio.app_info_launch_default_for_uri(this._mount.get_root().get_uri(),
-                                            global.create_app_launch_context());
+                                            _makeLaunchContex(params));
     },
 
     isRemovable: function() {
@@ -111,7 +127,6 @@ PlaceDeviceInfo.prototype = {
     }
 };
 
-
 function PlacesManager() {
     this._init();
 }
@@ -130,8 +145,8 @@ PlacesManager.prototype = {
             function(size) {
                 return St.TextureCache.get_default().load_gicon(null, homeIcon, size);
             },
-            function() {
-                Gio.app_info_launch_default_for_uri(homeUri, global.create_app_launch_context());
+            function(params) {
+                Gio.app_info_launch_default_for_uri(homeUri, _makeLaunchContext(params));
             });
 
         let desktopPath = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP);
@@ -143,8 +158,8 @@ PlacesManager.prototype = {
             function(size) {
                 return St.TextureCache.get_default().load_gicon(null, desktopIcon, size);
             },
-            function() {
-                Gio.app_info_launch_default_for_uri(desktopUri, global.create_app_launch_context());
+            function(params) {
+                Gio.app_info_launch_default_for_uri(desktopUri, _makeLaunchContext(params));
             });
 
         this._connect = new PlaceInfo('special:connect', _("Connect to..."),
@@ -153,7 +168,11 @@ PlacesManager.prototype = {
                                      icon_type: St.IconType.FULLCOLOR,
                                      icon_size: size });
             },
-            function () {
+            function (params) {
+                // BUG: nautilus-connect-server doesn't have a desktop file, so we can't
+                // launch it with the workspace from params. It's probably pretty rare
+                // and odd to drag this place onto a workspace in any case
+
                 Util.spawn(['nautilus-connect-server']);
             });
 
@@ -173,8 +192,12 @@ PlacesManager.prototype = {
                 function(size) {
                     return networkApp.create_icon_texture(size);
                 },
-                function () {
-                    networkApp.launch();
+                function (params) {
+                    params = Params.parse(params, { workspace: null,
+                                                    timestamp: 0 });
+
+                    networkApp.launch_full(params.timestamp, [],
+                                           params.workspace ? params.workspace.index() : -1);
                 });
         }
 
@@ -314,8 +337,8 @@ PlacesManager.prototype = {
                 function(size) {
                     return St.TextureCache.get_default().load_gicon(null, icon, size);
                 },
-                function() {
-                    Gio.app_info_launch_default_for_uri(bookmark, global.create_app_launch_context());
+                function(params) {
+                    Gio.app_info_launch_default_for_uri(bookmark, _makeLaunchContext(params));
                 });
             this._bookmarks.push(item);
         }
@@ -395,9 +418,9 @@ PlaceSearchProvider.prototype = {
                  'icon': placeInfo.iconFactory(Search.RESULT_ICON_SIZE) };
     },
 
-    activateResult: function(id) {
+    activateResult: function(id, params) {
         let placeInfo = Main.placesManager.lookupPlaceById(id);
-        placeInfo.launch();
+        placeInfo.launch(params);
     },
 
     _compareResultMeta: function (idA, idB) {
diff --git a/js/ui/search.js b/js/ui/search.js
index 24b411a..d1fa925 100644
--- a/js/ui/search.js
+++ b/js/ui/search.js
@@ -267,7 +267,7 @@ OpenSearchSystem.prototype = {
         return lang != null;
     },
 
-    activateResult: function(id) {
+    activateResult: function(id, params) {
         let searchTerms = this._terms.join(' ');
 
         let url = this._providers[id].url.replace('{searchTerms}', encodeURIComponent(searchTerms));
diff --git a/js/ui/searchDisplay.js b/js/ui/searchDisplay.js
index 44794f6..7e9ba7a 100644
--- a/js/ui/searchDisplay.js
+++ b/js/ui/searchDisplay.js
@@ -81,11 +81,11 @@ SearchResult.prototype = {
         return new Clutter.Clone({ source: this.metaInfo['icon'] });
     },
 
-    shellWorkspaceLaunch: function() {
+    shellWorkspaceLaunch: function(params) {
         if (this.provider.dragActivateResult)
-            this.provider.dragActivateResult(this.metaInfo.id);
+            this.provider.dragActivateResult(this.metaInfo.id, params);
         else
-            this.provider.activateResult(this.metaInfo.id);
+            this.provider.activateResult(this.metaInfo.id, params);
     }
 };
 
diff --git a/js/ui/workspace.js b/js/ui/workspace.js
index 0241213..3e76d71 100644
--- a/js/ui/workspace.js
+++ b/js/ui/workspace.js
@@ -1431,8 +1431,8 @@ Workspace.prototype = {
                                                  time);
             return true;
         } else if (source.shellWorkspaceLaunch) {
-            this.metaWorkspace.activate(time);
-            source.shellWorkspaceLaunch();
+            source.shellWorkspaceLaunch({ workspace: this.metaWorkspace,
+                                          timestamp: time });
             return true;
         }
 
diff --git a/js/ui/workspaceThumbnail.js b/js/ui/workspaceThumbnail.js
index 8f8586b..e4bd6bb 100644
--- a/js/ui/workspaceThumbnail.js
+++ b/js/ui/workspaceThumbnail.js
@@ -283,8 +283,8 @@ WorkspaceThumbnail.prototype = {
                                                  time);
             return true;
         } else if (source.shellWorkspaceLaunch) {
-            this.metaWorkspace.activate(time);
-            source.shellWorkspaceLaunch();
+            source.shellWorkspaceLaunch({ workspace: this.metaWorkspace,
+                                          timestamp: time });
             return true;
         }
 
diff --git a/src/shell-app.c b/src/shell-app.c
index 0f733a4..74b72fb 100644
--- a/src/shell-app.c
+++ b/src/shell-app.c
@@ -411,6 +411,8 @@ shell_app_activate_window (ShellApp     *app,
 /**
  * shell_app_activate:
  * @app: a #ShellApp
+ * @workspace: launch on this workspace, or -1 for default. Ignored if
+ *   activating an existing window
  *
  * Perform an appropriate default action for operating on this application,
  * dependent on its current state.  For example, if the application is not
@@ -419,13 +421,19 @@ shell_app_activate_window (ShellApp     *app,
  * recently used transient for that window).
  */
 void
-shell_app_activate (ShellApp  *app)
+shell_app_activate (ShellApp      *app,
+                    int            workspace)
 {
   switch (app->state)
     {
       case SHELL_APP_STATE_STOPPED:
         /* TODO sensibly handle this error */
-        shell_app_info_launch (app->info, NULL);
+        shell_app_info_launch_full (app->info,
+                                    0,
+                                    NULL,
+                                    workspace,
+                                    NULL,
+                                    NULL);
         break;
       case SHELL_APP_STATE_STARTING:
         break;
@@ -438,11 +446,13 @@ shell_app_activate (ShellApp  *app)
 /**
  * shell_app_open_new_window:
  * @app: a #ShellApp
+ * @workspace: open on this workspace, or -1 for default
  *
  * Request that the application create a new window.
  */
 void
-shell_app_open_new_window (ShellApp *app)
+shell_app_open_new_window (ShellApp      *app,
+                           int            workspace)
 {
   /* Here we just always launch the application again, even if we know
    * it was already running.  For most applications this
@@ -452,7 +462,12 @@ shell_app_open_new_window (ShellApp *app)
    * as say Pidgin.  Ideally, we have the application express to us
    * that it supports an explicit new-window action.
    */
-  shell_app_info_launch (app->info, NULL);
+  shell_app_info_launch_full (app->info,
+                              0,
+                              NULL,
+                              workspace,
+                              NULL,
+                              NULL);
 }
 
 /**
diff --git a/src/shell-app.h b/src/shell-app.h
index ce22237..78b61f5 100644
--- a/src/shell-app.h
+++ b/src/shell-app.h
@@ -44,9 +44,11 @@ gboolean shell_app_is_transient (ShellApp *app);
 
 void shell_app_activate_window (ShellApp *app, MetaWindow *window, guint32 timestamp);
 
-void shell_app_activate (ShellApp *app);
+void shell_app_activate (ShellApp      *app,
+                         int            workspace);
 
-void shell_app_open_new_window (ShellApp *app);
+void shell_app_open_new_window (ShellApp *app,
+                                int       workspace);
 
 ShellAppState shell_app_get_state (ShellApp *app);
 
diff --git a/src/shell-doc-system.c b/src/shell-doc-system.c
index 3ee51e6..a80e816 100644
--- a/src/shell-doc-system.c
+++ b/src/shell-doc-system.c
@@ -227,17 +227,24 @@ shell_doc_system_on_recent_changed (GtkRecentManager  *manager,
  * shell_doc_system_open:
  * @system: A #ShellDocSystem
  * @info: A #GtkRecentInfo
+ * @workspace: Open on this workspace, or -1 for default
  *
  * Launch the default application associated with the mime type of
  * @info, using its uri.
  */
 void
 shell_doc_system_open (ShellDocSystem *system,
-                       GtkRecentInfo  *info)
+                       GtkRecentInfo  *info,
+                       int             workspace)
 {
   GFile *file;
   GAppInfo *app_info;
   gboolean needs_uri;
+  GAppLaunchContext *context;
+
+  context = shell_global_create_app_launch_context (shell_global_get ());
+  if (workspace != -1)
+    gdk_app_launch_context_set_desktop ((GdkAppLaunchContext *)context, workspace);
 
   file = g_file_new_for_uri (gtk_recent_info_get_uri (info));
   needs_uri = g_file_get_path (file) == NULL;
@@ -248,7 +255,7 @@ shell_doc_system_open (ShellDocSystem *system,
     {
       GList *uris;
       uris = g_list_prepend (NULL, (gpointer)gtk_recent_info_get_uri (info));
-      g_app_info_launch_uris (app_info, uris, shell_global_create_app_launch_context (shell_global_get ()), NULL);
+      g_app_info_launch_uris (app_info, uris, context, NULL);
       g_list_free (uris);
     }
   else
@@ -267,7 +274,6 @@ shell_doc_system_open (ShellDocSystem *system,
       if (gtk_recent_info_get_application_info (info, app_name, &app_exec, &count, &time))
         {
           GRegex *regex;
-          GAppLaunchContext *context;
 
           /* TODO: Change this once better support for creating
              GAppInfo is added to GtkRecentInfo, as right now
@@ -298,13 +304,13 @@ shell_doc_system_open (ShellDocSystem *system,
              despite passing the app launch context, no startup
              notification occurs.
            */
-          context = shell_global_create_app_launch_context (shell_global_get ());
           g_app_info_launch (app_info, NULL, context, NULL);
-          g_object_unref (context);
         }
 
       g_free (app_name);
     }
+
+  g_object_unref (context);
 }
 
 static void
diff --git a/src/shell-doc-system.h b/src/shell-doc-system.h
index 95ffb6c..077bc1a 100644
--- a/src/shell-doc-system.h
+++ b/src/shell-doc-system.h
@@ -41,6 +41,7 @@ void shell_doc_system_queue_existence_check (ShellDocSystem   *system,
                                              guint             n_items);
 
 void shell_doc_system_open (ShellDocSystem *system,
-                            GtkRecentInfo  *info);
+                            GtkRecentInfo  *info,
+                            int             workspace);
 
 #endif /* __SHELL_DOC_SYSTEM_H__ */



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