js: Use implicit animations for animatable properties

We now have everything in place to replace Tweener for all animatable
properties with implicit animations, which has the following benefits:

 - they run entirely in C, while Tweener requires context switches
   to JS each frame

 - they are more reliable, as Tweener only detects when an animation
   is overwritten with another Tween, while Clutter considers any
   property change

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/22
This commit is contained in:
Florian Müllner
2018-07-20 21:46:19 +02:00
parent 007b6ca2e8
commit 0846238f69
38 changed files with 1004 additions and 998 deletions

View File

@ -8,14 +8,13 @@ const Signals = imports.signals;
const DND = imports.ui.dnd;
const Main = imports.ui.main;
const Overview = imports.ui.overview;
const Tweener = imports.ui.tweener;
var WINDOW_DND_SIZE = 256;
var WINDOW_CLONE_MAXIMUM_SCALE = 1.0;
var WINDOW_OVERLAY_IDLE_HIDE_TIMEOUT = 750;
var WINDOW_OVERLAY_FADE_TIME = 0.1;
var WINDOW_OVERLAY_FADE_TIME = 100;
var WINDOW_REPOSITIONING_DELAY = 750;
@ -541,9 +540,9 @@ var WindowOverlay = class {
let title = this.title;
let border = this.border;
Tweener.removeTweens(button);
Tweener.removeTweens(border);
Tweener.removeTweens(title);
button.remove_all_transitions();
border.remove_all_transitions();
title.remove_all_transitions();
let [cloneX, cloneY, cloneWidth, cloneHeight] = this._windowClone.slot;
@ -610,16 +609,16 @@ var WindowOverlay = class {
}
_animateOverlayActor(actor, x, y, width, height) {
let params = { x: x,
y: y,
width: width,
time: Overview.ANIMATION_TIME / 1000,
transition: 'easeOutQuad' };
let params = {
x, y, width,
duration: Overview.ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD
};
if (height !== undefined)
params.height = height;
Tweener.addTween(actor, params);
actor.ease(params);
}
_windowCanClose() {
@ -648,20 +647,22 @@ var WindowOverlay = class {
toAnimate.forEach(a => {
a.show();
a.opacity = 0;
Tweener.addTween(a,
{ opacity: 255,
time: WINDOW_OVERLAY_FADE_TIME / 1000,
transition: 'easeOutQuad' });
a.ease({
opacity: 255,
duration: WINDOW_OVERLAY_FADE_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD
});
});
}
_animateInvisible() {
[this.closeButton, this.border, this.title].forEach(a => {
a.opacity = 255;
Tweener.addTween(a,
{ opacity: 0,
time: WINDOW_OVERLAY_FADE_TIME / 1000,
transition: 'easeInQuad' });
a.ease({
opacity: 0,
duration: WINDOW_OVERLAY_FADE_TIME,
mode: Clutter.AnimationMode.EASE_IN_QUAD
});
});
}
@ -1344,17 +1345,17 @@ var Workspace = class {
clone.y = y;
}
Tweener.addTween(clone,
{ opacity: 255,
time: Overview.ANIMATION_TIME / 1000,
transition: 'easeInQuad'
});
clone.ease({
opacity: 255,
mode: Clutter.AnimationMode.EASE_IN_QUAD,
duration: Overview.ANIMATION_TIME
});
}
this._animateClone(clone, clone.overlay, x, y, scale);
} else {
// cancel any active tweens (otherwise they might override our changes)
Tweener.removeTweens(clone);
clone.remove_all_transitions();
clone.set_position(x, y);
clone.set_scale(scale, scale);
clone.set_opacity(255);
@ -1384,18 +1385,16 @@ var Workspace = class {
}
_animateClone(clone, overlay, x, y, scale) {
Tweener.addTween(clone,
{ x: x,
y: y,
scale_x: scale,
scale_y: scale,
time: Overview.ANIMATION_TIME / 1000,
transition: 'easeOutQuad',
onComplete: () => {
this._showWindowOverlay(clone, overlay);
}
});
clone.ease({
x, y,
scale_x: scale,
scale_y: scale,
duration: Overview.ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => {
this._showWindowOverlay(clone, overlay);
}
});
clone.overlay.relayout(true);
}
@ -1629,10 +1628,8 @@ var Workspace = class {
if (this._windows.length == 0)
return;
for (let i = 0; i < this._windows.length; i++) {
let clone = this._windows[i];
Tweener.removeTweens(clone);
}
for (let i = 0; i < this._windows.length; i++)
this._windows[i].remove_all_transitions();
if (this._repositionWindowsId > 0) {
Mainloop.source_remove(this._repositionWindowsId);
@ -1681,7 +1678,7 @@ var Workspace = class {
}
}
_fadeWindow(index, time, opacity) {
_fadeWindow(index, duration, opacity) {
let clone = this._windows[index];
let overlay = this._windowOverlays[index];
@ -1694,11 +1691,11 @@ var Workspace = class {
clone.scale_y = 1;
clone.x = origX;
clone.y = origY;
Tweener.addTween(clone,
{ time: time / 1000,
opacity: opacity,
transition: 'easeOutQuad'
});
clone.ease({
opacity,
duration,
mode: Clutter.AnimationMode.EASE_OUT_QUAD
});
} else {
// The window is hidden
clone.opacity = 0;
@ -1716,10 +1713,8 @@ var Workspace = class {
this.leavingOverview = true;
for (let i = 0; i < this._windows.length; i++) {
let clone = this._windows[i];
Tweener.removeTweens(clone);
}
for (let i = 0; i < this._windows.length; i++)
this._windows[i].remove_all_transitions();
if (this._repositionWindowsId > 0) {
Mainloop.source_remove(this._repositionWindowsId);
@ -1744,24 +1739,24 @@ var Workspace = class {
if (clone.metaWindow.showing_on_its_workspace()) {
let [origX, origY] = clone.getOriginalPosition();
Tweener.addTween(clone,
{ x: origX,
y: origY,
scale_x: 1.0,
scale_y: 1.0,
time: Overview.ANIMATION_TIME / 1000,
opacity: 255,
transition: 'easeOutQuad'
});
clone.ease({
x: origX,
y: origY,
scale_x: 1,
scale_y: 1,
opacity: 255,
duration: Overview.ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD
});
} else {
// The window is hidden, make it shrink and fade it out
Tweener.addTween(clone,
{ scale_x: 0,
scale_y: 0,
opacity: 0,
time: Overview.ANIMATION_TIME / 1000,
transition: 'easeOutQuad'
});
clone.ease({
scale_x: 0,
scale_y: 0,
opacity: 0,
duration: Overview.ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD
});
}
}
@ -1769,12 +1764,11 @@ var Workspace = class {
this.actor.destroy();
}
_onDestroy(actor) {
_onDestroy() {
if (this._overviewHiddenId) {
Main.overview.disconnect(this._overviewHiddenId);
this._overviewHiddenId = 0;
}
Tweener.removeTweens(actor);
if (this.metaWorkspace) {
this.metaWorkspace.disconnect(this._windowAddedId);