Slide workspace thumbnails in when added and out when removed
To explain to the user what is happening, instead of abruptly changing updating the workspace thumbnail list, slide thubmnails in and out as they are added and removed. To implement this, we track a state for each thumbnail and when things change go through a process of first sliding removed thumbnails out, then ollapsing the left-over spaces and rescaling the thumbnails, then finally sliding newly added thumbnails in. https://bugzilla.gnome.org/show_bug.cgi?id=641881
This commit is contained in:
parent
aaf94ea8f9
commit
7598fd4581
@ -3,6 +3,7 @@
|
|||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
|
const Meta = imports.gi.Meta;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
@ -17,6 +18,7 @@ const WorkspacesView = imports.ui.workspacesView;
|
|||||||
let MAX_THUMBNAIL_SCALE = 1/8.;
|
let MAX_THUMBNAIL_SCALE = 1/8.;
|
||||||
|
|
||||||
const RESCALE_ANIMATION_TIME = 0.2;
|
const RESCALE_ANIMATION_TIME = 0.2;
|
||||||
|
const SLIDE_ANIMATION_TIME = 0.2;
|
||||||
|
|
||||||
function WindowClone(realWindow) {
|
function WindowClone(realWindow) {
|
||||||
this._init(realWindow);
|
this._init(realWindow);
|
||||||
@ -123,6 +125,17 @@ WindowClone.prototype = {
|
|||||||
Signals.addSignalMethods(WindowClone.prototype);
|
Signals.addSignalMethods(WindowClone.prototype);
|
||||||
|
|
||||||
|
|
||||||
|
const ThumbnailState = {
|
||||||
|
NEW : 0,
|
||||||
|
ANIMATING_IN : 1,
|
||||||
|
NORMAL: 2,
|
||||||
|
REMOVING : 3,
|
||||||
|
ANIMATING_OUT : 4,
|
||||||
|
ANIMATED_OUT : 5,
|
||||||
|
COLLAPSING : 6,
|
||||||
|
DESTROYED : 7
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @metaWorkspace: a #Meta.Workspace
|
* @metaWorkspace: a #Meta.Workspace
|
||||||
*/
|
*/
|
||||||
@ -172,6 +185,10 @@ WorkspaceThumbnail.prototype = {
|
|||||||
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.state = ThumbnailState.NORMAL;
|
||||||
|
this._slidePosition = 0; // Fully slid in
|
||||||
|
this._collapseFraction = 0; // Not collapsed
|
||||||
},
|
},
|
||||||
|
|
||||||
_lookupIndex: function (metaWindow) {
|
_lookupIndex: function (metaWindow) {
|
||||||
@ -198,6 +215,24 @@ WorkspaceThumbnail.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
set slidePosition(slidePosition) {
|
||||||
|
this._slidePosition = slidePosition;
|
||||||
|
this.actor.queue_relayout();
|
||||||
|
},
|
||||||
|
|
||||||
|
get slidePosition() {
|
||||||
|
return this._slidePosition;
|
||||||
|
},
|
||||||
|
|
||||||
|
set collapseFraction(collapseFraction) {
|
||||||
|
this._collapseFraction = collapseFraction;
|
||||||
|
this.actor.queue_relayout();
|
||||||
|
},
|
||||||
|
|
||||||
|
get collapseFraction() {
|
||||||
|
return this._collapseFraction;
|
||||||
|
},
|
||||||
|
|
||||||
_windowRemoved : function(metaWorkspace, metaWin) {
|
_windowRemoved : function(metaWorkspace, metaWin) {
|
||||||
let win = metaWin.get_compositor_private();
|
let win = metaWin.get_compositor_private();
|
||||||
|
|
||||||
@ -344,8 +379,15 @@ ThumbnailsBox.prototype = {
|
|||||||
this._indicator = indicator;
|
this._indicator = indicator;
|
||||||
this.actor.add_actor(indicator);
|
this.actor.add_actor(indicator);
|
||||||
this._indicatorConstrained = false;
|
this._indicatorConstrained = false;
|
||||||
|
|
||||||
this._targetScale = 0;
|
this._targetScale = 0;
|
||||||
this._scale = 0;
|
this._scale = 0;
|
||||||
|
this._pendingScaleUpdate = false;
|
||||||
|
this._stateUpdateQueued = false;
|
||||||
|
|
||||||
|
this._stateCounts = {};
|
||||||
|
for (key in ThumbnailState)
|
||||||
|
this._stateCounts[ThumbnailState[key]] = 0;
|
||||||
|
|
||||||
this._thumbnails = [];
|
this._thumbnails = [];
|
||||||
},
|
},
|
||||||
@ -355,10 +397,18 @@ ThumbnailsBox.prototype = {
|
|||||||
global.window_manager.connect('switch-workspace',
|
global.window_manager.connect('switch-workspace',
|
||||||
Lang.bind(this, this._activeWorkspaceChanged));
|
Lang.bind(this, this._activeWorkspaceChanged));
|
||||||
|
|
||||||
this.addThumbnails(0, global.screen.n_workspaces);
|
|
||||||
this._constrainThumbnailIndicator();
|
this._constrainThumbnailIndicator();
|
||||||
|
|
||||||
this._targetScale = 0;
|
this._targetScale = 0;
|
||||||
this._scale = 0;
|
this._scale = 0;
|
||||||
|
this._pendingScaleUpdate = false;
|
||||||
|
this._stateUpdateQueued = false;
|
||||||
|
|
||||||
|
this._stateCounts = {};
|
||||||
|
for (key in ThumbnailState)
|
||||||
|
this._stateCounts[ThumbnailState[key]] = 0;
|
||||||
|
|
||||||
|
this.addThumbnails(0, global.screen.n_workspaces);
|
||||||
},
|
},
|
||||||
|
|
||||||
hide: function() {
|
hide: function() {
|
||||||
@ -378,18 +428,41 @@ ThumbnailsBox.prototype = {
|
|||||||
for (let k = start; k < start + count; k++) {
|
for (let k = start; k < start + count; k++) {
|
||||||
let metaWorkspace = global.screen.get_workspace_by_index(k);
|
let metaWorkspace = global.screen.get_workspace_by_index(k);
|
||||||
let thumbnail = new WorkspaceThumbnail(metaWorkspace);
|
let thumbnail = new WorkspaceThumbnail(metaWorkspace);
|
||||||
this._thumbnails[k] = thumbnail;
|
this._thumbnails.push(thumbnail);
|
||||||
this.actor.add_actor(thumbnail.actor);
|
this.actor.add_actor(thumbnail.actor);
|
||||||
|
|
||||||
|
if (start > 0) { // not the initial fill
|
||||||
|
thumbnail.state = ThumbnailState.NEW;
|
||||||
|
thumbnail.slidePosition = 1; // start slid out
|
||||||
|
this._haveNewThumbnails = true;
|
||||||
|
} else {
|
||||||
|
thumbnail.state = ThumbnailState.NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._stateCounts[thumbnail.state]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._queueUpdateStates();
|
||||||
|
|
||||||
// The thumbnails indicator actually needs to be on top of the thumbnails
|
// The thumbnails indicator actually needs to be on top of the thumbnails
|
||||||
this._indicator.raise_top();
|
this._indicator.raise_top();
|
||||||
},
|
},
|
||||||
|
|
||||||
removeThumbmails: function(start, count) {
|
removeThumbmails: function(start, count) {
|
||||||
for (let k = start; k < start + count; k++)
|
let currentPos = 0;
|
||||||
this._thumbnails[k].destroy();
|
for (let k = 0; k < this._thumbnails.length; k++) {
|
||||||
this._thumbnails.splice(start, count);
|
let thumbnail = this._thumbnails[k];
|
||||||
|
|
||||||
|
if (thumbnail.state > ThumbnailState.NORMAL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (currentPos >= start && currentPos < start + count)
|
||||||
|
this._setThumbnailState(thumbnail, ThumbnailState.REMOVING);
|
||||||
|
|
||||||
|
currentPos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._queueUpdateStates();
|
||||||
|
|
||||||
// If we removed the current workspace, then metacity will have already
|
// If we removed the current workspace, then metacity will have already
|
||||||
// switched to an adjacent workspace. Leaving the animation we
|
// switched to an adjacent workspace. Leaving the animation we
|
||||||
@ -415,6 +488,113 @@ ThumbnailsBox.prototype = {
|
|||||||
return this._scale;
|
return this._scale;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_setThumbnailState: function(thumbnail, state) {
|
||||||
|
this._stateCounts[thumbnail.state]--;
|
||||||
|
thumbnail.state = state;
|
||||||
|
this._stateCounts[thumbnail.state]++;
|
||||||
|
},
|
||||||
|
|
||||||
|
_iterateStateThumbnails: function(state, callback) {
|
||||||
|
if (this._stateCounts[state] == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (let i = 0; i < this._thumbnails.length; i++) {
|
||||||
|
if (this._thumbnails[i].state == state)
|
||||||
|
callback.call(this, this._thumbnails[i]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_tweenScale: function() {
|
||||||
|
Tweener.addTween(this,
|
||||||
|
{ scale: this._targetScale,
|
||||||
|
time: RESCALE_ANIMATION_TIME,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
onComplete: this._queueUpdateStates,
|
||||||
|
onCompleteScope: this });
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateStates: function() {
|
||||||
|
this._stateUpdateQueued = false;
|
||||||
|
|
||||||
|
// First thing to do is to start sliding out any thumbnails that have been destroyed
|
||||||
|
this._iterateStateThumbnails(ThumbnailState.REMOVING,
|
||||||
|
function(thumbnail) {
|
||||||
|
this._setThumbnailState(thumbnail, ThumbnailState.ANIMATING_OUT);
|
||||||
|
|
||||||
|
Tweener.addTween(thumbnail,
|
||||||
|
{ slidePosition: 1,
|
||||||
|
time: SLIDE_ANIMATION_TIME,
|
||||||
|
transition: 'linear',
|
||||||
|
onComplete: function() {
|
||||||
|
this._setThumbnailState(thumbnail, ThumbnailState.ANIMATED_OUT);
|
||||||
|
this._queueUpdateStates();
|
||||||
|
},
|
||||||
|
onCompleteScope: this
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// As long as things are sliding out, don't proceed
|
||||||
|
if (this._stateCounts[ThumbnailState.ANIMATING_OUT] > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Once that's complete, we can start scaling to the new size and collapse any removed thumbnails
|
||||||
|
this._iterateStateThumbnails(ThumbnailState.ANIMATED_OUT,
|
||||||
|
function(thumbnail) {
|
||||||
|
this.actor.set_skip_paint(thumbnail.actor, true);
|
||||||
|
this._setThumbnailState(thumbnail, ThumbnailState.COLLAPSING);
|
||||||
|
Tweener.addTween(thumbnail,
|
||||||
|
{ collapseFraction: 1,
|
||||||
|
time: RESCALE_ANIMATION_TIME,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
onComplete: function() {
|
||||||
|
this._stateCounts[thumbnail.state]--;
|
||||||
|
thumbnail.state = ThumbnailState.DESTROYED;
|
||||||
|
|
||||||
|
let index = this._thumbnails.indexOf(thumbnail);
|
||||||
|
this._thumbnails.splice(index, 1);
|
||||||
|
thumbnail.destroy();
|
||||||
|
|
||||||
|
this._queueUpdateStates();
|
||||||
|
},
|
||||||
|
onCompleteScope: this
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this._pendingScaleUpdate) {
|
||||||
|
this._tweenScale();
|
||||||
|
this._pendingScaleUpdate = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait until that's done
|
||||||
|
if (this._scale != this._targetScale || this._stateCounts[ThumbnailState.COLLAPSING] > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// And then slide in any new thumbnails
|
||||||
|
this._iterateStateThumbnails(ThumbnailState.NEW,
|
||||||
|
function(thumbnail) {
|
||||||
|
this._setThumbnailState(thumbnail, ThumbnailState.ANIMATING_IN);
|
||||||
|
Tweener.addTween(thumbnail,
|
||||||
|
{ slidePosition: 0,
|
||||||
|
time: SLIDE_ANIMATION_TIME,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
onComplete: function() {
|
||||||
|
this._setThumbnailState(thumbnail, ThumbnailState.NORMAL);
|
||||||
|
},
|
||||||
|
onCompleteScope: this
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_queueUpdateStates: function() {
|
||||||
|
if (this._stateUpdateQueued)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
|
||||||
|
Lang.bind(this, this._updateStates));
|
||||||
|
|
||||||
|
this._stateUpdateQueued = true;
|
||||||
|
},
|
||||||
|
|
||||||
_getPreferredHeight: function(actor, forWidth, alloc) {
|
_getPreferredHeight: function(actor, forWidth, alloc) {
|
||||||
// Note that for getPreferredWidth/Height we cheat a bit and skip propagating
|
// Note that for getPreferredWidth/Height we cheat a bit and skip propagating
|
||||||
// the size request to our children because we know how big they are and know
|
// the size request to our children because we know how big they are and know
|
||||||
@ -424,21 +604,27 @@ ThumbnailsBox.prototype = {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
let spacing = this.actor.get_theme_node().get_length('spacing');
|
let spacing = this.actor.get_theme_node().get_length('spacing');
|
||||||
let totalSpacing = (this._thumbnails.length - 1) * spacing;
|
let nWorkspaces = global.screen.n_workspaces;
|
||||||
|
let totalSpacing = (nWorkspaces - 1) * spacing;
|
||||||
|
|
||||||
alloc.min_size = totalSpacing;
|
alloc.min_size = totalSpacing;
|
||||||
alloc.natural_size = totalSpacing + this._thumbnails.length * global.screen_height * MAX_THUMBNAIL_SCALE;
|
alloc.natural_size = totalSpacing + nWorkspaces * global.screen_height * MAX_THUMBNAIL_SCALE;
|
||||||
},
|
},
|
||||||
|
|
||||||
_getPreferredWidth: function(actor, forHeight, alloc) {
|
_getPreferredWidth: function(actor, forHeight, alloc) {
|
||||||
if (this._thumbnails.length == 0)
|
if (this._thumbnails.length == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// We don't animate our preferred width, which is always reported according
|
||||||
|
// to the actual number of current workspaces, we just animate within that
|
||||||
|
|
||||||
let spacing = this.actor.get_theme_node().get_length('spacing');
|
let spacing = this.actor.get_theme_node().get_length('spacing');
|
||||||
let totalSpacing = (this._thumbnails.length - 1) * spacing;
|
let nWorkspaces = global.screen.n_workspaces;
|
||||||
|
let totalSpacing = (nWorkspaces - 1) * spacing;
|
||||||
|
|
||||||
let avail = forHeight - totalSpacing;
|
let avail = forHeight - totalSpacing;
|
||||||
|
|
||||||
let scale = (avail / this._thumbnails.length) / global.screen_height;
|
let scale = (avail / nWorkspaces) / global.screen_height;
|
||||||
scale = Math.min(scale, MAX_THUMBNAIL_SCALE);
|
scale = Math.min(scale, MAX_THUMBNAIL_SCALE);
|
||||||
|
|
||||||
alloc.min_size = alloc.natural_size = Math.round(global.screen_width * scale);
|
alloc.min_size = alloc.natural_size = Math.round(global.screen_width * scale);
|
||||||
@ -448,44 +634,49 @@ ThumbnailsBox.prototype = {
|
|||||||
if (this._thumbnails.length == 0) // not visible
|
if (this._thumbnails.length == 0) // not visible
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
let screenWidth = global.screen_width;
|
||||||
let screenHeight = global.screen_height;
|
let screenHeight = global.screen_height;
|
||||||
|
|
||||||
let spacing = this.actor.get_theme_node().get_length('spacing');
|
let spacing = this.actor.get_theme_node().get_length('spacing');
|
||||||
let totalSpacing = (this._thumbnails.length - 1) * spacing;
|
|
||||||
|
// Compute the scale we'll need once everything is updated
|
||||||
|
let nWorkspaces = global.screen.n_workspaces;
|
||||||
|
let totalSpacing = (nWorkspaces - 1) * spacing;
|
||||||
let avail = (box.y2 - box.y1) - totalSpacing;
|
let avail = (box.y2 - box.y1) - totalSpacing;
|
||||||
|
|
||||||
let scale = (avail / this._thumbnails.length) / screenHeight;
|
let newScale = (avail / nWorkspaces) / screenHeight;
|
||||||
scale = Math.min(scale, MAX_THUMBNAIL_SCALE);
|
newScale = Math.min(newScale, MAX_THUMBNAIL_SCALE);
|
||||||
|
|
||||||
if (scale != this._targetScale) {
|
if (newScale != this._targetScale) {
|
||||||
if (this._targetScale > 0) {
|
if (this._targetScale > 0) {
|
||||||
this._targetScale = scale;
|
// We don't do the tween immediately because we need to observe the ordering
|
||||||
Tweener.addTween(this,
|
// in queueUpdateStates - if workspaces have been removed we need to slide them
|
||||||
{ scale: this._targetScale,
|
// out as the first thing.
|
||||||
time: RESCALE_ANIMATION_TIME,
|
this._targetScale = newScale;
|
||||||
transition: 'easeOutQuad' });
|
this._pendingScaleUpdate = true;
|
||||||
} else {
|
} else {
|
||||||
this._targetScale = this._scale = scale;
|
this._targetScale = this._scale = newScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._queueUpdateStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
let thumbnailHeight = screenHeight * this._scale;
|
let thumbnailHeight = screenHeight * this._scale;
|
||||||
|
let thumbnailWidth = Math.round(screenWidth * this._scale);
|
||||||
|
let rightPadding = this.actor.get_theme_node().get_padding(St.Side.RIGHT);
|
||||||
|
let slideWidth = thumbnailWidth + rightPadding; // Amount to slide a thumbnail off to right
|
||||||
|
|
||||||
let childBox = new Clutter.ActorBox();
|
let childBox = new Clutter.ActorBox();
|
||||||
|
|
||||||
let indicatorWorkspace = this._indicatorConstrained ? global.screen.get_active_workspace() : null;
|
let indicatorWorkspace = this._indicatorConstrained ? global.screen.get_active_workspace() : null;
|
||||||
let indicatorBox;
|
let indicatorBox;
|
||||||
|
|
||||||
// Allocating a scaled actor is funny - x1/y1 correspond to the origin
|
|
||||||
// of the actor, but x2/y2 are increased by the *unscaled* size.
|
|
||||||
childBox.x1 = box.x1;
|
|
||||||
childBox.x2 = childBox.x1 + global.screen_width;
|
|
||||||
|
|
||||||
let y = box.y1;
|
let y = box.y1;
|
||||||
|
|
||||||
for (let i = 0; i < this._thumbnails.length; i++) {
|
for (let i = 0; i < this._thumbnails.length; i++) {
|
||||||
|
let thumbnail = this._thumbnails[i];
|
||||||
|
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
y += spacing + thumbnailHeight;
|
y += (1 - thumbnail.collapseFraction) * spacing;
|
||||||
|
|
||||||
// We might end up with thumbnailHeight being something like 99.33
|
// We might end up with thumbnailHeight being something like 99.33
|
||||||
// pixels. To make this work and not end up with a gap at the bottom,
|
// pixels. To make this work and not end up with a gap at the bottom,
|
||||||
@ -495,34 +686,30 @@ ThumbnailsBox.prototype = {
|
|||||||
let y2 = Math.round(y + thumbnailHeight);
|
let y2 = Math.round(y + thumbnailHeight);
|
||||||
let roundedScale = (y2 - y1) / screenHeight;
|
let roundedScale = (y2 - y1) / screenHeight;
|
||||||
|
|
||||||
// When animating to a smaller scale, don't include workspaces that don't
|
let x1 = box.x2 - thumbnailWidth + slideWidth * thumbnail.slidePosition;
|
||||||
// yet fit in the visible portion
|
let x2 = x1 + thumbnailWidth;
|
||||||
if (y2 > Math.round(box.y2)) {
|
|
||||||
|
|
||||||
this.actor.set_skip_paint(this._thumbnails[i].actor, true);
|
if (thumbnail.metaWorkspace == indicatorWorkspace) {
|
||||||
if (this._thumbnails[i].metaWorkspace == indicatorWorkspace)
|
|
||||||
this.actor.set_skip_paint(this._indicator, true);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._thumbnails[i].metaWorkspace == indicatorWorkspace) {
|
|
||||||
let indicatorBox = new Clutter.ActorBox();
|
let indicatorBox = new Clutter.ActorBox();
|
||||||
indicatorBox.x1 = box.x1;
|
indicatorBox.x1 = x1;
|
||||||
indicatorBox.x2 = box.x2;
|
indicatorBox.x2 = x2;
|
||||||
indicatorBox.y1 = y1;
|
indicatorBox.y1 = y1;
|
||||||
indicatorBox.y2 = y2;
|
indicatorBox.y2 = y2;
|
||||||
|
|
||||||
this.actor.set_skip_paint(this._indicator, false);
|
|
||||||
this._indicator.allocate(indicatorBox, flags);
|
this._indicator.allocate(indicatorBox, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allocating a scaled actor is funny - x1/y1 correspond to the origin
|
||||||
|
// of the actor, but x2/y2 are increased by the *unscaled* size.
|
||||||
|
childBox.x1 = x1;
|
||||||
|
childBox.x2 = x1 + screenWidth;
|
||||||
childBox.y1 = y1;
|
childBox.y1 = y1;
|
||||||
childBox.y2 = childBox.y1 + screenHeight;
|
childBox.y2 = y1 + screenHeight;
|
||||||
|
|
||||||
this.actor.set_skip_paint(this._thumbnails[i].actor, false);
|
thumbnail.actor.set_scale(roundedScale, roundedScale);
|
||||||
this._thumbnails[i].actor.set_scale(roundedScale, roundedScale);
|
thumbnail.actor.allocate(childBox, flags);
|
||||||
this._thumbnails[i].actor.allocate(childBox, flags);
|
|
||||||
|
y += thumbnailHeight * (1 - thumbnail.collapseFraction);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (indicatorWorkspace == null) {
|
if (indicatorWorkspace == null) {
|
||||||
@ -541,8 +728,14 @@ ThumbnailsBox.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_activeWorkspaceChanged: function(wm, from, to, direction) {
|
_activeWorkspaceChanged: function(wm, from, to, direction) {
|
||||||
let active = global.screen.get_active_workspace_index();
|
let thumbnail;
|
||||||
let thumbnail = this._thumbnails[active];
|
let activeWorkspace = global.screen.get_active_workspace();
|
||||||
|
for (let i = 0; i < this._thumbnails.length; i++) {
|
||||||
|
if (this._thumbnails[i].metaWorkspace == activeWorkspace) {
|
||||||
|
thumbnail = this._thumbnails[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this._unconstrainThumbnailIndicator();
|
this._unconstrainThumbnailIndicator();
|
||||||
let oldAllocation = this._indicator.allocation;
|
let oldAllocation = this._indicator.allocation;
|
||||||
|
Loading…
Reference in New Issue
Block a user