[gnome-shell] [linearView] Cleanup workspace scrolling and zooming
- From: Florian Müllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] [linearView] Cleanup workspace scrolling and zooming
- Date: Wed, 5 May 2010 19:08:16 +0000 (UTC)
commit 082a15bbc5ac438a71748198c63aa8eff708e4e9
Author: Florian Müllner <fmuellner src gnome org>
Date: Tue Mar 23 00:01:44 2010 +0100
[linearView] Cleanup workspace scrolling and zooming
Centralize the update of actor visibilities (overlays, shadows,
off-screen workspaces). Adjust the way scrolling is handled so
that it works correctly with removed workspaces.
https://bugzilla.gnome.org/show_bug.cgi?id=610191
js/ui/workspace.js | 3 +
js/ui/workspacesView.js | 266 +++++++++++++++++++++++++++--------------------
2 files changed, 158 insertions(+), 111 deletions(-)
---
diff --git a/js/ui/workspace.js b/js/ui/workspace.js
index d3165c5..508471e 100644
--- a/js/ui/workspace.js
+++ b/js/ui/workspace.js
@@ -1143,6 +1143,9 @@ Workspace.prototype = {
},
_fadeInWindowOverlay: function(clone, overlay) {
+ if (clone.inDrag)
+ return;
+
// This is a little messy and complicated because when we
// start the fade-in we may not have done the final positioning
// of the workspaces. (Tweener doesn't necessarily finish
diff --git a/js/ui/workspacesView.js b/js/ui/workspacesView.js
index 64a1438..a07834c 100644
--- a/js/ui/workspacesView.js
+++ b/js/ui/workspacesView.js
@@ -53,7 +53,7 @@ GenericWorkspacesView.prototype = {
let [a, spacing] = node.get_length('spacing', false);
this._spacing = spacing;
if (Main.overview.animationInProgress)
- this._positionWorkspaces();
+ this._computeWorkspacePositions();
else
this._transitionWorkspaces();
}));
@@ -252,7 +252,7 @@ GenericWorkspacesView.prototype = {
throw new Error("Not implemented");
},
- _positionWorkspaces: function() {
+ _computeWorkspacePositions: function() {
throw new Error("Not implemented");
},
@@ -294,7 +294,7 @@ MosaicView.prototype = {
// first row.)
//
// FIXME: need to make the metacity internal layout agree with this!
- _positionWorkspaces: function() {
+ _computeWorkspacePositions: function() {
let gridWidth = Math.ceil(Math.sqrt(this._workspaces.length));
let gridHeight = Math.ceil(this._workspaces.length / gridWidth);
@@ -337,7 +337,7 @@ MosaicView.prototype = {
_transitionWorkspaces: function() {
// update workspace parameters
- this._positionWorkspaces();
+ this._computeWorkspacePositions();
let active = global.screen.get_active_workspace_index();
let activeWorkspace = this._workspaces[active];
@@ -394,7 +394,7 @@ MosaicView.prototype = {
this._actor.add_actor(this._workspaces[w].actor);
// Figure out the new layout
- this._positionWorkspaces();
+ this._computeWorkspacePositions();
let newScale = this._workspaces[0].scale;
let newGridWidth = Math.ceil(Math.sqrt(newNumWorkspaces));
let newGridHeight = Math.ceil(newNumWorkspaces / newGridWidth);
@@ -522,10 +522,14 @@ SingleView.prototype = {
this._actor.set_clip(x, y, width, height);
this._indicatorsPanel = null;
this._indicatorsPanelWidth = 0;
+ this._activeWorkspaceX = 0; // x offset of active ws while dragging
+ this._activeWorkspaceY = 0; // y offset of active ws while dragging
this._scroll = null;
this._lostWorkspaces = [];
- this._scrolling = false;
- this._animatingScroll = false;
+ this._animating = false; // tweening
+ this._scrolling = false; // dragging scroll bar or desktop
+ this._animatingScroll = false; // programatically move the scroll bar
+ this._inDrag = false; // dragging a window
let primary = global.get_primary_monitor();
this._dropGroup = new Clutter.Group({ x: 0, y: 0,
@@ -539,58 +543,60 @@ SingleView.prototype = {
this._buttonPressId = 0;
this._capturedEventId = 0;
this._timeoutId = 0;
- this._windowDragBeginId = 0;
- this._windowDragEndId = 0;
},
- _positionWorkspaces: function() {
- let scale;
+ // Compute the position, scale and opacity of the workspaces, but don't
+ // actually change the actors to match
+ _computeWorkspacePositions: function() {
+ let active = global.screen.get_active_workspace_index();
+ let scale = this._width / global.screen_width;
if (this._inDrag)
- scale = this._width * WORKSPACE_DRAGGING_SCALE / global.screen_width;
- else
- scale = this._width / global.screen_width;
- let active = global.screen.get_active_workspace_index();
- let _width = this._workspaces[0].actor.width * scale;
+ scale *= WORKSPACE_DRAGGING_SCALE;
this._setWorkspaceDraggable(active, true);
+ let _width = this._workspaces[0].actor.width * scale;
+ let _height = this._workspaces[0].actor.height * scale;
+
+ this._activeWorkspaceX = (this._width - _width) / 2;
+ this._activeWorkspaceY = (this._height - _height) / 2;
+
for (let w = 0; w < this._workspaces.length; w++) {
let workspace = this._workspaces[w];
- if (this._inDrag)
- workspace.opacity = 200;
- else
- workspace.opacity = 255;
- if (active == w)
- workspace.opacity = 255;
+ workspace.opacity = (this._inDrag && w != active) ? 200 : 255;
workspace.gridRow = 0;
workspace.gridCol = 0;
workspace.scale = scale;
- workspace.gridX = this._x + (this._width - _width) / 2 + (w - active) * (_width + this._spacing);
- workspace.gridY = this._y + (this._height - workspace.actor.height * scale) / 2;
+ workspace.gridX = this._x + this._activeWorkspaceX
+ + (w - active) * (_width + this._spacing);
+ workspace.gridY = this._y + this._activeWorkspaceY;
workspace.setSelected(false);
}
this._newWorkspaceArea.scale = scale;
- this._newWorkspaceArea.gridX = this._x + (this._width - _width) / 2 + (this._workspaces.length - active) * (_width + this._spacing);
- this._newWorkspaceArea.gridY = this._y + (this._height - this._newWorkspaceArea.actor.height * scale) / 2;
+ this._newWorkspaceArea.gridX = this._x + this._activeWorkspaceX
+ + (this._workspaces.length - active) * (_width + this._spacing);
+ this._newWorkspaceArea.gridY = this._y + this._activeWorkspaceY;
this._leftShadow.scale = scale;
- this._leftShadow.gridX = this._x + (this._width - _width) / 2 - (this._leftShadow.width * scale + this._spacing);
- this._leftShadow.gridY = this._y + (this._height - this._leftShadow.height * scale) / 2;
+ this._leftShadow.gridX = this._x + this._activeWorkspaceX
+ - (this._leftShadow.width * scale + this._spacing);
+ this._leftShadow.gridY = this._y + this._activeWorkspaceY;
this._rightShadow.scale = scale;
- this._rightShadow.gridX = this._x + (this._width - _width) / 2 + (_width + this._spacing);
- this._rightShadow.gridY = this._y + (this._height - this._rightShadow.height * scale) / 2;
+ this._rightShadow.gridX = this._x + this._activeWorkspaceX
+ + (_width + this._spacing);
+ this._rightShadow.gridY = this._y + this._activeWorkspaceY;
},
_transitionWorkspaces: function() {
// update workspace parameters
- this._positionWorkspaces();
+ this._computeWorkspacePositions();
let active = global.screen.get_active_workspace_index();
let activeActor = this._workspaces[active].actor;
@@ -737,116 +743,154 @@ SingleView.prototype = {
return false;
},
+ // Update workspace actors parameters to the values calculated in
+ // _computeWorkspacePositions()
+ // @showAnimation: iff %true, transition between states
_updateWorkspaceActors: function(showAnimation) {
let active = global.screen.get_active_workspace_index();
-
- this._positionWorkspaces();
-
- let dx = this._workspaces[0].gridX - this._workspaces[0].actor.x;
+ let targetWorkspaceNewX = this._x + this._activeWorkspaceX;
+ let targetWorkspaceCurrentX = this._workspaces[active].gridX;
+ let dx = targetWorkspaceNewX - targetWorkspaceCurrentX;
this._setWorkspaceDraggable(active, true);
+ this._animating = showAnimation;
+
for (let w = 0; w < this._workspaces.length; w++) {
let workspace = this._workspaces[w];
- workspace.actor.show();
- workspace.hideWindowsOverlays();
+ Tweener.removeTweens(workspace.actor);
+
+ workspace.gridX += dx;
- let i = w;
if (showAnimation) {
Tweener.addTween(workspace.actor,
{ x: workspace.gridX,
y: workspace.gridY,
scale_x: workspace.scale,
scale_y: workspace.scale,
- time: WORKSPACE_SWITCH_TIME,
opacity: workspace.opacity,
- transition: 'easeOutQuad',
- onCompleteScope: this,
- onComplete: function() {
- if (i == active) {
- if (!this._inDrag)
- workspace.showWindowsOverlays();
- } else
- workspace.actor.visible = Math.abs(i - active) <= 1;
- }});
+ time: WORKSPACE_SWITCH_TIME,
+ transition: 'easeOutQuad'
+ });
} else {
workspace.actor.set_scale(workspace.scale, workspace.scale);
workspace.actor.set_position(workspace.gridX, workspace.gridY);
workspace.actor.opacity = workspace.opacity;
- if (i == active) {
- if (!this._inDrag)
- workspace.showWindowsOverlays();
- } else
- workspace.actor.visible = Math.abs(i - active) <= 1;
}
- workspace.positionWindows(0);
}
- if (active)
- this._leftShadow.show();
- else
- this._leftShadow.hide();
- if (active == this._workspaces.length - 1)
- this._rightShadow.hide();
- else
- this._rightShadow.show();
+ for (let l = 0; l < this._lostWorkspaces.length; l++) {
+ let workspace = this._lostWorkspaces[l];
+
+ Tweener.removeTweens(workspace.actor);
- this._leftShadow.raise_top();
- this._rightShadow.raise_top();
+ workspace.gridX += dx;
+ workspace.actor.show();
+ workspace.hideWindowsOverlays();
+ if (showAnimation) {
+ Tweener.addTween(workspace.actor,
+ { x: workspace.gridX,
+ time: WORKSPACE_SWITCH_TIME,
+ transition: 'easeOutQuad',
+ onComplete: Lang.bind(this,
+ this._cleanWorkspaces)
+ });
+ } else {
+ this._cleanWorkspaces();
+ }
+ }
+
+ Tweener.removeTweens(this._newWorkspaceArea.actor);
+ Tweener.removeTweens(this._leftShadow);
+ Tweener.removeTweens(this._rightShadow);
+
+ this._newWorkspaceArea.gridX += dx;
if (showAnimation) {
+ // we have to call _updateVisibility() once before the
+ // animation and once afterwards - it does not really
+ // matter which tween we use, as long as it's not inside
+ // a loop ...
+ this._updateVisibility();
Tweener.addTween(this._newWorkspaceArea.actor,
- { x: this._newWorkspaceArea.gridX,
- y: this._newWorkspaceArea.gridY,
- scale_x: this._newWorkspaceArea.scale,
- scale_y: this._newWorkspaceArea.scale,
- time: WORKSPACE_SWITCH_TIME,
- transition: 'easeOutQuad'
- });
+ { x: this._newWorkspaceArea.gridX,
+ y: this._newWorkspaceArea.gridY,
+ scale_x: this._newWorkspaceArea.scale,
+ scale_y: this._newWorkspaceArea.scale,
+ time: WORKSPACE_SWITCH_TIME,
+ transition: 'easeOutQuad',
+ onComplete: Lang.bind(this, function() {
+ this._animating = false;
+ this._updateVisibility();
+ })
+ });
this._leftShadow.x = this._leftShadow.gridX;
Tweener.addTween(this._leftShadow,
- { y: this._leftShadow.gridY,
- scale_x: this._leftShadow.scale,
- scale_y: this._leftShadow.scale,
- time: WORKSPACE_SWITCH_TIME,
- transition: 'easeOutQuad'
- });
+ { y: this._leftShadow.gridY,
+ scale_x: this._leftShadow.scale,
+ scale_y: this._leftShadow.scale,
+ time: WORKSPACE_SWITCH_TIME,
+ transition: 'easeOutQuad'
+ });
this._rightShadow.x = this._rightShadow.gridX;
Tweener.addTween(this._rightShadow,
- { y: this._rightShadow.gridY,
- scale_x: this._rightShadow.scale,
- scale_y: this._rightShadow.scale,
- time: WORKSPACE_SWITCH_TIME,
- transition: 'easeOutQuad'
- });
+ { y: this._rightShadow.gridY,
+ scale_x: this._rightShadow.scale,
+ scale_y: this._rightShadow.scale,
+ time: WORKSPACE_SWITCH_TIME,
+ transition: 'easeOutQuad'
+ });
} else {
- this._newWorkspaceArea.actor.set_scale(this._newWorkspaceArea.scale, this._newWorkspaceArea.scale);
- this._newWorkspaceArea.actor.set_position(this._newWorkspaceArea.gridX, this._newWorkspaceArea.gridY);
-
- this._leftShadow.set_scale(this._leftShadow.scale, this._leftShadow.scale);
- this._leftShadow.set_position(this._leftShadow.gridX, this._leftShadow.gridY);
- this._rightShadow.set_scale(this._rightShadow.scale, this._rightShadow.scale);
- this._rightShadow.set_position(this._rightShadow.gridX, this._rightShadow.gridY);
+ this._newWorkspaceArea.actor.set_scale(this._newWorkspaceArea.scale,
+ this._newWorkspaceArea.scale);
+ this._newWorkspaceArea.actor.set_position(this._newWorkspaceArea.gridX,
+ this._newWorkspaceArea.gridY);
+ this._leftShadow.set_scale(this._leftShadow.scale,
+ this._leftShadow.scale);
+ this._leftShadow.set_position(this._leftShadow.gridX,
+ this._leftShadow.gridY);
+ this._rightShadow.set_scale(this._rightShadow.scale,
+ this._rightShadow.scale);
+ this._rightShadow.set_position(this._rightShadow.gridX,
+ this._rightShadow.gridY);
+ this._updateVisibility();
}
+ },
- for (let l = 0; l < this._lostWorkspaces.length; l++) {
- let workspace = this._lostWorkspaces[l];
-
- workspace.gridX += dx;
- workspace.actor.show();
- workspace._hideAllOverlays();
+ _updateVisibility: function() {
+ let active = global.screen.get_active_workspace_index();
- if (showAnimation) {
- Tweener.addTween(workspace.actor,
- { x: workspace.gridX,
- time: WORKSPACE_SWITCH_TIME,
- transition: 'easeOutQuad',
- onComplete: Lang.bind(this, this._cleanWorkspaces)
- });
+ for (let w = 0; w < this._workspaces.length; w++) {
+ let workspace = this._workspaces[w];
+ if (this._animating || this._scrolling) {
+ workspace.hideWindowsOverlays();
+ workspace.actor.show();
} else {
- this._cleanWorkspaces();
+ workspace.showWindowsOverlays();
+ if (this._inDrag)
+ workspace.actor.visible = (Math.abs(w - active) <= 1);
+ else
+ workspace.actor.visible = (w == active);
}
}
+
+ if (this._inDrag) {
+ this._leftShadow.raise_top();
+ this._rightShadow.raise_top();
+
+ if (active > 0)
+ this._leftShadow.show();
+ else
+ this._leftShadow.hide();
+
+ if (active < this._workspaces.length - 1)
+ this._rightShadow.show();
+ else
+ this._rightShadow.hide();
+ } else {
+ this._leftShadow.hide();
+ this._rightShadow.hide();
+ }
},
_cleanWorkspaces: function() {
@@ -857,8 +901,8 @@ SingleView.prototype = {
this._lostWorkspaces[l].destroy();
this._lostWorkspaces = [];
- this._positionWorkspaces();
- this._updateWorkspaceActors();
+ this._computeWorkspacePositions();
+ this._updateWorkspaceActors(false);
},
_scrollScrollBarToIndex: function(index, showAnimation) {
@@ -901,8 +945,8 @@ SingleView.prototype = {
Lang.bind(this, this._onWindowDragEnd));
}
- this._positionWorkspaces();
- this._updateWorkspaceActors();
+ this._computeWorkspacePositions();
+ this._updateWorkspaceActors(false);
this._scrollScrollBarToIndex(active + 1, false);
} else {
this._lostWorkspaces = lostWorkspaces;
@@ -980,6 +1024,7 @@ SingleView.prototype = {
return;
this._inDrag = true;
+ this._computeWorkspacePositions();
this._updateWorkspaceActors(true);
this._dropGroup.raise_top();
@@ -1054,6 +1099,7 @@ SingleView.prototype = {
this._dropGroup.lower_bottom();
actor.opacity = 255;
this._inDrag = false;
+ this._computeWorkspacePositions();
this._updateWorkspaceActors(true);
for (let i = 0; i < this._workspaces.length; i++)
@@ -1112,9 +1158,7 @@ SingleView.prototype = {
if (!this._scrolling && active == adj.value) {
// Again, work around the paging in StScrollBar: simulate
// the effect of scroll-stop
- this._scrolling = true;
- this._scrollToActive(false);
- this._scrolling = false;
+ this._updateWorkspaceActors(false);
}
},
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]