From b3b91f1699e92c3dbaaa5965851394a7306f1398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 15 Apr 2020 11:24:10 +0200 Subject: [PATCH] js: Drop tweener.js We're using clutter's animation framework now, so lets drop the old tweener support layer. https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1200 --- js/js-resources.gresource.xml | 1 - js/ui/appDisplay.js | 2 +- js/ui/environment.js | 2 - js/ui/screenShield.js | 2 +- js/ui/tweener.js | 228 ---------------------------------- src/shell-global.c | 6 +- 6 files changed, 4 insertions(+), 237 deletions(-) delete mode 100644 js/ui/tweener.js diff --git a/js/js-resources.gresource.xml b/js/js-resources.gresource.xml index 2cf86a08a..6281eff7b 100644 --- a/js/js-resources.gresource.xml +++ b/js/js-resources.gresource.xml @@ -102,7 +102,6 @@ ui/swipeTracker.js ui/switcherPopup.js ui/switchMonitor.js - ui/tweener.js ui/unlockDialog.js ui/userWidget.js ui/viewSelector.js diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js index 08febc491..c8ac32841 100644 --- a/js/ui/appDisplay.js +++ b/js/ui/appDisplay.js @@ -638,7 +638,7 @@ var AllView = GObject.registerClass({ this._grid.currentPage = pageNumber; - // Tween the change between pages. + // Animate the change between pages. this._adjustment.ease(this._grid.getPageY(this._grid.currentPage), { mode: Clutter.AnimationMode.EASE_OUT_CUBIC, duration: animate ? PAGE_SWITCH_TIME : 0, diff --git a/js/ui/environment.js b/js/ui/environment.js index 8f23b107e..7a96d9480 100644 --- a/js/ui/environment.js +++ b/js/ui/environment.js @@ -356,9 +356,7 @@ function init() { // OK, now things are initialized enough that we can import shell JS const Format = imports.format; - const Tweener = imports.ui.tweener; - Tweener.init(); String.prototype.format = Format.format; } diff --git a/js/ui/screenShield.js b/js/ui/screenShield.js index 86221a309..98279e070 100644 --- a/js/ui/screenShield.js +++ b/js/ui/screenShield.js @@ -345,7 +345,7 @@ var ScreenShield = class { this._lockDialogGroup.remove_all_transitions(); if (animate) { - // Tween the lock screen out of screen + // Animate the lock screen out of screen // if velocity is not specified (i.e. we come here from pressing ESC), // use the same speed regardless of original position // if velocity is specified, it's in pixels per milliseconds diff --git a/js/ui/tweener.js b/js/ui/tweener.js deleted file mode 100644 index 221438c1b..000000000 --- a/js/ui/tweener.js +++ /dev/null @@ -1,228 +0,0 @@ -// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- -/* exported init, addCaller, addTween, getTweenCount, removeTweens, - pauseTweens, resumeTweens, registerSpecialProperty, - registerSpecialPropertyModifier, registerSpecialPropertySplitter */ - -const { Clutter, GLib, Shell } = imports.gi; -const Signals = imports.signals; -const Tweener = imports.tweener.tweener; - -const { adjustAnimationTime } = imports.ui.environment; - -// This is a wrapper around imports.tweener.tweener that adds a bit of -// Clutter integration. If the tweening target is a Clutter.Actor, then -// the tweenings will automatically be removed if the actor is destroyed. - -// ActionScript Tweener methods that imports.tweener.tweener doesn't -// currently implement: getTweens, getVersion, registerTransition, -// setTimeScale, updateTime. - -// imports.tweener.tweener methods that we don't re-export: -// pauseAllTweens, removeAllTweens, resumeAllTweens. (It would be hard -// to clean up properly after removeAllTweens, and also, any code that -// calls any of these is almost certainly wrong anyway, because they -// affect the entire application.) - -// Called from Main.start -function init() { - Tweener.setFrameTicker(new ClutterFrameTicker()); -} - - -function addCaller(target, tweeningParameters) { - _wrapTweening(target, tweeningParameters); - Tweener.addCaller(target, tweeningParameters); -} - -function addTween(target, tweeningParameters) { - _wrapTweening(target, tweeningParameters); - Tweener.addTween(target, tweeningParameters); -} - -function _wrapTweening(target, tweeningParameters) { - let state = _getTweenState(target); - - if (!state.destroyedId) { - if (target instanceof Clutter.Actor) { - state.actor = target; - state.destroyedId = target.connect('destroy', _actorDestroyed); - } else if (target.actor && target.actor instanceof Clutter.Actor) { - state.actor = target.actor; - state.destroyedId = target.actor.connect('destroy', () => _actorDestroyed(target)); - } - } - - let { time, delay } = tweeningParameters; - if (!isNaN(time)) - tweeningParameters['time'] = adjustAnimationTime(1000 * time) / 1000; - if (!isNaN(delay)) - tweeningParameters['delay'] = adjustAnimationTime(1000 * delay) / 1000; - - _addHandler(target, tweeningParameters, 'onComplete', _tweenCompleted); -} - -function _getTweenState(target) { - // If we were paranoid, we could keep a plist mapping targets to - // states... but we're not that paranoid. - if (!target.__ShellTweenerState) - target.__ShellTweenerState = {}; - return target.__ShellTweenerState; -} - -function _resetTweenState(target) { - let state = target.__ShellTweenerState; - - if (state) { - if (state.destroyedId) - state.actor.disconnect(state.destroyedId); - } - - target.__ShellTweenerState = {}; -} - -function _addHandler(target, params, name, handler) { - if (params[name]) { - let oldHandler = params[name]; - let oldScope = params[`${name}Scope`]; - let oldParams = params[`${name}Params`]; - let eventScope = oldScope ? oldScope : target; - - params[name] = () => { - oldHandler.apply(eventScope, oldParams); - handler(target); - }; - } else { - params[name] = () => handler(target); - } -} - -function _actorDestroyed(target) { - _resetTweenState(target); - Tweener.removeTweens(target); -} - -function _tweenCompleted(target) { - if (!isTweening(target)) - _resetTweenState(target); -} - -function getTweenCount(scope) { - return Tweener.getTweenCount(scope); -} - -// imports.tweener.tweener doesn't provide this method (which exists -// in the ActionScript version) but it's easy to implement. -function isTweening(scope) { - return Tweener.getTweenCount(scope) != 0; -} - -function removeTweens(...args) { - if (Tweener.removeTweens(args)) { - let [scope] = args; - // If we just removed the last active tween, clean up - if (Tweener.getTweenCount(scope) == 0) - _tweenCompleted(scope); - return true; - } else { - return false; - } -} - -function pauseTweens(...args) { - return Tweener.pauseTweens(...args); -} - -function resumeTweens(...args) { - return Tweener.resumeTweens(...args); -} - - -function registerSpecialProperty(...args) { - Tweener.registerSpecialProperty(...args); -} - -function registerSpecialPropertyModifier(name, modifyFunction, getFunction) { - Tweener.registerSpecialPropertyModifier(name, modifyFunction, getFunction); -} - -function registerSpecialPropertySplitter(name, splitFunction, parameters) { - Tweener.registerSpecialPropertySplitter(name, splitFunction, parameters); -} - - -// The 'FrameTicker' object is an object used to feed new frames to -// Tweener so it can update values and redraw. The default frame -// ticker for Tweener just uses a simple timeout at a fixed frame rate -// and has no idea of "catching up" by dropping frames. -// -// We substitute it with custom frame ticker here that connects -// Tweener to a Clutter.TimeLine. Now, Clutter.Timeline itself isn't a -// whole lot more sophisticated than a simple timeout at a fixed frame -// rate, but at least it knows how to drop frames. (See -// HippoAnimationManager for a more sophisticated view of continuous -// time updates; even better is to pay attention to the vertical -// vblank and sync to that when possible.) -// -var ClutterFrameTicker = class { - constructor() { - // We don't have a finite duration; tweener will tell us to stop - // when we need to stop, so use 1000 seconds as "infinity", and - // set the timeline to loop. Doing this means we have to track - // time ourselves, since clutter timeline's time will cycle - // instead of strictly increase. - this._timeline = new Clutter.Timeline({ duration: 1000 * 1000 }); - this._timeline.set_loop(true); - this._startTime = -1; - this._currentTime = -1; - - this._timeline.connect('new-frame', () => { - this._onNewFrame(); - }); - - let perfLog = Shell.PerfLog.get_default(); - perfLog.define_event("tweener.framePrepareStart", - "Start of a new animation frame", - ""); - perfLog.define_event("tweener.framePrepareDone", - "Finished preparing frame", - ""); - } - - get FRAME_RATE() { - return 60; - } - - _onNewFrame() { - // If there is a lot of setup to start the animation, then - // first frame number we get from clutter might be a long ways - // into the animation (or the animation might even be done). - // That looks bad, so we always start at the first frame of the - // animation then only do frame dropping from there. - if (this._startTime < 0) - this._startTime = GLib.get_monotonic_time() / 1000.0; - - // currentTime is in milliseconds - let perfLog = Shell.PerfLog.get_default(); - this._currentTime = GLib.get_monotonic_time() / 1000.0 - this._startTime; - perfLog.event("tweener.framePrepareStart"); - this.emit('prepare-frame'); - perfLog.event("tweener.framePrepareDone"); - } - - getTime() { - return this._currentTime; - } - - start() { - this._timeline.start(); - global.begin_work(); - } - - stop() { - this._timeline.stop(); - this._startTime = -1; - this._currentTime = -1; - global.end_work(); - } -}; -Signals.addSignalMethods(ClutterFrameTicker.prototype); diff --git a/src/shell-global.c b/src/shell-global.c index ec9a05217..e70677775 100644 --- a/src/shell-global.c +++ b/src/shell-global.c @@ -1599,10 +1599,8 @@ shell_global_end_work (ShellGlobal *global) * Idle means here no animations, no redrawing, and no ongoing background * work. Since there is currently no way to hook into the Clutter master * clock and know when is running, the implementation here is somewhat - * approximation. Animations done through the shell's Tweener module will - * be handled properly, but other animations may be detected as terminating - * early if they can be drawn fast enough so that the event loop goes idle - * between frames. + * approximation. Animations may be detected as terminating early if they + * can be drawn fast enough so that the event loop goes idle between frames. * * The intent of this function is for performance measurement runs * where a number of actions should be run serially and each action is