diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js index 9c20e5cbd..cf9966dab 100644 --- a/js/ui/appDisplay.js +++ b/js/ui/appDisplay.js @@ -663,6 +663,7 @@ WellMenu.prototype = { _onMenuButtonRelease: function (actor, event) { let clone = this._findWindowCloneForActor(event.get_source()); if (clone) { + this.didActivateWindow = true; Main.overview.activateWindow(clone.metaWindow, event.get_time()); } }, @@ -707,6 +708,7 @@ WellMenu.prototype = { _onWindowActivate: function (actor, child) { let metaWindow = child._window; + this.didActivateWindow = true; Main.overview.activateWindow(metaWindow, Clutter.get_current_event_time()); this.emit('popup', false); this.actor.hide(); @@ -854,6 +856,10 @@ RunningWellItem.prototype = { this._menu.connect('popup', Lang.bind(this, function (menu, isPoppedUp) { let id; + // If we successfully picked a window, don't reset the workspace + // state, since picking a window already did that. + if (!isPoppedUp && menu.didActivateWindow) + return; if (isPoppedUp) id = this.appInfo.get_id(); else diff --git a/js/ui/overview.js b/js/ui/overview.js index c8d272993..7afc56424 100644 --- a/js/ui/overview.js +++ b/js/ui/overview.js @@ -342,7 +342,7 @@ Overview.prototype = { this.emit('showing'); }, - hide : function() { + hide: function() { if (!this.visible || this._hideInProgress) return; @@ -410,7 +410,6 @@ Overview.prototype = { */ activateWindow: function (metaWindow, time) { this._workspaces.activateWindowFromOverview(metaWindow, time); - this.hide(); }, //// Private methods //// diff --git a/js/ui/workspaces.js b/js/ui/workspaces.js index d36366bfb..12e4b77d4 100644 --- a/js/ui/workspaces.js +++ b/js/ui/workspaces.js @@ -560,9 +560,11 @@ Workspace.prototype = { return this._lookupIndex(metaWindow) >= 0; }, - setShowOnlyWindows: function(showOnlyWindows) { + setShowOnlyWindows: function(showOnlyWindows, reposition) { this._showOnlyWindows = showOnlyWindows; - this.positionWindows(false); + this._resetCloneVisibility(); + if (reposition) + this.positionWindows(false); }, /** @@ -643,9 +645,24 @@ Workspace.prototype = { this._desktop.actor.height + 2 * FRAME_SIZE / this.actor.scale_y); }, - // Reposition all windows in their zoomed-to-Overview position. if workspaceZooming - // is true, then the workspace is moving at the same time and we need to take - // that into account + _resetCloneVisibility: function () { + for (let i = 1; i < this._windows.length; i++) { + let clone = this._windows[i]; + let icon = this._windowIcons[i]; + + if (this._showOnlyWindows != null && !(clone.metaWindow in this._showOnlyWindows)) { + clone.setVisibleWithChrome(false); + icon.hide(); + } else { + clone.setVisibleWithChrome(true); + } + } + }, + + /** + * positionWindows: + * @workspaceZooming: If true, then the workspace is moving at the same time and we need to take that into account. + */ positionWindows : function(workspaceZooming) { let totalVisible = 0; @@ -664,13 +681,8 @@ Workspace.prototype = { let clone = this._windows[i]; let icon = this._windowIcons[i]; - if (this._showOnlyWindows != null && !(clone.metaWindow in this._showOnlyWindows)) { - clone.setVisibleWithChrome(false); - icon.hide(); + if (this._showOnlyWindows != null && !(clone.metaWindow in this._showOnlyWindows)) continue; - } else { - clone.setVisibleWithChrome(true); - } clone.stackAbove = previousWindow.actor; previousWindow = clone; @@ -1100,6 +1112,8 @@ Workspaces.prototype = { this._x = x; this._y = y; + this._windowSelectionAppId = null; + this._workspaces = []; this._highlightWindow = null; @@ -1170,6 +1184,17 @@ Workspaces.prototype = { } }, + _clearApplicationWindowSelection: function(reposition) { + if (this._windowSelectionAppId == null) + return; + this._windowSelectionAppId = null; + + for (let i = 0; i < this._workspaces.length; i++) { + this._workspaces[i].setLightboxMode(false); + this._workspaces[i].setShowOnlyWindows(null, reposition); + } + }, + /** * setApplicationWindowSelection: * @appid: Application identifier string @@ -1179,26 +1204,31 @@ Workspaces.prototype = { * window with setHighlightWindow(). */ setApplicationWindowSelection: function (appId) { + if (appId == null) { + this._clearApplicationWindowSelection(true); + return; + } + + if (appId == this._windowSelectionAppId) + return; + + this._windowSelectionAppId = appId; + let appSys = Shell.AppMonitor.get_default(); - let showOnlyWindows; - if (appId) { - let windows = appSys.get_windows_for_app(appId); - showOnlyWindows = {}; - for (let i = 0; i < windows.length; i++) { - showOnlyWindows[windows[i]] = 1; - } - } else { - showOnlyWindows = null; + let showOnlyWindows = {}; + let windows = appSys.get_windows_for_app(appId); + for (let i = 0; i < windows.length; i++) { + showOnlyWindows[windows[i]] = 1; } + for (let i = 0; i < this._workspaces.length; i++) { - this._workspaces[i].setLightboxMode(showOnlyWindows != null); - this._workspaces[i].setShowOnlyWindows(showOnlyWindows); + this._workspaces[i].setLightboxMode(true); + this._workspaces[i].setShowOnlyWindows(showOnlyWindows, true); } }, - // Should only be called from active Overview context - activateWindowFromOverview: function (metaWindow, time) { + _activateWindowInternal: function (metaWindow, time) { let activeWorkspaceNum = global.screen.get_active_workspace_index(); let windowWorkspaceNum = metaWindow.get_workspace().index(); @@ -1213,6 +1243,22 @@ Workspaces.prototype = { } }, + /** + * activateWindowFromOverview: + * @metaWindow: A #MetaWindow + * @time: Integer even timestamp + * + * This function exits the overview, switching to the given @metaWindow. + * If an application filter is in effect, it will be cleared. + */ + activateWindowFromOverview: function (metaWindow, time) { + if (this._windowSelectionAppId != null) { + this._clearApplicationWindowSelection(false); + } + this._activateWindowInternal(metaWindow, time); + Main.overview.hide(); + }, + hide : function() { let activeWorkspaceIndex = global.screen.get_active_workspace_index(); let activeWorkspace = this._workspaces[activeWorkspaceIndex];