Add workspaces on non-primary monitors

We create a Workspace with a null metaWorkspace for each
non-primary monitor, showing the windows on these monitors.
These are saved in WorkspaceView.extraWorkspaces.

https://bugzilla.gnome.org/show_bug.cgi?id=609258
This commit is contained in:
Alexander Larsson 2011-03-03 22:33:27 +01:00
parent cdd1209b55
commit e5f05bc9d8
2 changed files with 49 additions and 14 deletions

View File

@ -541,7 +541,7 @@ const WindowPositionFlags = {
}; };
/** /**
* @metaWorkspace: a #Meta.Workspace * @metaWorkspace: a #Meta.Workspace, or null
*/ */
function Workspace(metaWorkspace, monitorIndex) { function Workspace(metaWorkspace, monitorIndex) {
this._init(metaWorkspace, monitorIndex); this._init(metaWorkspace, monitorIndex);
@ -587,10 +587,12 @@ Workspace.prototype = {
} }
// Track window changes // Track window changes
if (this.metaWorkspace) {
this._windowAddedId = this.metaWorkspace.connect('window-added', this._windowAddedId = this.metaWorkspace.connect('window-added',
Lang.bind(this, this._windowAdded)); Lang.bind(this, this._windowAdded));
this._windowRemovedId = this.metaWorkspace.connect('window-removed', this._windowRemovedId = this.metaWorkspace.connect('window-removed',
Lang.bind(this, this._windowRemoved)); Lang.bind(this, this._windowRemoved));
}
this._windowEnteredMonitorId = global.screen.connect('window-entered-monitor', this._windowEnteredMonitorId = global.screen.connect('window-entered-monitor',
Lang.bind(this, this._windowEnteredMonitor)); Lang.bind(this, this._windowEnteredMonitor));
this._windowLeftMonitorId = global.screen.connect('window-left-monitor', this._windowLeftMonitorId = global.screen.connect('window-left-monitor',
@ -902,7 +904,7 @@ Workspace.prototype = {
clones = this._orderWindowsByMotionAndStartup(clones, slots); clones = this._orderWindowsByMotionAndStartup(clones, slots);
let currentWorkspace = global.screen.get_active_workspace(); 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++) { for (let i = 0; i < clones.length; i++) {
let slot = slots[i]; let slot = slots[i];
@ -1005,7 +1007,8 @@ Workspace.prototype = {
for (let i = 0; i < this._windows.length; i++) { for (let i = 0; i < this._windows.length; i++) {
let clone = this._windows[i]; let clone = this._windows[i];
let overlay = this._windowOverlays[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._overviewHiddenId = Main.overview.connect('hidden', Lang.bind(this,
this._doneLeavingOverview)); this._doneLeavingOverview));
if (this.metaWorkspace != currentWorkspace) if (this.metaWorkspace != null && this.metaWorkspace != currentWorkspace)
return; return;
// Position and scale the windows. // Position and scale the windows.
@ -1246,8 +1249,10 @@ Workspace.prototype = {
} }
Tweener.removeTweens(actor); Tweener.removeTweens(actor);
if (this.metaWorkspace) {
this.metaWorkspace.disconnect(this._windowAddedId); this.metaWorkspace.disconnect(this._windowAddedId);
this.metaWorkspace.disconnect(this._windowRemovedId); this.metaWorkspace.disconnect(this._windowRemovedId);
}
global.screen.disconnect(this._windowEnteredMonitorId); global.screen.disconnect(this._windowEnteredMonitorId);
global.screen.disconnect(this._windowLeftMonitorId); global.screen.disconnect(this._windowLeftMonitorId);
@ -1270,7 +1275,7 @@ Workspace.prototype = {
// Tests if @win belongs to this workspaces and monitor // Tests if @win belongs to this workspaces and monitor
_isMyWindow : function (win) { _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); (!win.get_meta_window() || win.get_meta_window().get_monitor() == this.monitorIndex);
}, },
@ -1359,8 +1364,10 @@ Workspace.prototype = {
}, },
_onCloneSelected : function (clone, time) { _onCloneSelected : function (clone, time) {
Main.activateWindow(clone.metaWindow, time, let wsIndex = undefined;
this.metaWorkspace.index()); if (this.metaWorkspace)
wsIndex = this.metaWorkspace.index();
Main.activateWindow(clone.metaWindow, time, wsIndex);
}, },
// Draggable target interface // Draggable target interface
@ -1388,7 +1395,15 @@ Workspace.prototype = {
}; };
let metaWindow = win.get_meta_window(); 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 false, // don't create workspace
time); time);
return true; return true;

View File

@ -67,6 +67,18 @@ WorkspacesView.prototype = {
this._workspaces[w].actor.reparent(this.actor); this._workspaces[w].actor.reparent(this.actor);
this._workspaces[activeWorkspaceIndex].actor.raise_top(); 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 // Position/scale the desktop windows and their children after the
// workspaces have been created. This cannot be done first because // workspaces have been created. This cannot be done first because
// window movement depends on the Workspaces object being accessible // window movement depends on the Workspaces object being accessible
@ -76,6 +88,8 @@ WorkspacesView.prototype = {
Lang.bind(this, function() { Lang.bind(this, function() {
for (let w = 0; w < this._workspaces.length; w++) for (let w = 0; w < this._workspaces.length; w++)
this._workspaces[w].zoomToOverview(); this._workspaces[w].zoomToOverview();
for (let w = 0; w < this._extraWorkspaces.length; w++)
this._extraWorkspaces[w].zoomToOverview();
})); }));
this._overviewShownId = this._overviewShownId =
Main.overview.connect('shown', Main.overview.connect('shown',
@ -146,6 +160,8 @@ WorkspacesView.prototype = {
for (let w = 0; w < this._workspaces.length; w++) for (let w = 0; w < this._workspaces.length; w++)
this._workspaces[w].zoomFromOverview(); this._workspaces[w].zoomFromOverview();
for (let w = 0; w < this._extraWorkspaces.length; w++)
this._extraWorkspaces[w].zoomFromOverview();
}, },
destroy: function() { destroy: function() {
@ -155,6 +171,8 @@ WorkspacesView.prototype = {
syncStacking: function(stackIndices) { syncStacking: function(stackIndices) {
for (let i = 0; i < this._workspaces.length; i++) for (let i = 0; i < this._workspaces.length; i++)
this._workspaces[i].syncStacking(stackIndices); this._workspaces[i].syncStacking(stackIndices);
for (let i = 0; i < this._extraWorkspaces.length; i++)
this._extraWorkspaces[i].syncStacking(stackIndices);
}, },
updateWindowPositions: function() { updateWindowPositions: function() {
@ -315,6 +333,8 @@ WorkspacesView.prototype = {
}, },
_onDestroy: function() { _onDestroy: function() {
for (let i = 0; i < this._extraWorkspaces.length; i++)
this._extraWorkspaces[i].destroy();
this._scrollAdjustment.run_dispose(); this._scrollAdjustment.run_dispose();
Main.overview.disconnect(this._overviewShowingId); Main.overview.disconnect(this._overviewShowingId);
Main.overview.disconnect(this._overviewShownId); Main.overview.disconnect(this._overviewShownId);