[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
This commit is contained in:
Vlad Zagorodniy 2018-09-20 20:35:01 +03:00
parent 2d3431aede
commit 66a91f0861

View file

@ -388,11 +388,17 @@ void SlidingPopupsEffect::slideIn(EffectWindow *w)
Animation &animation = m_animations[w]; Animation &animation = m_animations[w];
animation.kind = AnimationKind::In; animation.kind = AnimationKind::In;
animation.timeLine.reset();
animation.timeLine.setDirection(TimeLine::Forward); animation.timeLine.setDirection(TimeLine::Forward);
animation.timeLine.setDuration((*dataIt).slideInDuration); animation.timeLine.setDuration((*dataIt).slideInDuration);
animation.timeLine.setEasingCurve(QEasingCurve::InOutSine); 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<void*>(this))); w->setData(WindowAddedGrabRole, QVariant::fromValue(static_cast<void*>(this)));
w->setData(WindowForceBackgroundContrastRole, QVariant(true)); w->setData(WindowForceBackgroundContrastRole, QVariant(true));
w->setData(WindowForceBlurRole, QVariant(true)); w->setData(WindowForceBlurRole, QVariant(true));
@ -421,11 +427,17 @@ void SlidingPopupsEffect::slideOut(EffectWindow *w)
Animation &animation = m_animations[w]; Animation &animation = m_animations[w];
animation.kind = AnimationKind::Out; animation.kind = AnimationKind::Out;
animation.timeLine.reset();
animation.timeLine.setDirection(TimeLine::Backward); animation.timeLine.setDirection(TimeLine::Backward);
animation.timeLine.setDuration((*dataIt).slideOutDuration); animation.timeLine.setDuration((*dataIt).slideOutDuration);
animation.timeLine.setEasingCurve(QEasingCurve::InOutSine); 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<void*>(this))); w->setData(WindowClosedGrabRole, QVariant::fromValue(static_cast<void*>(this)));
w->setData(WindowForceBackgroundContrastRole, QVariant(true)); w->setData(WindowForceBackgroundContrastRole, QVariant(true));
w->setData(WindowForceBlurRole, QVariant(true)); w->setData(WindowForceBlurRole, QVariant(true));