From 66a91f086196f83f79dea35004aafba529b3cad9 Mon Sep 17 00:00:00 2001 From: Vlad Zagorodniy Date: Thu, 20 Sep 2018 20:35:01 +0300 Subject: [PATCH] [effects/slidingpopups] Fix jumpy transition between In and Out animations Summary: If a window is being slided in and for some reason it gets closed, the window will be slided out. The problem is that there is a jump between the slide in animation and the slide out animation. The reason for that is we cancel the slide in animation when the slide out animation is started. It makes sense to cancel previously active animations because they have different durations. But visually, it doesn't look good. TimeLine tries to preserve progress value when changing duration. Thus, let's utilize that to fix the jump. This change matters only with animation speed factor > 1.0. CCBUG: 264276 Test Plan: Manually. Reviewers: #kwin, davidedmundson Reviewed By: #kwin, davidedmundson Subscribers: abetts, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D15626 --- effects/slidingpopups/slidingpopups.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/effects/slidingpopups/slidingpopups.cpp b/effects/slidingpopups/slidingpopups.cpp index 53c8e565a4..a0e3610710 100644 --- a/effects/slidingpopups/slidingpopups.cpp +++ b/effects/slidingpopups/slidingpopups.cpp @@ -388,11 +388,17 @@ void SlidingPopupsEffect::slideIn(EffectWindow *w) Animation &animation = m_animations[w]; animation.kind = AnimationKind::In; - animation.timeLine.reset(); animation.timeLine.setDirection(TimeLine::Forward); animation.timeLine.setDuration((*dataIt).slideInDuration); animation.timeLine.setEasingCurve(QEasingCurve::InOutSine); + // If the opposite animation (Out) was active and it had shorter duration, + // at this point, the timeline can end up in the "done" state. Thus, we have + // to reset it. + if (animation.timeLine.done()) { + animation.timeLine.reset(); + } + w->setData(WindowAddedGrabRole, QVariant::fromValue(static_cast(this))); w->setData(WindowForceBackgroundContrastRole, QVariant(true)); w->setData(WindowForceBlurRole, QVariant(true)); @@ -421,11 +427,17 @@ void SlidingPopupsEffect::slideOut(EffectWindow *w) Animation &animation = m_animations[w]; animation.kind = AnimationKind::Out; - animation.timeLine.reset(); animation.timeLine.setDirection(TimeLine::Backward); animation.timeLine.setDuration((*dataIt).slideOutDuration); animation.timeLine.setEasingCurve(QEasingCurve::InOutSine); + // If the opposite animation (In) was active and it had shorter duration, + // at this point, the timeline can end up in the "done" state. Thus, we have + // to reset it. + if (animation.timeLine.done()) { + animation.timeLine.reset(); + } + w->setData(WindowClosedGrabRole, QVariant::fromValue(static_cast(this))); w->setData(WindowForceBackgroundContrastRole, QVariant(true)); w->setData(WindowForceBlurRole, QVariant(true));