diff --git a/js/ui/workspace.js b/js/ui/workspace.js index 049cc74cd..05a22f7e5 100644 --- a/js/ui/workspace.js +++ b/js/ui/workspace.js @@ -541,7 +541,7 @@ const WindowPositionFlags = { }; /** - * @metaWorkspace: a #Meta.Workspace + * @metaWorkspace: a #Meta.Workspace, or null */ function Workspace(metaWorkspace, monitorIndex) { this._init(metaWorkspace, monitorIndex); @@ -587,10 +587,12 @@ Workspace.prototype = { } // Track window changes - this._windowAddedId = this.metaWorkspace.connect('window-added', - Lang.bind(this, this._windowAdded)); - this._windowRemovedId = this.metaWorkspace.connect('window-removed', - Lang.bind(this, this._windowRemoved)); + if (this.metaWorkspace) { + this._windowAddedId = this.metaWorkspace.connect('window-added', + Lang.bind(this, this._windowAdded)); + this._windowRemovedId = this.metaWorkspace.connect('window-removed', + Lang.bind(this, this._windowRemoved)); + } this._windowEnteredMonitorId = global.screen.connect('window-entered-monitor', Lang.bind(this, this._windowEnteredMonitor)); this._windowLeftMonitorId = global.screen.connect('window-left-monitor', @@ -902,7 +904,7 @@ Workspace.prototype = { clones = this._orderWindowsByMotionAndStartup(clones, slots); let currentWorkspace = global.screen.get_active_workspace(); - let isOnCurrentWorkspace = this.metaWorkspace == currentWorkspace; + let isOnCurrentWorkspace = this.metaWorkspace == null || this.metaWorkspace == currentWorkspace; for (let i = 0; i < clones.length; i++) { let slot = slots[i]; @@ -1005,7 +1007,8 @@ Workspace.prototype = { for (let i = 0; i < this._windows.length; i++) { let clone = this._windows[i]; let overlay = this._windowOverlays[i]; - this._showWindowOverlay(clone, overlay, this.metaWorkspace == currentWorkspace); + this._showWindowOverlay(clone, overlay, + this.metaWorkspace == null || this.metaWorkspace == currentWorkspace); } }, @@ -1202,7 +1205,7 @@ Workspace.prototype = { this._overviewHiddenId = Main.overview.connect('hidden', Lang.bind(this, this._doneLeavingOverview)); - if (this.metaWorkspace != currentWorkspace) + if (this.metaWorkspace != null && this.metaWorkspace != currentWorkspace) return; // Position and scale the windows. @@ -1246,8 +1249,10 @@ Workspace.prototype = { } Tweener.removeTweens(actor); - this.metaWorkspace.disconnect(this._windowAddedId); - this.metaWorkspace.disconnect(this._windowRemovedId); + if (this.metaWorkspace) { + this.metaWorkspace.disconnect(this._windowAddedId); + this.metaWorkspace.disconnect(this._windowRemovedId); + } global.screen.disconnect(this._windowEnteredMonitorId); global.screen.disconnect(this._windowLeftMonitorId); @@ -1270,7 +1275,7 @@ Workspace.prototype = { // Tests if @win belongs to this workspaces and monitor _isMyWindow : function (win) { - return Main.isWindowActorDisplayedOnWorkspace(win, this.metaWorkspace.index()) && + return (this.metaWorkspace == null || Main.isWindowActorDisplayedOnWorkspace(win, this.metaWorkspace.index())) && (!win.get_meta_window() || win.get_meta_window().get_monitor() == this.monitorIndex); }, @@ -1359,8 +1364,10 @@ Workspace.prototype = { }, _onCloneSelected : function (clone, time) { - Main.activateWindow(clone.metaWindow, time, - this.metaWorkspace.index()); + let wsIndex = undefined; + if (this.metaWorkspace) + wsIndex = this.metaWorkspace.index(); + Main.activateWindow(clone.metaWindow, time, wsIndex); }, // Draggable target interface @@ -1388,7 +1395,15 @@ Workspace.prototype = { }; let metaWindow = win.get_meta_window(); - metaWindow.change_workspace_by_index(this.metaWorkspace.index(), + + // We need to move the window before changing the workspace, because + // the move itself could cause a workspace change if the window enters + // the primary monitor + if (metaWindow.get_monitor() != this.monitorIndex) + metaWindow.move_frame(true, this._x, this._y); + + let index = this.metaWorkspace ? this.metaWorkspace.index() : global.screen.get_active_workspace_index(); + metaWindow.change_workspace_by_index(index, false, // don't create workspace time); return true; diff --git a/js/ui/workspacesView.js b/js/ui/workspacesView.js index d1631024e..e9b548a44 100644 --- a/js/ui/workspacesView.js +++ b/js/ui/workspacesView.js @@ -67,6 +67,18 @@ WorkspacesView.prototype = { this._workspaces[w].actor.reparent(this.actor); this._workspaces[activeWorkspaceIndex].actor.raise_top(); + this._extraWorkspaces = []; + let monitors = global.get_monitors(); + let m = 0; + for (let i = 0; i < monitors.length; i++) { + if (i == global.get_primary_monitor_index()) + continue; + let ws = new Workspace.Workspace(null, i); + this._extraWorkspaces[m++] = ws; + ws.setGeometry(monitors[i].x, monitors[i].y, monitors[i].width, monitors[i].height); + global.overlay_group.add_actor(ws.actor); + } + // Position/scale the desktop windows and their children after the // workspaces have been created. This cannot be done first because // window movement depends on the Workspaces object being accessible @@ -76,6 +88,8 @@ WorkspacesView.prototype = { Lang.bind(this, function() { for (let w = 0; w < this._workspaces.length; w++) this._workspaces[w].zoomToOverview(); + for (let w = 0; w < this._extraWorkspaces.length; w++) + this._extraWorkspaces[w].zoomToOverview(); })); this._overviewShownId = Main.overview.connect('shown', @@ -146,6 +160,8 @@ WorkspacesView.prototype = { for (let w = 0; w < this._workspaces.length; w++) this._workspaces[w].zoomFromOverview(); + for (let w = 0; w < this._extraWorkspaces.length; w++) + this._extraWorkspaces[w].zoomFromOverview(); }, destroy: function() { @@ -155,6 +171,8 @@ WorkspacesView.prototype = { syncStacking: function(stackIndices) { for (let i = 0; i < this._workspaces.length; i++) this._workspaces[i].syncStacking(stackIndices); + for (let i = 0; i < this._extraWorkspaces.length; i++) + this._extraWorkspaces[i].syncStacking(stackIndices); }, updateWindowPositions: function() { @@ -315,6 +333,8 @@ WorkspacesView.prototype = { }, _onDestroy: function() { + for (let i = 0; i < this._extraWorkspaces.length; i++) + this._extraWorkspaces[i].destroy(); this._scrollAdjustment.run_dispose(); Main.overview.disconnect(this._overviewShowingId); Main.overview.disconnect(this._overviewShownId);