workspacesView: Make each WorkspacesView own its set of workspaces

Right now, the workspace update code is complex and spread across parts:
WorkspacesView takes a set of workspaces and looks like it owns them, but
WorkspacesDisplay is actually in charge of setting them up and creating
new ones for each WorkspacesView.

Change initialization and handling to move all of the creation/destruction
responsibilities to WorkspacesView.

We pass in monitorIndex into each WorkspacesView, which is a lie in the
workspacesOnlyOnPrimary case, as the primary WorkspacesView currently has
the responsibility of handling the extra workspaces on all the other
monitors. The commit will clean this up and punt the responsibility back
to WorkspacesDisplay.
This commit is contained in:
Jasper St. Pierre 2013-09-11 10:09:13 -04:00
parent a5a6fd3bc2
commit d5cd534320

View File

@ -26,7 +26,7 @@ const OVERRIDE_SCHEMA = 'org.gnome.shell.overrides';
const WorkspacesView = new Lang.Class({ const WorkspacesView = new Lang.Class({
Name: 'WorkspacesView', Name: 'WorkspacesView',
_init: function(workspaces) { _init: function(monitorIndex) {
this.actor = new St.Widget({ style_class: 'workspaces-view', this.actor = new St.Widget({ style_class: 'workspaces-view',
reactive: true }); reactive: true });
@ -38,26 +38,32 @@ const WorkspacesView = new Lang.Class({
this._fullGeometry = null; this._fullGeometry = null;
this._actualGeometry = null; this._actualGeometry = null;
this._monitorIndex = monitorIndex;
this._animating = false; // tweening this._animating = false; // tweening
this._scrolling = false; // swipe-scrolling this._scrolling = false; // swipe-scrolling
this._animatingScroll = false; // programatically updating the adjustment this._animatingScroll = false; // programatically updating the adjustment
this._inDrag = false; // dragging a window this._inDrag = false; // dragging a window
this._settings = new Gio.Settings({ schema: OVERRIDE_SCHEMA }); this._settings = new Gio.Settings({ schema: OVERRIDE_SCHEMA });
this._updateExtraWorkspacesId =
this._settings.connect('changed::workspaces-only-on-primary',
Lang.bind(this, this._updateExtraWorkspaces));
let activeWorkspaceIndex = global.screen.get_active_workspace_index(); let activeWorkspaceIndex = global.screen.get_active_workspace_index();
this._workspaces = workspaces; this.scrollAdjustment = new St.Adjustment({ value: activeWorkspaceIndex,
lower: 0,
page_increment: 1,
page_size: 1,
step_increment: 0,
upper: 0 });
this.scrollAdjustment.connect('notify::value',
Lang.bind(this, this._onScroll));
// Add workspace actors this._workspaces = [];
for (let w = 0; w < global.screen.n_workspaces; w++) this._updateWorkspaces();
this.actor.add_actor(this._workspaces[w].actor); this._updateWorkspacesId = global.screen.connect('notify::n-workspaces', Lang.bind(this, this._updateWorkspaces));
this._workspaces[activeWorkspaceIndex].actor.raise_top();
this._extraWorkspaces = []; this._extraWorkspaces = [];
this._updateExtraWorkspaces(); this._updateExtraWorkspaces();
this._updateExtraWorkspacesId = this._settings.connect('changed::workspaces-only-on-primary', Lang.bind(this, this._updateExtraWorkspaces));
this._overviewShownId = this._overviewShownId =
Main.overview.connect('shown', Main.overview.connect('shown',
@ -66,15 +72,6 @@ const WorkspacesView = new Lang.Class({
this._fullGeometry.width, this._fullGeometry.height); this._fullGeometry.width, this._fullGeometry.height);
})); }));
this.scrollAdjustment = new St.Adjustment({ value: activeWorkspaceIndex,
lower: 0,
page_increment: 1,
page_size: 1,
step_increment: 0,
upper: this._workspaces.length });
this.scrollAdjustment.connect('notify::value',
Lang.bind(this, this._onScroll));
this._switchWorkspaceNotifyId = this._switchWorkspaceNotifyId =
global.window_manager.connect('switch-workspace', global.window_manager.connect('switch-workspace',
Lang.bind(this, this._activeWorkspaceChanged)); Lang.bind(this, this._activeWorkspaceChanged));
@ -110,18 +107,21 @@ const WorkspacesView = new Lang.Class({
this._extraWorkspaces = []; this._extraWorkspaces = [];
}, },
_syncGeometry: function() {
for (let i = 0; i < this._workspaces.length; i++)
this._workspaces[i].setFullGeometry(this._fullGeometry);
for (let i = 0; i < this._workspaces.length; i++)
this._workspaces[i].setActualGeometry(this._actualGeometry);
},
setFullGeometry: function(geom) { setFullGeometry: function(geom) {
this._fullGeometry = geom; this._fullGeometry = geom;
this._syncGeometry();
for (let i = 0; i < this._workspaces.length; i++)
this._workspaces[i].setFullGeometry(geom);
}, },
setActualGeometry: function(geom) { setActualGeometry: function(geom) {
this._actualGeometry = geom; this._actualGeometry = geom;
this._syncGeometry();
for (let i = 0; i < this._workspaces.length; i++)
this._workspaces[i].setActualGeometry(geom);
}, },
getActiveWorkspace: function() { getActiveWorkspace: function() {
@ -235,19 +235,31 @@ const WorkspacesView = new Lang.Class({
}); });
}, },
updateWorkspaces: function(oldNumWorkspaces, newNumWorkspaces) { _updateWorkspaces: function() {
let oldNumWorkspaces = this._workspaces.length;
let newNumWorkspaces = global.screen.n_workspaces;
this.scrollAdjustment.upper = newNumWorkspaces; this.scrollAdjustment.upper = newNumWorkspaces;
if (newNumWorkspaces > oldNumWorkspaces) { if (newNumWorkspaces > oldNumWorkspaces) {
for (let w = oldNumWorkspaces; w < newNumWorkspaces; w++) { for (let w = oldNumWorkspaces; w < newNumWorkspaces; w++) {
this._workspaces[w].setFullGeometry(this._fullGeometry); let metaWorkspace = global.screen.get_workspace_by_index(w);
if (this._actualGeometry) let workspace = new Workspace.Workspace(metaWorkspace, this._monitorIndex);
this._workspaces[w].setActualGeometry(this._actualGeometry); this._workspaces.push(workspace);
this.actor.add_actor(this._workspaces[w].actor); this.actor.add_actor(workspace.actor);
} }
this._updateWorkspaceActors(false); if (this._fullGeometry)
this._updateWorkspaceActors(false);
} else if (newNumWorkspaces < oldNumWorkspaces) {
let nRemoved = (newNumWorkspaces - oldNumWorkspaces);
let removed = this._workspaces.splice(oldNumWorkspaces, nRemoved);
removed.forEach(function(workspace) {
workspace.destroy();
});
} }
this._syncGeometry();
}, },
_activeWorkspaceChanged: function(wm, from, to, direction) { _activeWorkspaceChanged: function(wm, from, to, direction) {
@ -262,6 +274,7 @@ const WorkspacesView = new Lang.Class({
this.scrollAdjustment.run_dispose(); this.scrollAdjustment.run_dispose();
Main.overview.disconnect(this._overviewShownId); Main.overview.disconnect(this._overviewShownId);
global.window_manager.disconnect(this._switchWorkspaceNotifyId); global.window_manager.disconnect(this._switchWorkspaceNotifyId);
global.screen.disconnect(this._updateWorkspacesId);
this._settings.disconnect(this._updateExtraWorkspacesId); this._settings.disconnect(this._updateExtraWorkspacesId);
if (this._inDrag) if (this._inDrag)
@ -397,7 +410,6 @@ const WorkspacesDisplay = new Lang.Class({
this._primaryIndex = Main.layoutManager.primaryIndex; this._primaryIndex = Main.layoutManager.primaryIndex;
this._workspacesViews = []; this._workspacesViews = [];
this._workspaces = [];
this._primaryScrollAdjustment = null; this._primaryScrollAdjustment = null;
this._settings = new Gio.Settings({ schema: OVERRIDE_SCHEMA }); this._settings = new Gio.Settings({ schema: OVERRIDE_SCHEMA });
@ -406,9 +418,6 @@ const WorkspacesDisplay = new Lang.Class({
this._workspacesOnlyOnPrimaryChanged)); this._workspacesOnlyOnPrimaryChanged));
this._workspacesOnlyOnPrimaryChanged(); this._workspacesOnlyOnPrimaryChanged();
global.screen.connect('notify::n-workspaces',
Lang.bind(this, this._workspacesChanged));
this._switchWorkspaceNotifyId = 0; this._switchWorkspaceNotifyId = 0;
this._notifyOpacityId = 0; this._notifyOpacityId = 0;
@ -470,21 +479,12 @@ const WorkspacesDisplay = new Lang.Class({
this._workspacesViews[i].destroy(); this._workspacesViews[i].destroy();
this._workspacesViews = []; this._workspacesViews = [];
this._workspaces = [];
let monitors = Main.layoutManager.monitors; let monitors = Main.layoutManager.monitors;
for (let i = 0; i < monitors.length; i++) { for (let i = 0; i < monitors.length; i++) {
if (this._workspacesOnlyOnPrimary && i != this._primaryIndex) if (this._workspacesOnlyOnPrimary && i != this._primaryIndex)
continue; // we are only interested in the primary monitor continue; // we are only interested in the primary monitor
let monitorWorkspaces = []; let view = new WorkspacesView(i);
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);
let view = new WorkspacesView(monitorWorkspaces);
view.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent)); view.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
if (this._workspacesOnlyOnPrimary || i == this._primaryIndex) { if (this._workspacesOnlyOnPrimary || i == this._primaryIndex) {
this._scrollAdjustment = view.scrollAdjustment; this._scrollAdjustment = view.scrollAdjustment;
@ -607,60 +607,6 @@ const WorkspacesDisplay = new Lang.Class({
this._workspacesViews[i].syncStacking(stackIndices); this._workspacesViews[i].syncStacking(stackIndices);
}, },
_workspacesChanged: function() {
if (!this._workspacesViews.length)
return;
let oldNumWorkspaces = this._workspaces[0].length;
let newNumWorkspaces = global.screen.n_workspaces;
let active = global.screen.get_active_workspace_index();
let lostWorkspaces = [];
if (newNumWorkspaces > oldNumWorkspaces) {
let monitors = Main.layoutManager.monitors;
let m = 0;
for (let i = 0; i < monitors.length; i++) {
if (this._workspacesOnlyOnPrimary &&
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);
}
m++;
}
} else {
// Assume workspaces are only removed sequentially
// (e.g. 2,3,4 - not 2,4,7)
let removedIndex;
let removedNum = oldNumWorkspaces - newNumWorkspaces;
for (let w = 0; w < oldNumWorkspaces; w++) {
let metaWorkspace = global.screen.get_workspace_by_index(w);
if (this._workspaces[0][w].metaWorkspace != metaWorkspace) {
removedIndex = w;
break;
}
}
for (let i = 0; i < this._workspaces.length; i++) {
lostWorkspaces = this._workspaces[i].splice(removedIndex,
removedNum);
for (let l = 0; l < lostWorkspaces.length; l++) {
lostWorkspaces[l].disconnectAll();
lostWorkspaces[l].destroy();
}
}
}
for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].updateWorkspaces(oldNumWorkspaces,
newNumWorkspaces);
},
_onScrollEvent: function(actor, event) { _onScrollEvent: function(actor, event) {
if (!this.actor.mapped) if (!this.actor.mapped)
return false; return false;