Make a separate class for workspace thumbnails box
Add WorkspaceThumbnail.ThumbnailsBox to handle managing the array of workspace thumbnails; the logic will get more complex as we add scaling and animation. https://bugzilla.gnome.org/show_bug.cgi?id=641879
This commit is contained in:
parent
493e82e37d
commit
ae5131f902
@ -9,7 +9,9 @@ const St = imports.gi.St;
|
|||||||
|
|
||||||
const DND = imports.ui.dnd;
|
const DND = imports.ui.dnd;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
|
const Tweener = imports.ui.tweener;
|
||||||
const Workspace = imports.ui.workspace;
|
const Workspace = imports.ui.workspace;
|
||||||
|
const WorkspacesView = imports.ui.workspacesView;
|
||||||
|
|
||||||
// Fraction of original screen size for thumbnails
|
// Fraction of original screen size for thumbnails
|
||||||
let THUMBNAIL_SCALE = 1/8.;
|
let THUMBNAIL_SCALE = 1/8.;
|
||||||
@ -319,3 +321,126 @@ WorkspaceThumbnail.prototype = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Signals.addSignalMethods(WorkspaceThumbnail.prototype);
|
Signals.addSignalMethods(WorkspaceThumbnail.prototype);
|
||||||
|
|
||||||
|
|
||||||
|
function ThumbnailsBox() {
|
||||||
|
this._init();
|
||||||
|
}
|
||||||
|
|
||||||
|
ThumbnailsBox.prototype = {
|
||||||
|
_init: function() {
|
||||||
|
this.actor = new St.BoxLayout({ vertical: true,
|
||||||
|
style_class: 'workspace-thumbnails' });
|
||||||
|
|
||||||
|
let indicator = new St.Bin({ style_class: 'workspace-thumbnail-indicator',
|
||||||
|
fixed_position_set: true });
|
||||||
|
|
||||||
|
// We don't want the indicator to affect drag-and-drop
|
||||||
|
Shell.util_set_hidden_from_pick(indicator, true);
|
||||||
|
|
||||||
|
this._indicator = indicator;
|
||||||
|
this.actor.add(indicator);
|
||||||
|
this._indicatorConstraints = [];
|
||||||
|
this._indicatorConstraints.push(new Clutter.BindConstraint({ coordinate: Clutter.BindCoordinate.POSITION }));
|
||||||
|
this._indicatorConstraints.push(new Clutter.BindConstraint({ coordinate: Clutter.BindCoordinate.SIZE }));
|
||||||
|
this._indicatorConstraints.forEach(function(constraint) {
|
||||||
|
indicator.add_constraint(constraint);
|
||||||
|
});
|
||||||
|
|
||||||
|
this._thumbnails = [];
|
||||||
|
},
|
||||||
|
|
||||||
|
show: function() {
|
||||||
|
this._switchWorkspaceNotifyId =
|
||||||
|
global.window_manager.connect('switch-workspace',
|
||||||
|
Lang.bind(this, this._activeWorkspaceChanged));
|
||||||
|
|
||||||
|
this.addThumbnails(0, global.screen.n_workspaces);
|
||||||
|
this._constrainThumbnailIndicator();
|
||||||
|
},
|
||||||
|
|
||||||
|
hide: function() {
|
||||||
|
this._unconstrainThumbnailIndicator();
|
||||||
|
|
||||||
|
if (this._switchWorkspaceNotifyId > 0) {
|
||||||
|
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
|
||||||
|
this._switchWorkspaceNotifyId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let w = 0; w < this._thumbnails.length; w++)
|
||||||
|
this._thumbnails[w].destroy();
|
||||||
|
this._thumbnails = [];
|
||||||
|
},
|
||||||
|
|
||||||
|
addThumbnails: function(start, count) {
|
||||||
|
for (let k = start; k < start + count; k++) {
|
||||||
|
let metaWorkspace = global.screen.get_workspace_by_index(k);
|
||||||
|
let thumbnail = new WorkspaceThumbnail(metaWorkspace);
|
||||||
|
this._thumbnails[k] = thumbnail;
|
||||||
|
this.actor.add(thumbnail.actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The thumbnails indicator actually needs to be on top of the thumbnails, but
|
||||||
|
// there is also something more subtle going on as well - actors in a StBoxLayout
|
||||||
|
// are allocated from bottom to top (start to end), and we need the
|
||||||
|
// thumnail indicator to be allocated after the actors it is constrained to.
|
||||||
|
this._indicator.raise_top();
|
||||||
|
},
|
||||||
|
|
||||||
|
removeThumbmails: function(start, count) {
|
||||||
|
for (let k = start; k < start + count; k++)
|
||||||
|
this._thumbnails[k].destroy();
|
||||||
|
this._thumbnails.splice(start, count);
|
||||||
|
|
||||||
|
// If we removed the current workspace, then metacity will have already
|
||||||
|
// switched to an adjacent workspace. Leaving the animation we
|
||||||
|
// started in response to that around will look funny because it's an
|
||||||
|
// animation for the *old* workspace configuration. So, kill it.
|
||||||
|
// If we animate the workspace removal in the future, we should animate
|
||||||
|
// the indicator as part of that.
|
||||||
|
Tweener.removeTweens(this._thumbnailIndicator);
|
||||||
|
this._constrainThumbnailIndicator();
|
||||||
|
},
|
||||||
|
|
||||||
|
syncStacking: function(stackIndices) {
|
||||||
|
for (let i = 0; i < this._thumbnails.length; i++)
|
||||||
|
this._thumbnails[i].syncStacking(stackIndices);
|
||||||
|
},
|
||||||
|
|
||||||
|
_constrainThumbnailIndicator: function() {
|
||||||
|
let active = global.screen.get_active_workspace_index();
|
||||||
|
let thumbnail = this._thumbnails[active];
|
||||||
|
|
||||||
|
this._indicatorConstraints.forEach(function(constraint) {
|
||||||
|
constraint.set_source(thumbnail.actor);
|
||||||
|
constraint.set_enabled(true);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_unconstrainThumbnailIndicator: function() {
|
||||||
|
this._indicatorConstraints.forEach(function(constraint) {
|
||||||
|
constraint.set_enabled(false);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_activeWorkspaceChanged: function(wm, from, to, direction) {
|
||||||
|
let active = global.screen.get_active_workspace_index();
|
||||||
|
let thumbnail = this._thumbnails[active];
|
||||||
|
|
||||||
|
this._unconstrainThumbnailIndicator();
|
||||||
|
let oldAllocation = this._indicator.allocation;
|
||||||
|
this._indicator.x = oldAllocation.x1;
|
||||||
|
this._indicator.y = oldAllocation.y1;
|
||||||
|
this._indicator.width = oldAllocation.x2 - oldAllocation.x1;
|
||||||
|
this._indicator.height = oldAllocation.y2 - oldAllocation.y1;
|
||||||
|
|
||||||
|
Tweener.addTween(this._indicator,
|
||||||
|
{ x: thumbnail.actor.allocation.x1,
|
||||||
|
y: thumbnail.actor.allocation.y1,
|
||||||
|
time: WorkspacesView.WORKSPACE_SWITCH_TIME,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
onComplete: Lang.bind(this,
|
||||||
|
this._constrainThumbnailIndicator)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@ -604,24 +604,8 @@ WorkspacesDisplay.prototype = {
|
|||||||
controls.connect('notify::hover',
|
controls.connect('notify::hover',
|
||||||
Lang.bind(this, this._onControlsHoverChanged));
|
Lang.bind(this, this._onControlsHoverChanged));
|
||||||
|
|
||||||
this._thumbnailsBox = new St.BoxLayout({ vertical: true,
|
this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox();
|
||||||
style_class: 'workspace-thumbnails' });
|
controls.add(this._thumbnailsBox.actor, { expand: false });
|
||||||
controls.add(this._thumbnailsBox, { expand: false });
|
|
||||||
|
|
||||||
let indicator = new St.Bin({ style_class: 'workspace-thumbnail-indicator',
|
|
||||||
fixed_position_set: true });
|
|
||||||
|
|
||||||
// We don't want the indicator to affect drag-and-drop
|
|
||||||
Shell.util_set_hidden_from_pick(indicator, true);
|
|
||||||
|
|
||||||
this._thumbnailIndicator = indicator;
|
|
||||||
this._thumbnailsBox.add(this._thumbnailIndicator);
|
|
||||||
this._thumbnailIndicatorConstraints = [];
|
|
||||||
this._thumbnailIndicatorConstraints.push(new Clutter.BindConstraint({ coordinate: Clutter.BindCoordinate.POSITION }));
|
|
||||||
this._thumbnailIndicatorConstraints.push(new Clutter.BindConstraint({ coordinate: Clutter.BindCoordinate.SIZE }));
|
|
||||||
this._thumbnailIndicatorConstraints.forEach(function(constraint) {
|
|
||||||
indicator.add_constraint(constraint);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.workspacesView = null;
|
this.workspacesView = null;
|
||||||
|
|
||||||
@ -640,24 +624,14 @@ WorkspacesDisplay.prototype = {
|
|||||||
|
|
||||||
show: function() {
|
show: function() {
|
||||||
this._controls.show();
|
this._controls.show();
|
||||||
|
this._thumbnailsBox.show();
|
||||||
|
|
||||||
this._workspaces = [];
|
this._workspaces = [];
|
||||||
this._workspaceThumbnails = [];
|
|
||||||
for (let i = 0; i < global.screen.n_workspaces; i++) {
|
for (let i = 0; i < global.screen.n_workspaces; i++) {
|
||||||
let metaWorkspace = global.screen.get_workspace_by_index(i);
|
let metaWorkspace = global.screen.get_workspace_by_index(i);
|
||||||
this._workspaces[i] = new Workspace.Workspace(metaWorkspace);
|
this._workspaces[i] = new Workspace.Workspace(metaWorkspace);
|
||||||
|
|
||||||
let thumbnail = new WorkspaceThumbnail.WorkspaceThumbnail(metaWorkspace);
|
|
||||||
this._workspaceThumbnails[i] = thumbnail;
|
|
||||||
this._thumbnailsBox.add(thumbnail.actor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The thumbnails indicator actually needs to be on top of the thumbnails, but
|
|
||||||
// there is also something more subtle going on as well - actors in a StBoxLayout
|
|
||||||
// are allocated from bottom to top (start to end), and we need the
|
|
||||||
// thumnail indicator to be allocated after the actors it is constrained to.
|
|
||||||
this._thumbnailIndicator.raise_top();
|
|
||||||
|
|
||||||
let rtl = (St.Widget.get_default_direction () == St.TextDirection.RTL);
|
let rtl = (St.Widget.get_default_direction () == St.TextDirection.RTL);
|
||||||
|
|
||||||
let totalAllocation = this.actor.allocation;
|
let totalAllocation = this.actor.allocation;
|
||||||
@ -700,9 +674,6 @@ WorkspacesDisplay.prototype = {
|
|||||||
this._nWorkspacesNotifyId =
|
this._nWorkspacesNotifyId =
|
||||||
global.screen.connect('notify::n-workspaces',
|
global.screen.connect('notify::n-workspaces',
|
||||||
Lang.bind(this, this._workspacesChanged));
|
Lang.bind(this, this._workspacesChanged));
|
||||||
this._switchWorkspaceNotifyId =
|
|
||||||
global.window_manager.connect('switch-workspace',
|
|
||||||
Lang.bind(this, this._activeWorkspaceChanged));
|
|
||||||
|
|
||||||
this._restackedNotifyId =
|
this._restackedNotifyId =
|
||||||
global.screen.connect('restacked',
|
global.screen.connect('restacked',
|
||||||
@ -722,7 +693,6 @@ WorkspacesDisplay.prototype = {
|
|||||||
Lang.bind(this, this._dragEnd));
|
Lang.bind(this, this._dragEnd));
|
||||||
|
|
||||||
this._onRestacked();
|
this._onRestacked();
|
||||||
this._constrainThumbnailIndicator();
|
|
||||||
this._zoomOut = false;
|
this._zoomOut = false;
|
||||||
this._zoomFraction = 0;
|
this._zoomFraction = 0;
|
||||||
this._updateZoom();
|
this._updateZoom();
|
||||||
@ -730,15 +700,12 @@ WorkspacesDisplay.prototype = {
|
|||||||
|
|
||||||
hide: function() {
|
hide: function() {
|
||||||
this._controls.hide();
|
this._controls.hide();
|
||||||
|
this._thumbnailsBox.hide();
|
||||||
|
|
||||||
if (this._nWorkspacesNotifyId > 0) {
|
if (this._nWorkspacesNotifyId > 0) {
|
||||||
global.screen.disconnect(this._nWorkspacesNotifyId);
|
global.screen.disconnect(this._nWorkspacesNotifyId);
|
||||||
this._nWorkspacesNotifyId = 0;
|
this._nWorkspacesNotifyId = 0;
|
||||||
}
|
}
|
||||||
if (this._switchWorkspaceNotifyId > 0) {
|
|
||||||
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
|
|
||||||
this._switchWorkspaceNotifyId = 0;
|
|
||||||
}
|
|
||||||
if (this._restackedNotifyId > 0){
|
if (this._restackedNotifyId > 0){
|
||||||
global.screen.disconnect(this._restackedNotifyId);
|
global.screen.disconnect(this._restackedNotifyId);
|
||||||
this._restackedNotifyId = 0;
|
this._restackedNotifyId = 0;
|
||||||
@ -762,11 +729,9 @@ WorkspacesDisplay.prototype = {
|
|||||||
|
|
||||||
this.workspacesView.destroy();
|
this.workspacesView.destroy();
|
||||||
this.workspacesView = null;
|
this.workspacesView = null;
|
||||||
this._unconstrainThumbnailIndicator();
|
|
||||||
for (let w = 0; w < this._workspaces.length; w++) {
|
for (let w = 0; w < this._workspaces.length; w++) {
|
||||||
this._workspaces[w].disconnectAll();
|
this._workspaces[w].disconnectAll();
|
||||||
this._workspaces[w].destroy();
|
this._workspaces[w].destroy();
|
||||||
this._workspaceThumbnails[w].destroy();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -815,43 +780,6 @@ WorkspacesDisplay.prototype = {
|
|||||||
this._controls.allocate(childBox, flags);
|
this._controls.allocate(childBox, flags);
|
||||||
},
|
},
|
||||||
|
|
||||||
_constrainThumbnailIndicator: function() {
|
|
||||||
let active = global.screen.get_active_workspace_index();
|
|
||||||
let thumbnail = this._workspaceThumbnails[active];
|
|
||||||
|
|
||||||
this._thumbnailIndicatorConstraints.forEach(function(constraint) {
|
|
||||||
constraint.set_source(thumbnail.actor);
|
|
||||||
constraint.set_enabled(true);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
_unconstrainThumbnailIndicator: function() {
|
|
||||||
this._thumbnailIndicatorConstraints.forEach(function(constraint) {
|
|
||||||
constraint.set_enabled(false);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
_activeWorkspaceChanged: function(wm, from, to, direction) {
|
|
||||||
let active = global.screen.get_active_workspace_index();
|
|
||||||
let thumbnail = this._workspaceThumbnails[active];
|
|
||||||
|
|
||||||
this._unconstrainThumbnailIndicator();
|
|
||||||
let oldAllocation = this._thumbnailIndicator.allocation;
|
|
||||||
this._thumbnailIndicator.x = oldAllocation.x1;
|
|
||||||
this._thumbnailIndicator.y = oldAllocation.y1;
|
|
||||||
this._thumbnailIndicator.width = oldAllocation.x2 - oldAllocation.x1;
|
|
||||||
this._thumbnailIndicator.height = oldAllocation.y2 - oldAllocation.y1;
|
|
||||||
|
|
||||||
Tweener.addTween(this._thumbnailIndicator,
|
|
||||||
{ x: thumbnail.actor.allocation.x1,
|
|
||||||
y: thumbnail.actor.allocation.y1,
|
|
||||||
time: WORKSPACE_SWITCH_TIME,
|
|
||||||
transition: 'easeOutQuad',
|
|
||||||
onComplete: Lang.bind(this,
|
|
||||||
this._constrainThumbnailIndicator)
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
_onRestacked: function() {
|
_onRestacked: function() {
|
||||||
let stack = global.get_window_actors();
|
let stack = global.get_window_actors();
|
||||||
let stackIndices = {};
|
let stackIndices = {};
|
||||||
@ -862,8 +790,7 @@ WorkspacesDisplay.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.workspacesView.syncStacking(stackIndices);
|
this.workspacesView.syncStacking(stackIndices);
|
||||||
for (let i = 0; i < this._workspaceThumbnails.length; i++)
|
this._thumbnailsBox.syncStacking(stackIndices);
|
||||||
this._workspaceThumbnails[i].syncStacking(stackIndices);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_workspacesChanged: function() {
|
_workspacesChanged: function() {
|
||||||
@ -880,12 +807,9 @@ WorkspacesDisplay.prototype = {
|
|||||||
for (let w = oldNumWorkspaces; w < newNumWorkspaces; w++) {
|
for (let w = oldNumWorkspaces; w < newNumWorkspaces; w++) {
|
||||||
let metaWorkspace = global.screen.get_workspace_by_index(w);
|
let metaWorkspace = global.screen.get_workspace_by_index(w);
|
||||||
this._workspaces[w] = new Workspace.Workspace(metaWorkspace);
|
this._workspaces[w] = new Workspace.Workspace(metaWorkspace);
|
||||||
|
|
||||||
let thumbnail = new WorkspaceThumbnail.WorkspaceThumbnail(metaWorkspace);
|
|
||||||
this._workspaceThumbnails[w] = thumbnail;
|
|
||||||
this._thumbnailsBox.add(thumbnail.actor);
|
|
||||||
}
|
}
|
||||||
this._thumbnailIndicator.raise_top();
|
|
||||||
|
this._thumbnailsBox.addThumbnails(oldNumWorkspaces, newNumWorkspaces - oldNumWorkspaces);
|
||||||
} else {
|
} else {
|
||||||
// Assume workspaces are only removed sequentially
|
// Assume workspaces are only removed sequentially
|
||||||
// (e.g. 2,3,4 - not 2,4,7)
|
// (e.g. 2,3,4 - not 2,4,7)
|
||||||
@ -907,20 +831,9 @@ WorkspacesDisplay.prototype = {
|
|||||||
for (let l = 0; l < lostWorkspaces.length; l++)
|
for (let l = 0; l < lostWorkspaces.length; l++)
|
||||||
lostWorkspaces[l].setReactive(false);
|
lostWorkspaces[l].setReactive(false);
|
||||||
|
|
||||||
for (let k = removedIndex; k < removedIndex + removedNum; k++)
|
this._thumbnailsBox.removeThumbmails(removedIndex, removedNum);
|
||||||
this._workspaceThumbnails[k].destroy();
|
|
||||||
this._workspaceThumbnails.splice(removedIndex, removedNum);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we removed the current workspace, then metacity will have already
|
|
||||||
// switched to an adjacent workspace. Leaving the animation we
|
|
||||||
// started in response to that around will look funny because it's an
|
|
||||||
// animation for the *old* workspace configuration. So, kill it.
|
|
||||||
// If we animate the workspace removal in the future, we should animate
|
|
||||||
// the indicator as part of that.
|
|
||||||
Tweener.removeTweens(this._thumbnailIndicator);
|
|
||||||
this._constrainThumbnailIndicator();
|
|
||||||
|
|
||||||
this.workspacesView.updateWorkspaces(oldNumWorkspaces,
|
this.workspacesView.updateWorkspaces(oldNumWorkspaces,
|
||||||
newNumWorkspaces,
|
newNumWorkspaces,
|
||||||
lostWorkspaces);
|
lostWorkspaces);
|
||||||
|
Loading…
Reference in New Issue
Block a user