From 74ca9a8a074380ee05cc94ee74c7cf9358f9004a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Fri, 4 Oct 2019 15:02:40 +0200 Subject: [PATCH 01/10] environment: Use zero duration for animations if disabled If animations are disabled we force the duration to 1ms, however this would still imply to pass through the transition code path, instead of applying the changes promptly. Use different adjustment for tweener animations instead to preserve logic prior to commit 99b4e047d. Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/1749 --- js/ui/environment.js | 2 +- js/ui/tweener.js | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/js/ui/environment.js b/js/ui/environment.js index 38d1d281a6..43ec2128cf 100644 --- a/js/ui/environment.js +++ b/js/ui/environment.js @@ -293,7 +293,7 @@ function adjustAnimationTime(msecs) { let settings = St.Settings.get(); if (!settings.enable_animations) - return 1; + return 0; return settings.slow_down_factor * msecs; } diff --git a/js/ui/tweener.js b/js/ui/tweener.js index 221438c1bd..56f430a691 100644 --- a/js/ui/tweener.js +++ b/js/ui/tweener.js @@ -7,7 +7,7 @@ const { Clutter, GLib, Shell } = imports.gi; const Signals = imports.signals; const Tweener = imports.tweener.tweener; -const { adjustAnimationTime } = imports.ui.environment; +const Environment = 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 @@ -39,6 +39,11 @@ function addTween(target, tweeningParameters) { Tweener.addTween(target, tweeningParameters); } +function adjustAnimationTime(msecs) { + let time = Environment.adjustAnimationTime(1000 * msecs) / 1000; + return time ? time : 0.000001; +} + function _wrapTweening(target, tweeningParameters) { let state = _getTweenState(target); @@ -54,9 +59,9 @@ function _wrapTweening(target, tweeningParameters) { let { time, delay } = tweeningParameters; if (!isNaN(time)) - tweeningParameters['time'] = adjustAnimationTime(1000 * time) / 1000; + tweeningParameters['time'] = adjustAnimationTime(time); if (!isNaN(delay)) - tweeningParameters['delay'] = adjustAnimationTime(1000 * delay) / 1000; + tweeningParameters['delay'] = adjustAnimationTime(delay); _addHandler(target, tweeningParameters, 'onComplete', _tweenCompleted); } -- GitLab From 43d2dbecd8011d0df05c804ab2c9c87b5efcce52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Tue, 8 Oct 2019 18:33:14 +0200 Subject: [PATCH 02/10] iconGrid: Avoid any animation computation if animations are disabled If animations are disabled we still do lots of computations and we allocate actors clones even if they are not needed, and if the animation callback happens promptly we might try to access to clones that have been already destroyed as part of the cleanup. So, in case animations are disabled, just don't try to animate any grid children. https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/752 --- js/ui/iconGrid.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/js/ui/iconGrid.js b/js/ui/iconGrid.js index ffddd11bdf..d893fd4639 100644 --- a/js/ui/iconGrid.js +++ b/js/ui/iconGrid.js @@ -436,6 +436,8 @@ var IconGrid = GObject.registerClass({ * set of items to be animated. */ _getChildrenToAnimate() { + if (!St.Settings.get().enable_animations) + return []; return this._getVisibleChildren().filter(child => child.opacity > 0); } -- GitLab From ae34925be8366140a63c9969c8552e57ba0b483d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Tue, 8 Oct 2019 18:42:06 +0200 Subject: [PATCH 03/10] overview: Replace deprecated raise_top() with set_child_above_sibling() https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/752 --- js/ui/overview.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/js/ui/overview.js b/js/ui/overview.js index e4837c8211..90ea4d1f26 100644 --- a/js/ui/overview.js +++ b/js/ui/overview.js @@ -540,7 +540,8 @@ var Overview = class { }); this._shadeBackgrounds(); - this._coverPane.raise_top(); + Main.layoutManager.overviewGroup.set_child_above_sibling( + this._coverPane, null); this._coverPane.show(); this.emit('showing'); } @@ -603,7 +604,8 @@ var Overview = class { }); this._unshadeBackgrounds(); - this._coverPane.raise_top(); + Main.layoutManager.overviewGroup.set_child_above_sibling( + this._coverPane, null); this._coverPane.show(); this.emit('hiding'); } -- GitLab From f83cd0067474747f369c8854e7a490d48dd66335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Tue, 8 Oct 2019 18:42:50 +0200 Subject: [PATCH 04/10] overview: Show and raise the cover pane before animating When animations are disabled the overview easing onComplete callback is called with no delay, and in such case we'd end up to hide the the coverPane first and then to show it, making impossible to interact with the overview. In order to avoid this, show the cover pane before easing the overview so that the show/hide order is always preserved. https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/752 --- js/ui/overview.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/js/ui/overview.js b/js/ui/overview.js index 90ea4d1f26..00fb77a1bb 100644 --- a/js/ui/overview.js +++ b/js/ui/overview.js @@ -531,6 +531,10 @@ var Overview = class { Meta.disable_unredirect_for_display(global.display); this.viewSelector.show(); + Main.layoutManager.overviewGroup.set_child_above_sibling( + this._coverPane, null); + this._coverPane.show(); + this._overview.opacity = 0; this._overview.ease({ opacity: 255, @@ -540,9 +544,6 @@ var Overview = class { }); this._shadeBackgrounds(); - Main.layoutManager.overviewGroup.set_child_above_sibling( - this._coverPane, null); - this._coverPane.show(); this.emit('showing'); } @@ -595,6 +596,10 @@ var Overview = class { this.viewSelector.animateFromOverview(); + Main.layoutManager.overviewGroup.set_child_above_sibling( + this._coverPane, null); + this._coverPane.show(); + // Make other elements fade out. this._overview.ease({ opacity: 0, @@ -604,9 +609,6 @@ var Overview = class { }); this._unshadeBackgrounds(); - Main.layoutManager.overviewGroup.set_child_above_sibling( - this._coverPane, null); - this._coverPane.show(); this.emit('hiding'); } -- GitLab From fb948b27e1f45b27d12073f47c91268e11b0de11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 9 Oct 2019 00:32:35 +0200 Subject: [PATCH 05/10] dnd: Manually perform the dragActor transition if animations are disabled In case animations are disabled and we have no transition time set, the 'scale-x' transition is unset as it's performed immediately, and so we won't adjust the drag offset variables and the drag actor position. To ensure this always works, check for transition and if not set, call the new-frame callback manually. https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/752 --- js/ui/dnd.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/js/ui/dnd.js b/js/ui/dnd.js index 786d654199..094ab9fce0 100644 --- a/js/ui/dnd.js +++ b/js/ui/dnd.js @@ -430,14 +430,20 @@ var _Draggable = class _Draggable { mode: Clutter.AnimationMode.EASE_OUT_QUAD }); - this._dragActor.get_transition('scale-x').connect('new-frame', () => { + let transition = this._dragActor.get_transition('scale-x'); + let transitionFrame = () => { let currentScale = this._dragActor.scale_x / origScale; this._dragOffsetX = currentScale * origDragOffsetX; this._dragOffsetY = currentScale * origDragOffsetY; this._dragActor.set_position( this._dragX + this._dragOffsetX, this._dragY + this._dragOffsetY); - }); + }; + + if (transition) + transition.connect('new-frame', transitionFrame); + else + transitionFrame(); } } } -- GitLab From 2a3bb434bb1cdf3af41ccfb18c7e7827015f7646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 9 Oct 2019 02:45:04 +0200 Subject: [PATCH 06/10] environment: Add onNewFrame callback to transitions Some animations such as the one on DND, might need to change properties at each animation frame, so add ability to set a callback function to be called at every animation tick, with the current progress as argument. And call this even if the animation has no duration. This allows to replace the code in DND that was fetching an arbitrary transition to monitor frames, but that was not working as expected in case the animation duration was 0. https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/752 --- js/ui/dnd.js | 25 +++++++++---------------- js/ui/environment.js | 26 ++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/js/ui/dnd.js b/js/ui/dnd.js index 094ab9fce0..b62e6a3c8e 100644 --- a/js/ui/dnd.js +++ b/js/ui/dnd.js @@ -427,23 +427,16 @@ var _Draggable = class _Draggable { scale_x: scale * origScale, scale_y: scale * origScale, duration: SCALE_ANIMATION_TIME, - mode: Clutter.AnimationMode.EASE_OUT_QUAD + mode: Clutter.AnimationMode.EASE_OUT_QUAD, + onNewFrame: () => { + let currentScale = this._dragActor.scale_x / origScale; + this._dragOffsetX = currentScale * origDragOffsetX; + this._dragOffsetY = currentScale * origDragOffsetY; + this._dragActor.set_position( + this._dragX + this._dragOffsetX, + this._dragY + this._dragOffsetY); + } }); - - let transition = this._dragActor.get_transition('scale-x'); - let transitionFrame = () => { - let currentScale = this._dragActor.scale_x / origScale; - this._dragOffsetX = currentScale * origDragOffsetX; - this._dragOffsetY = currentScale * origDragOffsetY; - this._dragActor.set_position( - this._dragX + this._dragOffsetX, - this._dragY + this._dragOffsetY); - }; - - if (transition) - transition.connect('new-frame', transitionFrame); - else - transitionFrame(); } } } diff --git a/js/ui/environment.js b/js/ui/environment.js index 43ec2128cf..2e39e86fd4 100644 --- a/js/ui/environment.js +++ b/js/ui/environment.js @@ -75,6 +75,15 @@ function _makeEaseCallback(params, cleanup) { }; } +function _makeFrameCallback(params) { + let onNewFrame = params.onNewFrame; + delete params.onNewFrame; + + if (onNewFrame) + return (progress) => onNewFrame(progress); + return null; +} + function _getPropertyTarget(actor, propName) { if (!propName.startsWith('@')) return [actor, propName]; @@ -113,6 +122,7 @@ function _easeActor(actor, params) { let cleanup = () => Meta.enable_unredirect_for_display(global.display); let callback = _makeEaseCallback(params, cleanup); + let frameCallback = _makeFrameCallback(params); // cancel overwritten transitions let animatedProps = Object.keys(params).map(p => p.replace('_', '-', 'g')); @@ -124,10 +134,15 @@ function _easeActor(actor, params) { let transition = animatedProps.map(p => actor.get_transition(p)) .find(t => t !== null); - if (transition) + if (transition) { + if (frameCallback) + transition.connect('new-frame', (t) => frameCallback(t.get_progress())); transition.connect('stopped', (t, finished) => callback(finished)); - else + } else { + if (frameCallback) + frameCallback(1.0); callback(true); + } } function _easeActorProperty(actor, propName, target, params) { @@ -149,6 +164,7 @@ function _easeActorProperty(actor, propName, target, params) { let cleanup = () => Meta.enable_unredirect_for_display(global.display); let callback = _makeEaseCallback(params, cleanup); + let frameCallback = _makeFrameCallback(params); // cancel overwritten transition actor.remove_transition(propName); @@ -157,6 +173,9 @@ function _easeActorProperty(actor, propName, target, params) { let [obj, prop] = _getPropertyTarget(actor, propName); obj[prop] = target; + if (frameCallback) + frameCallback(1.0); + callback(true); return; @@ -172,6 +191,9 @@ function _easeActorProperty(actor, propName, target, params) { transition.set_to(target); + if (frameCallback) + transition.connect('new-frame', (t) => frameCallback(t.get_progress())); + transition.connect('stopped', (t, finished) => callback(finished)); } -- GitLab From b04a5e2ab8037e4eb3694a27b4be0f1d173aeb02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 9 Oct 2019 00:33:47 +0200 Subject: [PATCH 07/10] workspace: Relayout the overlay before easing it. Ensure that the overlay values are reset even if animations are disabled. https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/752 --- js/ui/workspace.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/ui/workspace.js b/js/ui/workspace.js index a93b19add9..005c7d33bb 100644 --- a/js/ui/workspace.js +++ b/js/ui/workspace.js @@ -1402,6 +1402,7 @@ var Workspace = class { } _animateClone(clone, overlay, x, y, scale) { + clone.overlay.relayout(true); clone.ease({ x, y, scale_x: scale, @@ -1412,7 +1413,6 @@ var Workspace = class { this._showWindowOverlay(clone, overlay); } }); - clone.overlay.relayout(true); } _showWindowOverlay(clone, overlay) { -- GitLab From 39264e35a6047c351c63259a74811433c0f1269c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 9 Oct 2019 01:49:17 +0200 Subject: [PATCH 08/10] environment: Sanitize property target names for JS objects When an animation duration is 0 (and so even when an actor is unmapped), we just set the property without performing any transition, however if the property contains a dash (in the form 'property-name') and if this property is defined in a JS object, then gjs is not smart enough to do a property name conversion and will just set the object's 'property-name' ignoring the setter that we might have defined. And so, for example animations such as the SlideLayout sliding won't work. However, since starting with commit dfa41f692 we use native properties and all the object setters and getters need to use the snake_case in order to be called by clutter, just replace all the dashes in properties names with underscores to make sure that we call the actual setter. This is not a problem for the C side of things, as properties can be equally called using snake or parameter case. Also don't use String.replace for sanitizing because it will replace only the first occurrence unless using a RegExp, but since these are more expensive, let's just use the split+join hack. https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/752 --- js/ui/environment.js | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/js/ui/environment.js b/js/ui/environment.js index 2e39e86fd4..ef13a72114 100644 --- a/js/ui/environment.js +++ b/js/ui/environment.js @@ -86,12 +86,14 @@ function _makeFrameCallback(params) { function _getPropertyTarget(actor, propName) { if (!propName.startsWith('@')) - return [actor, propName]; + return [actor, propName.split('-').join('_')]; let [type, name, prop] = propName.split('.'); + if (prop) + prop = prop.split('-').join('_'); switch (type) { case '@layout': - return [actor.layout_manager, name]; + return [actor.layout_manager, name.split('-').join('_')]; case '@actions': return [actor.get_action(name), prop]; case '@constraints': @@ -124,9 +126,19 @@ function _easeActor(actor, params) { let callback = _makeEaseCallback(params, cleanup); let frameCallback = _makeFrameCallback(params); - // cancel overwritten transitions - let animatedProps = Object.keys(params).map(p => p.replace('_', '-', 'g')); - animatedProps.forEach(p => actor.remove_transition(p)); + // sanitize property names and cancel overwritten transitions + let animatedProps = []; + Object.keys(params).forEach(p => { + let pspecName = p.split('_').join('-'); + actor.remove_transition(pspecName); + animatedProps.push(pspecName); + + if (p.indexOf('-') !== -1) { + let prop = p.split('-').join('_'); + params[prop] = params[p]; + delete params[p]; + } + }); actor.set(params); actor.restore_easing_state(); -- GitLab From 497c286b3543ff1115e12f4e7638f79edbbe9d52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 9 Oct 2019 03:25:37 +0200 Subject: [PATCH 09/10] cleanup: Use easing with null duration instead of duplicated code When not animating we can avoid to repeat the same actions that the easing would perform by just setting the animation duration to 0. So do this, removing lots of code duplication that might easily lead to errors. https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/752 --- js/ui/messageList.js | 84 ++++++++++++++++++-------------------------- js/ui/messageTray.js | 40 +++++++++------------ js/ui/popupMenu.js | 46 +++++++++++------------- js/ui/workspace.js | 45 ++++++++---------------- 4 files changed, 86 insertions(+), 129 deletions(-) diff --git a/js/ui/messageList.js b/js/ui/messageList.js index 4dcdb6d7fd..65d9980012 100644 --- a/js/ui/messageList.js +++ b/js/ui/messageList.js @@ -438,47 +438,38 @@ var Message = class Message { this.setExpandedBody(this._expandedLabel.actor); } - if (animate) { - this._bodyStack.ease_property('@layout.expansion', 1, { - progress_mode: Clutter.AnimationMode.EASE_OUT_QUAD, - duration: MessageTray.ANIMATION_TIME, - }); + let duration = animate ? MessageTray.ANIMATION_TIME : 0; + this._bodyStack.ease_property('@layout.expansion', 1, { + progress_mode: Clutter.AnimationMode.EASE_OUT_QUAD, + duration, + }); - this._actionBin.scale_y = 0; - this._actionBin.ease({ - scale_y: 1, - duration: MessageTray.ANIMATION_TIME, - mode: Clutter.AnimationMode.EASE_OUT_QUAD - }); - } else { - this._bodyStack.layout_manager.expansion = 1; - this._actionBin.scale_y = 1; - } + this._actionBin.scale_y = 0; + this._actionBin.ease({ + scale_y: 1, + duration, + mode: Clutter.AnimationMode.EASE_OUT_QUAD + }); this.emit('expanded'); } unexpand(animate) { - if (animate) { - this._bodyStack.ease_property('@layout.expansion', 0, { - progress_mode: Clutter.AnimationMode.EASE_OUT_QUAD, - duration: MessageTray.ANIMATION_TIME, - }); + let duration = animate ? MessageTray.ANIMATION_TIME : 0; + this._bodyStack.ease_property('@layout.expansion', 0, { + progress_mode: Clutter.AnimationMode.EASE_OUT_QUAD, + duration, + }); - this._actionBin.ease({ - scale_y: 0, - duration: MessageTray.ANIMATION_TIME, - mode: Clutter.AnimationMode.EASE_OUT_QUAD, - onComplete: () => { - this._actionBin.hide(); - this.expanded = false; - } - }); - } else { - this._bodyStack.layout_manager.expansion = 0; - this._actionBin.scale_y = 0; - this.expanded = false; - } + this._actionBin.ease({ + scale_y: 0, + duration, + mode: Clutter.AnimationMode.EASE_OUT_QUAD, + onComplete: () => { + this._actionBin.hide(); + this.expanded = false; + } + }); this.emit('unexpanded'); } @@ -627,21 +618,16 @@ var MessageListSection = class MessageListSection { this._messages.delete(message); - if (animate) { - obj.container.ease({ - scale_x: 0, - scale_y: 0, - duration: MESSAGE_ANIMATION_TIME, - mode: Clutter.AnimationMode.EASE_OUT_QUAD, - onComplete: () => { - obj.container.destroy(); - global.sync_pointer(); - } - }); - } else { - obj.container.destroy(); - global.sync_pointer(); - } + obj.container.ease({ + scale_x: 0, + scale_y: 0, + duration: animate ? MESSAGE_ANIMATION_TIME : 0, + mode: Clutter.AnimationMode.EASE_OUT_QUAD, + onComplete: () => { + obj.container.destroy(); + global.sync_pointer(); + } + }); } clear() { diff --git a/js/ui/messageTray.js b/js/ui/messageTray.js index 560deda6ff..cc0dade963 100644 --- a/js/ui/messageTray.js +++ b/js/ui/messageTray.js @@ -1398,29 +1398,23 @@ var MessageTray = class MessageTray { this._resetNotificationLeftTimeout(); this._bannerBin.remove_all_transitions(); - if (animate) { - this._notificationState = State.HIDING; - this._bannerBin.ease({ - opacity: 0, - duration: ANIMATION_TIME, - mode: Clutter.AnimationMode.EASE_OUT_BACK - }); - this._bannerBin.ease({ - y: -this._bannerBin.height, - duration: ANIMATION_TIME, - mode: Clutter.AnimationMode.EASE_OUT_BACK, - onComplete: () => { - this._notificationState = State.HIDDEN; - this._hideNotificationCompleted(); - this._updateState(); - } - }); - } else { - this._bannerBin.y = -this._bannerBin.height; - this._bannerBin.opacity = 0; - this._notificationState = State.HIDDEN; - this._hideNotificationCompleted(); - } + let duration = animate ? ANIMATION_TIME : 0; + this._notificationState = State.HIDING; + this._bannerBin.ease({ + opacity: 0, + duration, + mode: Clutter.AnimationMode.EASE_OUT_BACK + }); + this._bannerBin.ease({ + y: -this._bannerBin.height, + duration, + mode: Clutter.AnimationMode.EASE_OUT_BACK, + onComplete: () => { + this._notificationState = State.HIDDEN; + this._hideNotificationCompleted(); + this._updateState(); + } + }); } _hideNotificationCompleted() { diff --git a/js/ui/popupMenu.js b/js/ui/popupMenu.js index 49ed823b12..aa17c3eb0d 100644 --- a/js/ui/popupMenu.js +++ b/js/ui/popupMenu.js @@ -1023,14 +1023,12 @@ var PopupSubMenu = class extends PopupMenuBase { mode: Clutter.AnimationMode.EASE_OUT_EXPO, onComplete: () => this.actor.set_height(-1) }); - this._arrow.ease({ - rotation_angle_z: targetAngle, - duration: 250, - mode: Clutter.AnimationMode.EASE_OUT_EXPO - }); - } else { - this._arrow.rotation_angle_z = targetAngle; } + this._arrow.ease({ + rotation_angle_z: targetAngle, + duration: animate ? 250 : 0, + mode: Clutter.AnimationMode.EASE_OUT_EXPO + }); } close(animate) { @@ -1046,25 +1044,21 @@ var PopupSubMenu = class extends PopupMenuBase { if (animate && this._needsScrollbar()) animate = false; - if (animate) { - this.actor.ease({ - height: 0, - duration: 250, - mode: Clutter.AnimationMode.EASE_OUT_EXPO, - onComplete: () => { - this.actor.hide(); - this.actor.set_height(-1); - } - }); - this._arrow.ease({ - rotation_angle_z: 0, - duration: 250, - mode: Clutter.AnimationMode.EASE_OUT_EXPO - }); - } else { - this._arrow.rotation_angle_z = 0; - this.actor.hide(); - } + let duration = animate ? 250 : 0; + this.actor.ease({ + height: 0, + duration, + mode: Clutter.AnimationMode.EASE_OUT_EXPO, + onComplete: () => { + this.actor.hide(); + this.actor.set_height(-1); + } + }); + this._arrow.ease({ + rotation_angle_z: 0, + duration, + mode: Clutter.AnimationMode.EASE_OUT_EXPO + }); } _onKeyPressEvent(actor, event) { diff --git a/js/ui/workspace.js b/js/ui/workspace.js index 005c7d33bb..4d015ac61d 100644 --- a/js/ui/workspace.js +++ b/js/ui/workspace.js @@ -561,10 +561,8 @@ var WindowOverlay = class { else buttonX = cloneX + (cloneWidth - button._overlap); - if (animate) - this._animateOverlayActor(button, Math.floor(buttonX), Math.floor(buttonY), button.width); - else - button.set_position(Math.floor(buttonX), Math.floor(buttonY)); + this._resizeOverlayActor(button, animate, + Math.floor(buttonX), Math.floor(buttonY), button.width); // Clutter.Actor.get_preferred_width() will return the fixed width if // one is set, so we need to reset the width by calling set_width(-1), @@ -582,25 +580,16 @@ var WindowOverlay = class { let titleX = cloneX + (cloneWidth - titleWidth) / 2; let titleY = cloneY + cloneHeight - (title.height - this.borderSize) / 2; - if (animate) { - this._animateOverlayActor(title, Math.floor(titleX), Math.floor(titleY), titleWidth); - } else { - title.width = titleWidth; - title.set_position(Math.floor(titleX), Math.floor(titleY)); - } + this._resizeOverlayActor(title, animate, + Math.floor(titleX), Math.floor(titleY), titleWidth); let borderX = cloneX - this.borderSize; let borderY = cloneY - this.borderSize; let borderWidth = cloneWidth + 2 * this.borderSize; let borderHeight = cloneHeight + 2 * this.borderSize; - if (animate) { - this._animateOverlayActor(this.border, borderX, borderY, - borderWidth, borderHeight); - } else { - this.border.set_position(borderX, borderY); - this.border.set_size(borderWidth, borderHeight); - } + this._resizeOverlayActor(this.border, animate, + borderX, borderY, borderWidth, borderHeight); } _getCaption() { @@ -613,10 +602,10 @@ var WindowOverlay = class { return app.get_name(); } - _animateOverlayActor(actor, x, y, width, height) { + _resizeOverlayActor(actor, animate, x, y, width, height) { let params = { x, y, width, - duration: Overview.ANIMATION_TIME, + duration: animate ? Overview.ANIMATION_TIME : 0, mode: Clutter.AnimationMode.EASE_OUT_QUAD }; @@ -1349,7 +1338,9 @@ var Workspace = class { clone.positioned = true; } + let animateClone; if (animate && isOnCurrentWorkspace) { + animateClone = true; if (!clone.metaWindow.showing_on_its_workspace()) { /* Hidden windows should fade in and grow * therefore we need to resize them now so they @@ -1368,17 +1359,9 @@ var Workspace = class { duration: Overview.ANIMATION_TIME }); } - - this._animateClone(clone, clone.overlay, x, y, scale); - } else { - // cancel any active tweens (otherwise they might override our changes) - clone.remove_all_transitions(); - clone.set_position(x, y); - clone.set_scale(scale, scale); - clone.set_opacity(255); - clone.overlay.relayout(false); - this._showWindowOverlay(clone, clone.overlay); } + + this._moveClone(clone, clone.overlay, animateClone, x, y, scale); } } @@ -1401,13 +1384,13 @@ var Workspace = class { } } - _animateClone(clone, overlay, x, y, scale) { + _moveClone(clone, overlay, animate, x, y, scale) { clone.overlay.relayout(true); clone.ease({ x, y, scale_x: scale, scale_y: scale, - duration: Overview.ANIMATION_TIME, + duration: animate ? Overview.ANIMATION_TIME : 0, mode: Clutter.AnimationMode.EASE_OUT_QUAD, onComplete: () => { this._showWindowOverlay(clone, overlay); -- GitLab From 7b9bf5569a6be867ddbe4aff0f54f5050f918a08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 9 Oct 2019 05:14:15 +0200 Subject: [PATCH 10/10] animation: Finish porting to clutter transitions https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/752 --- js/ui/animation.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/ui/animation.js b/js/ui/animation.js index a1f257efce..18c837e822 100644 --- a/js/ui/animation.js +++ b/js/ui/animation.js @@ -167,8 +167,8 @@ var Spinner = class extends AnimatedIcon { if (this._animate) { this.actor.ease({ opacity: 0, - time: SPINNER_ANIMATION_TIME, - transition: 'linear', + duration: SPINNER_ANIMATION_TIME, + mode: Clutter.AnimationMode.LINEAR, onComplete: () => super.stop() }); } else { -- GitLab