workspaces-display: Implement workspaces on non-primary monitors

If workspaces-only-on-primary is false, workspaces should be shown
on each monitor; rather than letting the existing workspaces span
the entire screen, manage one workspacesView per monitor (similar
to the extra workspaces in WorkspacesView when the setting is true).

https://bugzilla.gnome.org/show_bug.cgi?id=652580
This commit is contained in:
Florian Müllner 2011-11-25 18:25:31 +01:00
parent 84dde8e9bb
commit 26df6cf35c

View File

@ -513,12 +513,18 @@ const WorkspacesDisplay = new Lang.Class({
controls.connect('scroll-event', controls.connect('scroll-event',
Lang.bind(this, this._onScrollEvent)); Lang.bind(this, this._onScrollEvent));
this._monitorIndex = Main.layoutManager.primaryIndex; this._primaryIndex = Main.layoutManager.primaryIndex;
this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox(); this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox();
controls.add_actor(this._thumbnailsBox.actor); controls.add_actor(this._thumbnailsBox.actor);
this._workspacesView = null; this._workspacesViews = null;
this._settings = new Gio.Settings({ schema: OVERRIDE_SCHEMA });
this._settings.connect('changed::workspaces-only-on-primary',
Lang.bind(this,
this._workspacesOnlyOnPrimaryChanged));
this._workspacesOnlyOnPrimaryChanged();
this._inDrag = false; this._inDrag = false;
this._cancelledDrag = false; this._cancelledDrag = false;
@ -529,6 +535,8 @@ const WorkspacesDisplay = new Lang.Class({
this._updateAlwaysZoom(); this._updateAlwaysZoom();
// If we stop hiding the overview on layout changes, we will need to
// update the _workspacesViews here
Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._updateAlwaysZoom)); Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._updateAlwaysZoom));
Main.xdndHandler.connect('drag-begin', Lang.bind(this, function(){ Main.xdndHandler.connect('drag-begin', Lang.bind(this, function(){
@ -560,17 +568,7 @@ const WorkspacesDisplay = new Lang.Class({
this._controls.show(); this._controls.show();
this._thumbnailsBox.show(); this._thumbnailsBox.show();
this._workspaces = []; this._updateWorkspacesViews();
for (let i = 0; i < global.screen.n_workspaces; i++) {
let metaWorkspace = global.screen.get_workspace_by_index(i);
this._workspaces[i] = new Workspace.Workspace(metaWorkspace, this._monitorIndex);
}
if (this._workspacesView)
this._workspacesView.destroy();
this._workspacesView = new WorkspacesView(this._workspaces);
this._updateWorkspacesGeometry();
global.overlay_group.add_actor(this._workspacesView.actor);
this._restackedNotifyId = this._restackedNotifyId =
global.screen.connect('restacked', global.screen.connect('restacked',
@ -602,7 +600,9 @@ const WorkspacesDisplay = new Lang.Class({
}, },
zoomFromOverview: function() { zoomFromOverview: function() {
this._workspacesView.hide(); for (let i = 0; i < this._workspacesViews.length; i++) {
this._workspacesViews[i].hide();
}
}, },
hide: function() { hide: function() {
@ -638,16 +638,70 @@ const WorkspacesDisplay = new Lang.Class({
this._windowDragEndId = 0; this._windowDragEndId = 0;
} }
this._workspacesView.destroy(); for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesView = null; this._workspacesViews[i].destroy();
for (let w = 0; w < this._workspaces.length; w++) { this._workspacesViews = null;
this._workspaces[w].disconnectAll();
this._workspaces[w].destroy(); for (let i = 0; i < this._workspaces.length; i++)
for (let w = 0; w < this._workspaces[i].length; w++) {
this._workspaces[i][w].disconnectAll();
this._workspaces[i][w].destroy();
}
},
_workspacesOnlyOnPrimaryChanged: function() {
this._workspacesOnlyOnPrimary = this._settings.get_boolean('workspaces-only-on-primary');
if (!Main.overview.visible)
return;
this._updateWorkspacesViews();
},
_updateWorkspacesViews: function() {
if (this._workspacesViews)
for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].destroy();
if (this._workspaces)
for (let i = 0; i < this._workspaces.length; i++)
for (let w = 0; w < this._workspaces[i].length; w++)
this._workspaces[i][w].destroy();
this._workspacesViews = [];
this._workspaces = [];
let monitors = Main.layoutManager.monitors;
for (let i = 0; i < monitors.length; i++) {
if (this._workspacesOnlyOnPrimary && i != this._primaryIndex)
continue; // we are only interested in the primary monitor
let monitorWorkspaces = [];
for (let w = 0; w < global.screen.n_workspaces; w++) {
let metaWorkspace = global.screen.get_workspace_by_index(w);
monitorWorkspaces.push(new Workspace.Workspace(metaWorkspace, i));
}
this._workspaces.push(monitorWorkspaces);
this._workspacesViews.push(new WorkspacesView(monitorWorkspaces));
} }
this._updateWorkspacesGeometry();
for (let i = 0; i < this._workspacesViews.length; i++)
global.overlay_group.add_actor(this._workspacesViews[i].actor);
},
_getPrimaryView: function() {
if (!this._workspacesViews)
return null;
if (this._workspacesOnlyOnPrimary)
return this._workspacesViews[0];
else
return this._workspacesViews[this._primaryIndex];
}, },
activeWorkspaceHasMaximizedWindows: function() { activeWorkspaceHasMaximizedWindows: function() {
return this._workspacesView.getActiveWorkspace().hasMaximizedWindows(); return this._getPrimaryView().getActiveWorkspace().hasMaximizedWindows();
}, },
// zoomFraction property allows us to tween the controls sliding in and out // zoomFraction property allows us to tween the controls sliding in and out
@ -737,17 +791,20 @@ const WorkspacesDisplay = new Lang.Class({
this._notifyOpacityId = newParent.connect('notify::opacity', this._notifyOpacityId = newParent.connect('notify::opacity',
Lang.bind(this, function() { Lang.bind(this, function() {
let opacity = this.actor.get_parent().opacity; let opacity = this.actor.get_parent().opacity;
this._workspacesView.actor.opacity = opacity; let primaryView = this._getPrimaryView();
if (!primaryView)
return;
primaryView.actor.opacity = opacity;
if (opacity == 0) if (opacity == 0)
this._workspacesView.actor.hide(); primaryView.actor.hide();
else else
this._workspacesView.actor.show(); primaryView.actor.show();
})); }));
})); }));
}, },
_updateWorkspacesGeometry: function() { _updateWorkspacesGeometry: function() {
if (!this._workspacesView) if (!this._workspacesViews)
return; return;
let fullWidth = this.actor.allocation.x2 - this.actor.allocation.x1; let fullWidth = this.actor.allocation.x2 - this.actor.allocation.x1;
@ -768,8 +825,6 @@ const WorkspacesDisplay = new Lang.Class({
let clipX = rtl ? x + controlsVisible : x; let clipX = rtl ? x + controlsVisible : x;
let clipY = y + (fullHeight - clipHeight) / 2; let clipY = y + (fullHeight - clipHeight) / 2;
this._workspacesView.setClipRect(clipX, clipY, clipWidth, clipHeight);
if (this._zoomOut) { if (this._zoomOut) {
width -= controlsNatural; width -= controlsNatural;
if (rtl) if (rtl)
@ -784,7 +839,28 @@ const WorkspacesDisplay = new Lang.Class({
let difference = fullHeight - height; let difference = fullHeight - height;
y += difference / 2; y += difference / 2;
this._workspacesView.setGeometry(x, y, width, height, difference);
let monitors = Main.layoutManager.monitors;
let m = 0;
for (let i = 0; i < monitors.length; i++) {
if (i == this._primaryIndex) {
this._workspacesViews[m].setClipRect(clipX, clipY,
clipWidth, clipHeight);
this._workspacesViews[m].setGeometry(x, y, width, height,
difference);
m++;
} else if (!this._workspacesOnlyOnPrimary) {
this._workspacesViews[m].setClipRect(monitors[i].x,
monitors[i].y,
monitors[i].width,
monitors[i].height);
this._workspacesViews[m].setGeometry(monitors[i].x,
monitors[i].y,
monitors[i].width,
monitors[i].height, 0);
m++;
}
}
}, },
_onRestacked: function() { _onRestacked: function() {
@ -796,12 +872,14 @@ const WorkspacesDisplay = new Lang.Class({
stackIndices[stack[i].get_meta_window().get_stable_sequence()] = i; stackIndices[stack[i].get_meta_window().get_stable_sequence()] = i;
} }
this._workspacesView.syncStacking(stackIndices); for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].syncStacking(stackIndices);
this._thumbnailsBox.syncStacking(stackIndices); this._thumbnailsBox.syncStacking(stackIndices);
}, },
_workspacesChanged: function() { _workspacesChanged: function() {
let oldNumWorkspaces = this._workspaces.length; let oldNumWorkspaces = this._workspaces[0].length;
let newNumWorkspaces = global.screen.n_workspaces; let newNumWorkspaces = global.screen.n_workspaces;
let active = global.screen.get_active_workspace_index(); let active = global.screen.get_active_workspace_index();
@ -811,15 +889,24 @@ const WorkspacesDisplay = new Lang.Class({
this._updateAlwaysZoom(); this._updateAlwaysZoom();
this._updateZoom(); this._updateZoom();
if (this._workspacesView == null) if (this._workspacesViews == null)
return; return;
let lostWorkspaces = []; let lostWorkspaces = [];
if (newNumWorkspaces > oldNumWorkspaces) { if (newNumWorkspaces > oldNumWorkspaces) {
// Assume workspaces are only added at the end let monitors = Main.layoutManager.monitors;
for (let w = oldNumWorkspaces; w < newNumWorkspaces; w++) { let m = 0;
let metaWorkspace = global.screen.get_workspace_by_index(w); for (let i = 0; i < monitors.length; i++) {
this._workspaces[w] = new Workspace.Workspace(metaWorkspace, this._monitorIndex); if (this._workspacesOnlyOnPrimaryChanged &&
i != this._primaryIndex)
continue;
// Assume workspaces are only added at the end
for (let w = oldNumWorkspaces; w < newNumWorkspaces; w++) {
let metaWorkspace = global.screen.get_workspace_by_index(w);
this._workspaces[m++][w] =
new Workspace.Workspace(metaWorkspace, i);
}
} }
this._thumbnailsBox.addThumbnails(oldNumWorkspaces, newNumWorkspaces - oldNumWorkspaces); this._thumbnailsBox.addThumbnails(oldNumWorkspaces, newNumWorkspaces - oldNumWorkspaces);
@ -830,25 +917,28 @@ const WorkspacesDisplay = new Lang.Class({
let removedNum = oldNumWorkspaces - newNumWorkspaces; let removedNum = oldNumWorkspaces - newNumWorkspaces;
for (let w = 0; w < oldNumWorkspaces; w++) { for (let w = 0; w < oldNumWorkspaces; w++) {
let metaWorkspace = global.screen.get_workspace_by_index(w); let metaWorkspace = global.screen.get_workspace_by_index(w);
if (this._workspaces[w].metaWorkspace != metaWorkspace) { if (this._workspaces[0][w].metaWorkspace != metaWorkspace) {
removedIndex = w; removedIndex = w;
break; break;
} }
} }
lostWorkspaces = this._workspaces.splice(removedIndex, for (let i = 0; i < this._workspaces.length; i++) {
removedNum); lostWorkspaces = this._workspaces[i].splice(removedIndex,
removedNum);
for (let l = 0; l < lostWorkspaces.length; l++) { for (let l = 0; l < lostWorkspaces.length; l++) {
lostWorkspaces[l].disconnectAll(); lostWorkspaces[l].disconnectAll();
lostWorkspaces[l].destroy(); lostWorkspaces[l].destroy();
}
} }
this._thumbnailsBox.removeThumbmails(removedIndex, removedNum); this._thumbnailsBox.removeThumbmails(removedIndex, removedNum);
} }
this._workspacesView.updateWorkspaces(oldNumWorkspaces, for (let i = 0; i < this._workspacesViews.length; i++)
newNumWorkspaces); this._workspacesViews[i].updateWorkspaces(oldNumWorkspaces,
newNumWorkspaces);
}, },
_updateZoom : function() { _updateZoom : function() {
@ -860,7 +950,7 @@ const WorkspacesDisplay = new Lang.Class({
this._zoomOut = shouldZoom; this._zoomOut = shouldZoom;
this._updateWorkspacesGeometry(); this._updateWorkspacesGeometry();
if (!this._workspacesView) if (!this._workspacesViews)
return; return;
Tweener.addTween(this, Tweener.addTween(this,
@ -868,7 +958,8 @@ const WorkspacesDisplay = new Lang.Class({
time: WORKSPACE_SWITCH_TIME, time: WORKSPACE_SWITCH_TIME,
transition: 'easeOutQuad' }); transition: 'easeOutQuad' });
this._workspacesView.updateWindowPositions(); for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].updateWindowPositions();
} }
}, },