- Revision
- 290045
- Author
- [email protected]
- Date
- 2022-02-17 12:02:04 -0800 (Thu, 17 Feb 2022)
Log Message
[GTK] REGRESSION: Cumulative velocity for scrolling doesn't work
https://bugs.webkit.org/show_bug.cgi?id=235507
Reviewed by Chris Lord.
ScrollAnimationKinetic can accumulate velocity from the previous scroll
animation. This relies on reusing the same animation every time, so it can
pick up the previous scroll data.
However, ScrollingEffectsController now creates and destroys ScrollAnimationKinetic
every time now, we can't rely on that.
Instead, save and propagate the data manually, same as the macOS port.
* platform/ScrollAnimationKinetic.cpp:
(WebCore::ScrollAnimationKinetic::startAnimatedScrollWithInitialVelocity):
(WebCore::ScrollAnimationKinetic::accumulateVelocityFromPreviousGesture):
* platform/ScrollAnimationKinetic.h:
* platform/ScrollingEffectsController.cpp:
(WebCore::ScrollingEffectsController::processWheelEventForKineticScrolling):
* platform/ScrollingEffectsController.h:
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (290044 => 290045)
--- trunk/Source/WebCore/ChangeLog 2022-02-17 19:59:25 UTC (rev 290044)
+++ trunk/Source/WebCore/ChangeLog 2022-02-17 20:02:04 UTC (rev 290045)
@@ -1,3 +1,27 @@
+2022-02-17 Alexander Mikhaylenko <[email protected]>
+
+ [GTK] REGRESSION: Cumulative velocity for scrolling doesn't work
+ https://bugs.webkit.org/show_bug.cgi?id=235507
+
+ Reviewed by Chris Lord.
+
+ ScrollAnimationKinetic can accumulate velocity from the previous scroll
+ animation. This relies on reusing the same animation every time, so it can
+ pick up the previous scroll data.
+
+ However, ScrollingEffectsController now creates and destroys ScrollAnimationKinetic
+ every time now, we can't rely on that.
+
+ Instead, save and propagate the data manually, same as the macOS port.
+
+ * platform/ScrollAnimationKinetic.cpp:
+ (WebCore::ScrollAnimationKinetic::startAnimatedScrollWithInitialVelocity):
+ (WebCore::ScrollAnimationKinetic::accumulateVelocityFromPreviousGesture):
+ * platform/ScrollAnimationKinetic.h:
+ * platform/ScrollingEffectsController.cpp:
+ (WebCore::ScrollingEffectsController::processWheelEventForKineticScrolling):
+ * platform/ScrollingEffectsController.h:
+
2022-02-17 Antti Koivisto <[email protected]>
[CSS Container Queries] Support full range notation in size queries
Modified: trunk/Source/WebCore/platform/ScrollAnimationKinetic.cpp (290044 => 290045)
--- trunk/Source/WebCore/platform/ScrollAnimationKinetic.cpp 2022-02-17 19:59:25 UTC (rev 290044)
+++ trunk/Source/WebCore/platform/ScrollAnimationKinetic.cpp 2022-02-17 20:02:04 UTC (rev 290045)
@@ -150,8 +150,11 @@
return FloatSize(accumDelta.x() * -1 / (last - first).value(), accumDelta.y() * -1 / (last - first).value());
}
-bool ScrollAnimationKinetic::startAnimatedScrollWithInitialVelocity(const FloatPoint& initialOffset, const FloatSize& velocity, bool mayHScroll, bool mayVScroll)
+bool ScrollAnimationKinetic::startAnimatedScrollWithInitialVelocity(const FloatPoint& initialOffset, const FloatSize& velocity, const FloatSize& previousVelocity, bool mayHScroll, bool mayVScroll)
{
+ m_initialOffset = initialOffset;
+ m_initialVelocity = velocity;
+
stop();
if (velocity.isZero()) {
@@ -160,19 +163,15 @@
return false;
}
- auto elapsedTime = 0_s;
auto extents = m_client.scrollExtentsForAnimation(*this);
- auto accumulateVelocity = [&](double velocity, std::optional<PerAxisData> axisData) -> double {
- if (axisData && axisData.value().animateScroll(elapsedTime)) {
- double lastVelocity = axisData.value().velocity();
- if ((std::signbit(lastVelocity) == std::signbit(velocity))
- && (std::abs(velocity) >= std::abs(lastVelocity * velocityAccumulationFloor))) {
- double minVelocity = lastVelocity * velocityAccumulationFloor;
- double maxVelocity = lastVelocity * velocityAccumulationCeil;
- double accumulationMultiplier = (velocity - minVelocity) / (maxVelocity - minVelocity);
- velocity += lastVelocity * std::min(accumulationMultiplier, velocityAccumulationMax);
- }
+ auto accumulateVelocity = [&](double velocity, double previousVelocity) -> double {
+ if ((std::signbit(previousVelocity) == std::signbit(velocity))
+ && (std::abs(velocity) >= std::abs(previousVelocity * velocityAccumulationFloor))) {
+ double minVelocity = previousVelocity * velocityAccumulationFloor;
+ double maxVelocity = previousVelocity * velocityAccumulationCeil;
+ double accumulationMultiplier = (velocity - minVelocity) / (maxVelocity - minVelocity);
+ velocity += previousVelocity * std::min(accumulationMultiplier, velocityAccumulationMax);
}
return velocity;
@@ -181,7 +180,7 @@
if (mayHScroll) {
m_horizontalData = PerAxisData(extents.minimumScrollOffset().x(),
extents.maximumScrollOffset().x(),
- initialOffset.x(), accumulateVelocity(velocity.width(), m_horizontalData));
+ initialOffset.x(), accumulateVelocity(velocity.width(), previousVelocity.width()));
} else
m_horizontalData = std::nullopt;
@@ -188,7 +187,7 @@
if (mayVScroll) {
m_verticalData = PerAxisData(extents.minimumScrollOffset().y(),
extents.maximumScrollOffset().y(),
- initialOffset.y(), accumulateVelocity(velocity.height(), m_verticalData));
+ initialOffset.y(), accumulateVelocity(velocity.height(), previousVelocity.height()));
} else
m_verticalData = std::nullopt;
@@ -232,5 +231,23 @@
return textStream.release();
}
+FloatSize ScrollAnimationKinetic::accumulateVelocityFromPreviousGesture(const MonotonicTime lastStartTime, const FloatPoint& lastInitialOffset, const FloatSize& lastInitialVelocity)
+{
+ auto elapsedTime = MonotonicTime::now() - lastStartTime;
+ auto extents = m_client.scrollExtentsForAnimation(*this);
+ auto horizontalData = PerAxisData(extents.minimumScrollOffset().x(),
+ extents.maximumScrollOffset().x(),
+ lastInitialOffset.x(), lastInitialVelocity.width());
+
+ auto verticalData = PerAxisData(extents.minimumScrollOffset().y(),
+ extents.maximumScrollOffset().y(),
+ lastInitialOffset.y(), lastInitialVelocity.height());
+
+ horizontalData.animateScroll(elapsedTime);
+ verticalData.animateScroll(elapsedTime);
+
+ return FloatSize(horizontalData.velocity(), verticalData.velocity());
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/ScrollAnimationKinetic.h (290044 => 290045)
--- trunk/Source/WebCore/platform/ScrollAnimationKinetic.h 2022-02-17 19:59:25 UTC (rev 290044)
+++ trunk/Source/WebCore/platform/ScrollAnimationKinetic.h 2022-02-17 20:02:04 UTC (rev 290045)
@@ -60,7 +60,7 @@
ScrollAnimationKinetic(ScrollAnimationClient&);
virtual ~ScrollAnimationKinetic();
- bool startAnimatedScrollWithInitialVelocity(const FloatPoint& initialOffset, const FloatSize& velocity, bool mayHScroll, bool mayVScroll);
+ bool startAnimatedScrollWithInitialVelocity(const FloatPoint& initialOffset, const FloatSize& velocity, const FloatSize& previousVelocity, bool mayHScroll, bool mayVScroll);
bool retargetActiveAnimation(const FloatPoint& newOffset) final;
void appendToScrollHistory(const PlatformWheelEvent&);
@@ -68,6 +68,12 @@
FloatSize computeVelocity();
+ MonotonicTime startTime() { return m_startTime; }
+ FloatSize initialVelocity() { return m_initialVelocity; }
+ FloatPoint initialOffset() { return m_initialOffset; }
+
+ FloatSize accumulateVelocityFromPreviousGesture(const MonotonicTime, const FloatPoint&, const FloatSize&);
+
private:
void serviceAnimation(MonotonicTime) final;
String debugDescription() const final;
@@ -76,6 +82,8 @@
std::optional<PerAxisData> m_verticalData;
Vector<PlatformWheelEvent> m_scrollHistory;
+ FloatPoint m_initialOffset;
+ FloatSize m_initialVelocity;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/ScrollingEffectsController.cpp (290044 => 290045)
--- trunk/Source/WebCore/platform/ScrollingEffectsController.cpp 2022-02-17 19:59:25 UTC (rev 290044)
+++ trunk/Source/WebCore/platform/ScrollingEffectsController.cpp 2022-02-17 20:02:04 UTC (rev 290045)
@@ -276,11 +276,19 @@
#if ENABLE(KINETIC_SCROLLING)
bool ScrollingEffectsController::processWheelEventForKineticScrolling(const PlatformWheelEvent& event)
{
- if (is<ScrollAnimationKinetic>(m_currentAnimation.get()))
+ if (is<ScrollAnimationKinetic>(m_currentAnimation.get())) {
+ auto& kineticAnimation = downcast<ScrollAnimationKinetic>(*m_currentAnimation);
+
+ m_previousKineticAnimationInfo.startTime = kineticAnimation.startTime();
+ m_previousKineticAnimationInfo.initialOffset = kineticAnimation.initialOffset();
+ m_previousKineticAnimationInfo.initialVelocity = kineticAnimation.initialVelocity();
+
m_currentAnimation->stop();
+ }
if (!event.hasPreciseScrollingDeltas()) {
m_scrollHistory.clear();
+ m_previousKineticAnimationInfo.initialVelocity = FloatSize();
return false;
}
@@ -294,6 +302,7 @@
if (m_currentAnimation && !is<ScrollAnimationKinetic>(m_currentAnimation.get())) {
m_currentAnimation->stop();
m_currentAnimation = nullptr;
+ m_previousKineticAnimationInfo.initialVelocity = FloatSize();
}
if (usesScrollSnap())
@@ -306,13 +315,20 @@
while (!m_scrollHistory.isEmpty())
kineticAnimation.appendToScrollHistory(m_scrollHistory.takeFirst());
+ FloatSize previousVelocity;
+ if (!m_previousKineticAnimationInfo.initialVelocity.isZero()) {
+ previousVelocity = kineticAnimation.accumulateVelocityFromPreviousGesture(m_previousKineticAnimationInfo.startTime,
+ m_previousKineticAnimationInfo.initialOffset, m_previousKineticAnimationInfo.initialVelocity);
+ m_previousKineticAnimationInfo.initialVelocity = FloatSize();
+ }
+
if (event.isEndOfNonMomentumScroll()) {
- kineticAnimation.startAnimatedScrollWithInitialVelocity(m_client.scrollOffset(), kineticAnimation.computeVelocity(), m_client.allowsHorizontalScrolling(), m_client.allowsVerticalScrolling());
+ kineticAnimation.startAnimatedScrollWithInitialVelocity(m_client.scrollOffset(), kineticAnimation.computeVelocity(), previousVelocity, m_client.allowsHorizontalScrolling(), m_client.allowsVerticalScrolling());
return true;
}
if (event.isTransitioningToMomentumScroll()) {
kineticAnimation.clearScrollHistory();
- kineticAnimation.startAnimatedScrollWithInitialVelocity(m_client.scrollOffset(), event.swipeVelocity(), m_client.allowsHorizontalScrolling(), m_client.allowsVerticalScrolling());
+ kineticAnimation.startAnimatedScrollWithInitialVelocity(m_client.scrollOffset(), event.swipeVelocity(), previousVelocity, m_client.allowsHorizontalScrolling(), m_client.allowsVerticalScrolling());
return true;
}
Modified: trunk/Source/WebCore/platform/ScrollingEffectsController.h (290044 => 290045)
--- trunk/Source/WebCore/platform/ScrollingEffectsController.h 2022-02-17 19:59:25 UTC (rev 290044)
+++ trunk/Source/WebCore/platform/ScrollingEffectsController.h 2022-02-17 20:02:04 UTC (rev 290045)
@@ -237,6 +237,12 @@
bool processWheelEventForKineticScrolling(const PlatformWheelEvent&);
Deque<PlatformWheelEvent> m_scrollHistory;
+
+ struct {
+ MonotonicTime startTime;
+ FloatPoint initialOffset;
+ FloatSize initialVelocity;
+ } m_previousKineticAnimationInfo;
#endif
ScrollingEffectsControllerClient& m_client;