Diff
Modified: trunk/Source/WebCore/ChangeLog (283018 => 283019)
--- trunk/Source/WebCore/ChangeLog 2021-09-23 23:08:19 UTC (rev 283018)
+++ trunk/Source/WebCore/ChangeLog 2021-09-23 23:54:41 UTC (rev 283019)
@@ -1,3 +1,89 @@
+2021-09-23 Simon Fraser <[email protected]>
+
+ Move the ScrollAnimationSmooth from ScrollAnimator into ScrollingEffectsController
+ https://bugs.webkit.org/show_bug.cgi?id=230720
+
+ Reviewed by Tim Horton.
+
+ ScrollingEffectsController is where all the ScrollAnimations will live. The first
+ step is to move ScrollAnimator's m_scrollAnimation there; this is used for
+ keyboard scrolling, and CSS smooth scrolling.
+
+ ScrollingEffectsController becomes a ScrollAnimationClient (and ScrollAnimator stops
+ being one), so needs a little bit more glue code.
+
+ Add type traits for ScrollAnimator subclasses because we need to downcast<> them
+ here and in future patches.
+
+ Move some code from ScrollAnimatorMac into ScrollAnimator since it's not platform
+ specific.
+
+ ScrollAnimatorGeneric is almost entirely gutted, and code pushed into ScrollingEffectsController.
+ Make a ScrollAnimationKinetic in ScrollingEffectsController for this code path.
+
+ * page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.h:
+ * page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm:
+ (WebCore::ScrollingTreeScrollingNodeDelegateMac::immediateScrollOnAxis): Deleted.
+ * platform/ScrollAnimation.h:
+ (WebCore::ScrollAnimation::ScrollAnimation):
+ (WebCore::ScrollAnimation::type const):
+ * platform/ScrollAnimationKinetic.cpp:
+ (WebCore::ScrollAnimationKinetic::ScrollAnimationKinetic):
+ * platform/ScrollAnimationKinetic.h:
+ * platform/ScrollAnimationMomentum.cpp:
+ (WebCore::ScrollAnimationMomentum::ScrollAnimationMomentum):
+ * platform/ScrollAnimationMomentum.h:
+ * platform/ScrollAnimationSmooth.cpp:
+ (WebCore::ScrollAnimationSmooth::ScrollAnimationSmooth):
+ * platform/ScrollAnimationSmooth.h:
+ * platform/ScrollAnimator.cpp:
+ (WebCore::ScrollAnimator::ScrollAnimator):
+ (WebCore::ScrollAnimator::scroll):
+ (WebCore::ScrollAnimator::scrollToPositionWithoutAnimation):
+ (WebCore::ScrollAnimator::scrollToPositionWithAnimation):
+ (WebCore::ScrollAnimator::retargetRunningAnimation):
+ (WebCore::ScrollAnimator::setScrollBehaviorStatus):
+ (WebCore::ScrollAnimator::scrollBehaviorStatus const):
+ (WebCore::ScrollAnimator::adjustScrollPositionToBoundsIfNecessary):
+ (WebCore::ScrollAnimator::adjustScrollPositionIfNecessary const):
+ (WebCore::ScrollAnimator::immediateScrollByWithoutContentEdgeConstraints):
+ (WebCore::ScrollAnimator::immediateScrollBy):
+ (WebCore::ScrollAnimator::cancelAnimations):
+ (WebCore::ScrollAnimator::contentsSizeChanged):
+ (WebCore::ScrollAnimator::immediateScrollOnAxis): Deleted.
+ (WebCore::ScrollAnimator::contentsSizeChanged const): Deleted.
+ (WebCore::ScrollAnimator::scrollAnimationDidUpdate): Deleted.
+ (WebCore::ScrollAnimator::scrollAnimationDidEnd): Deleted.
+ (WebCore::ScrollAnimator::scrollExtentsForAnimation): Deleted.
+ * platform/ScrollAnimator.h:
+ * platform/ScrollingEffectsController.cpp:
+ (WebCore::ScrollingEffectsController::startAnimatedScrollToDestination):
+ (WebCore::ScrollingEffectsController::regargetAnimatedScroll):
+ (WebCore::ScrollingEffectsController::stopAnimatedScroll):
+ (WebCore::ScrollingEffectsController::processWheelEventForKineticScrolling):
+ (WebCore::ScrollingEffectsController::contentsSizeChanged):
+ (WebCore::ScrollingEffectsController::activeScrollSnapIndexForAxis const):
+ (WebCore::ScrollingEffectsController::scrollToOffsetForAnimation):
+ (WebCore::ScrollingEffectsController::scrollAnimationDidUpdate):
+ (WebCore::ScrollingEffectsController::scrollAnimationDidEnd):
+ (WebCore::ScrollingEffectsController::scrollExtentsForAnimation):
+ * platform/ScrollingEffectsController.h:
+ (WebCore::ScrollingEffectsControllerClient::rubberBandingStateChanged):
+ * platform/generic/ScrollAnimatorGeneric.cpp:
+ (WebCore::ScrollAnimatorGeneric::ScrollAnimatorGeneric):
+ (WebCore::ScrollAnimatorGeneric::handleWheelEvent):
+ (WebCore::ScrollAnimatorGeneric::scrollToPositionWithoutAnimation): Deleted.
+ (WebCore::ScrollAnimatorGeneric::scrollAnimationDidUpdate): Deleted.
+ * platform/generic/ScrollAnimatorGeneric.h:
+ * platform/mac/ScrollAnimatorMac.h:
+ * platform/mac/ScrollAnimatorMac.mm:
+ (WebCore::ScrollAnimatorMac::adjustScrollPositionIfNecessary const): Deleted.
+ (WebCore::ScrollAnimatorMac::adjustScrollPositionToBoundsIfNecessary): Deleted.
+ (WebCore::ScrollAnimatorMac::immediateScrollByWithoutContentEdgeConstraints): Deleted.
+ (WebCore::ScrollAnimatorMac::immediateScrollBy): Deleted.
+ * platform/mac/ScrollingEffectsController.mm:
+ (WebCore::ScrollingEffectsController::updateScrollSnapAnimatingState):
+
2021-09-23 Nikos Mouchtaris <[email protected]>
Implement atan, acos, asin, atan2 calc functions
Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.h (283018 => 283019)
--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.h 2021-09-23 23:08:19 UTC (rev 283018)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.h 2021-09-23 23:54:41 UTC (rev 283019)
@@ -82,6 +82,9 @@
RectEdges<bool> edgePinnedState() const final;
bool allowsHorizontalScrolling() const final;
bool allowsVerticalScrolling() const final;
+ void setScrollBehaviorStatus(ScrollBehaviorStatus status) final { m_scrollBehaviorStatus = status; }
+ ScrollBehaviorStatus scrollBehaviorStatus() const final { return m_scrollBehaviorStatus; }
+
bool shouldRubberBandInDirection(ScrollDirection) const final;
void immediateScrollBy(const FloatSize&) final;
void immediateScrollByWithoutContentEdgeConstraints(const FloatSize&) final;
@@ -93,7 +96,6 @@
void scrollControllerAnimationTimerFired();
FloatPoint scrollOffset() const final;
- void immediateScrollOnAxis(ScrollEventAxis, float delta) final;
float pageScaleFactor() const final;
void willStartScrollSnapAnimation() final;
void didStopScrollSnapAnimation() final;
@@ -108,6 +110,7 @@
std::unique_ptr<RunLoop::Timer<ScrollingTreeScrollingNodeDelegateMac>> m_scrollControllerAnimationTimer;
+ ScrollBehaviorStatus m_scrollBehaviorStatus { ScrollBehaviorStatus::NotInAnimation };
bool m_inMomentumPhase { false };
};
Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm (283018 => 283019)
--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm 2021-09-23 23:08:19 UTC (rev 283018)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm 2021-09-23 23:54:41 UTC (rev 283019)
@@ -379,18 +379,6 @@
return ScrollableArea::scrollOffsetFromPosition(currentScrollPosition(), scrollOrigin());
}
-void ScrollingTreeScrollingNodeDelegateMac::immediateScrollOnAxis(ScrollEventAxis axis, float delta)
-{
- const FloatPoint& scrollPosition = currentScrollPosition();
- FloatPoint change;
- if (axis == ScrollEventAxis::Horizontal)
- change = FloatPoint(scrollPosition.x() + delta, scrollPosition.y());
- else
- change = FloatPoint(scrollPosition.x(), scrollPosition.y() + delta);
-
- immediateScrollBy(change - scrollPosition);
-}
-
float ScrollingTreeScrollingNodeDelegateMac::pageScaleFactor() const
{
// FIXME: What should this return for non-root frames, and overflow?
Modified: trunk/Source/WebCore/platform/ScrollAnimation.h (283018 => 283019)
--- trunk/Source/WebCore/platform/ScrollAnimation.h 2021-09-23 23:08:19 UTC (rev 283018)
+++ trunk/Source/WebCore/platform/ScrollAnimation.h 2021-09-23 23:54:41 UTC (rev 283019)
@@ -47,10 +47,19 @@
class ScrollAnimation {
WTF_MAKE_FAST_ALLOCATED;
public:
- ScrollAnimation(ScrollAnimationClient& client)
+ enum class Type {
+ Smooth,
+ Kinetic,
+ Momentum,
+ };
+
+ ScrollAnimation(Type animationType, ScrollAnimationClient& client)
: m_client(client)
+ , m_animationType(animationType)
{ }
virtual ~ScrollAnimation() = default;
+
+ Type type() const { return m_animationType; }
virtual bool retargetActiveAnimation(const FloatPoint& newDestinationOffset) = 0;
virtual void stop() = 0;
@@ -62,6 +71,12 @@
protected:
ScrollAnimationClient& m_client;
+ const Type m_animationType;
};
} // namespace WebCore
+
+#define SPECIALIZE_TYPE_TRAITS_SCROLL_ANIMATION(ToValueTypeName, predicate) \
+SPECIALIZE_TYPE_TRAITS_BEGIN(ToValueTypeName) \
+ static bool isType(const WebCore::ScrollAnimation& scrollAnimation) { return scrollAnimation.predicate; } \
+SPECIALIZE_TYPE_TRAITS_END()
Modified: trunk/Source/WebCore/platform/ScrollAnimationKinetic.cpp (283018 => 283019)
--- trunk/Source/WebCore/platform/ScrollAnimationKinetic.cpp 2021-09-23 23:08:19 UTC (rev 283018)
+++ trunk/Source/WebCore/platform/ScrollAnimationKinetic.cpp 2021-09-23 23:54:41 UTC (rev 283019)
@@ -114,7 +114,7 @@
}
ScrollAnimationKinetic::ScrollAnimationKinetic(ScrollAnimationClient& client)
- : ScrollAnimation(client)
+ : ScrollAnimation(Type::Kinetic, client)
, m_animationTimer(RunLoop::current(), this, &ScrollAnimationKinetic::animationTimerFired)
{
#if USE(GLIB_EVENT_LOOP)
Modified: trunk/Source/WebCore/platform/ScrollAnimationKinetic.h (283018 => 283019)
--- trunk/Source/WebCore/platform/ScrollAnimationKinetic.h 2021-09-23 23:08:19 UTC (rev 283018)
+++ trunk/Source/WebCore/platform/ScrollAnimationKinetic.h 2021-09-23 23:54:41 UTC (rev 283019)
@@ -61,6 +61,7 @@
ScrollAnimationKinetic(ScrollAnimationClient&);
virtual ~ScrollAnimationKinetic();
+ // FIXME: Velocity should be a FloatSize.
bool startAnimatedScrollWithInitialVelocity(const FloatPoint& initialOffset, const FloatPoint& velocity, bool mayHScroll, bool mayVScroll);
bool retargetActiveAnimation(const FloatPoint& newOffset) final;
@@ -86,3 +87,5 @@
};
} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_SCROLL_ANIMATION(WebCore::ScrollAnimationKinetic, type() == WebCore::ScrollAnimation::Type::Kinetic)
Modified: trunk/Source/WebCore/platform/ScrollAnimationMomentum.cpp (283018 => 283019)
--- trunk/Source/WebCore/platform/ScrollAnimationMomentum.cpp 2021-09-23 23:08:19 UTC (rev 283018)
+++ trunk/Source/WebCore/platform/ScrollAnimationMomentum.cpp 2021-09-23 23:54:41 UTC (rev 283019)
@@ -32,7 +32,7 @@
namespace WebCore {
ScrollAnimationMomentum::ScrollAnimationMomentum(ScrollAnimationClient& client)
- : ScrollAnimation(client)
+ : ScrollAnimation(Type::Momentum, client)
{
}
Modified: trunk/Source/WebCore/platform/ScrollAnimationMomentum.h (283018 => 283019)
--- trunk/Source/WebCore/platform/ScrollAnimationMomentum.h 2021-09-23 23:08:19 UTC (rev 283018)
+++ trunk/Source/WebCore/platform/ScrollAnimationMomentum.h 2021-09-23 23:54:41 UTC (rev 283019)
@@ -51,3 +51,5 @@
};
} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_SCROLL_ANIMATION(WebCore::ScrollAnimationMomentum, type() == WebCore::ScrollAnimation::Type::Momentum)
Modified: trunk/Source/WebCore/platform/ScrollAnimationSmooth.cpp (283018 => 283019)
--- trunk/Source/WebCore/platform/ScrollAnimationSmooth.cpp 2021-09-23 23:08:19 UTC (rev 283018)
+++ trunk/Source/WebCore/platform/ScrollAnimationSmooth.cpp 2021-09-23 23:54:41 UTC (rev 283019)
@@ -45,7 +45,7 @@
static const Seconds maxAnimationDuration { 200_ms };
ScrollAnimationSmooth::ScrollAnimationSmooth(ScrollAnimationClient& client)
- : ScrollAnimation(client)
+ : ScrollAnimation(Type::Smooth, client)
, m_animationTimer(RunLoop::current(), this, &ScrollAnimationSmooth::animationTimerFired)
, m_easeInOutTimingFunction(CubicBezierTimingFunction::create(CubicBezierTimingFunction::TimingFunctionPreset::EaseInOut))
{
Modified: trunk/Source/WebCore/platform/ScrollAnimationSmooth.h (283018 => 283019)
--- trunk/Source/WebCore/platform/ScrollAnimationSmooth.h 2021-09-23 23:08:19 UTC (rev 283018)
+++ trunk/Source/WebCore/platform/ScrollAnimationSmooth.h 2021-09-23 23:54:41 UTC (rev 283019)
@@ -73,3 +73,4 @@
} // namespace WebCore
+SPECIALIZE_TYPE_TRAITS_SCROLL_ANIMATION(WebCore::ScrollAnimationSmooth, type() == WebCore::ScrollAnimation::Type::Smooth)
Modified: trunk/Source/WebCore/platform/ScrollAnimator.cpp (283018 => 283019)
--- trunk/Source/WebCore/platform/ScrollAnimator.cpp 2021-09-23 23:08:19 UTC (rev 283018)
+++ trunk/Source/WebCore/platform/ScrollAnimator.cpp 2021-09-23 23:54:41 UTC (rev 283019)
@@ -36,7 +36,6 @@
#include "KeyboardScrollingAnimator.h"
#include "LayoutSize.h"
#include "PlatformWheelEvent.h"
-#include "ScrollAnimationSmooth.h"
#include "ScrollableArea.h"
#include "ScrollbarsController.h"
#include "ScrollingEffectsController.h"
@@ -55,7 +54,6 @@
: m_scrollableArea(scrollableArea)
, m_scrollController(*this)
, m_scrollControllerAnimationTimer(*this, &ScrollAnimator::scrollControllerAnimationTimerFired)
- , m_scrollAnimation(makeUnique<ScrollAnimationSmooth>(*this))
, m_keyboardScrollingAnimator(makeUnique<KeyboardScrollingAnimator>(*this, m_scrollController))
{
}
@@ -93,7 +91,7 @@
auto startOffset = offsetFromPosition(m_currentPosition);
auto extents = scrollExtents();
auto destinationOffset = (startOffset + delta).constrainedBetween(extents.minimumScrollOffset(), extents.maximumScrollOffset());
- return m_scrollAnimation->startAnimatedScrollToDestination(startOffset, destinationOffset);
+ return m_scrollController.startAnimatedScrollToDestination(startOffset, destinationOffset);
}
return scrollToPositionWithoutAnimation(currentPosition() + delta);
@@ -109,7 +107,7 @@
if (adjustedPosition == currentPosition && adjustedPosition == scrollableArea().scrollPosition() && !scrollableArea().scrollOriginChanged())
return false;
- m_scrollAnimation->stop();
+ m_scrollController.stopAnimatedScroll();
setCurrentPosition(adjustedPosition, NotifyScrollableArea::Yes);
return true;
@@ -121,8 +119,8 @@
if (!positionChanged && !scrollableArea().scrollOriginChanged())
return false;
- m_scrollAnimation->startAnimatedScrollToDestination(offsetFromPosition(m_currentPosition), offsetFromPosition(newPosition));
- scrollableArea().setScrollBehaviorStatus(ScrollBehaviorStatus::InNonNativeAnimation);
+ m_scrollController.startAnimatedScrollToDestination(offsetFromPosition(m_currentPosition), offsetFromPosition(newPosition));
+ setScrollBehaviorStatus(ScrollBehaviorStatus::InNonNativeAnimation);
return true;
}
@@ -129,8 +127,7 @@
void ScrollAnimator::retargetRunningAnimation(const FloatPoint& newPosition)
{
ASSERT(scrollableArea().currentScrollBehaviorStatus() == ScrollBehaviorStatus::InNonNativeAnimation);
- ASSERT(m_scrollAnimation->isActive());
- m_scrollAnimation->retargetActiveAnimation(newPosition);
+ m_scrollController.regargetAnimatedScroll(offsetFromPosition(newPosition));
}
FloatPoint ScrollAnimator::offsetFromPosition(const FloatPoint& position) const
@@ -290,6 +287,16 @@
return m_scrollableArea.allowsVerticalScrolling();
}
+void ScrollAnimator::setScrollBehaviorStatus(ScrollBehaviorStatus status)
+{
+ m_scrollableArea.setScrollBehaviorStatus(status);
+}
+
+ScrollBehaviorStatus ScrollAnimator::scrollBehaviorStatus() const
+{
+ return m_scrollableArea.currentScrollBehaviorStatus();
+}
+
#if HAVE(RUBBER_BANDING)
IntSize ScrollAnimator::stretchAmount() const
{
@@ -313,18 +320,43 @@
}
#endif
-// FIXME: Unused.
-void ScrollAnimator::immediateScrollOnAxis(ScrollEventAxis axis, float delta)
+void ScrollAnimator::adjustScrollPositionToBoundsIfNecessary()
{
- FloatSize deltaSize;
- if (axis == ScrollEventAxis::Horizontal)
- deltaSize.setWidth(delta);
- else
- deltaSize.setHeight(delta);
+ bool currentlyConstrainsToContentEdge = m_scrollableArea.constrainsScrollingToContentEdge();
+ m_scrollableArea.setConstrainsScrollingToContentEdge(true);
- scrollToPositionWithoutAnimation(currentPosition() + deltaSize);
+ auto currentScrollPosition = m_scrollableArea.scrollPosition();
+ auto constrainedPosition = m_scrollableArea.constrainScrollPosition(currentScrollPosition);
+ immediateScrollBy(constrainedPosition - currentScrollPosition);
+
+ m_scrollableArea.setConstrainsScrollingToContentEdge(currentlyConstrainsToContentEdge);
}
+FloatPoint ScrollAnimator::adjustScrollPositionIfNecessary(const FloatPoint& position) const
+{
+ if (!m_scrollableArea.constrainsScrollingToContentEdge())
+ return position;
+
+ return m_scrollableArea.constrainScrollPosition(ScrollPosition(position));
+}
+
+void ScrollAnimator::immediateScrollByWithoutContentEdgeConstraints(const FloatSize& delta)
+{
+ m_scrollableArea.setConstrainsScrollingToContentEdge(false);
+ immediateScrollBy(delta);
+ m_scrollableArea.setConstrainsScrollingToContentEdge(true);
+}
+
+void ScrollAnimator::immediateScrollBy(const FloatSize& delta)
+{
+ FloatPoint currentPosition = this->currentPosition();
+ FloatPoint newPosition = adjustScrollPositionIfNecessary(currentPosition + delta);
+ if (newPosition == currentPosition)
+ return;
+
+ setCurrentPosition(newPosition, NotifyScrollableArea::Yes);
+}
+
ScrollExtents ScrollAnimator::scrollExtents() const
{
return {
@@ -385,13 +417,13 @@
void ScrollAnimator::cancelAnimations()
{
- m_scrollAnimation->stop();
+ m_scrollController.stopAnimatedScroll();
m_scrollableArea.scrollbarsController().cancelAnimations();
}
-void ScrollAnimator::contentsSizeChanged() const
+void ScrollAnimator::contentsSizeChanged()
{
- m_scrollAnimation->updateScrollExtents();
+ m_scrollController.contentsSizeChanged();
}
FloatPoint ScrollAnimator::scrollOffsetAdjustedForSnapping(const FloatPoint& offset, ScrollSnapPointSelectionMethod method) const
@@ -423,20 +455,4 @@
return m_scrollController.adjustedScrollDestination(axis, newOffset, velocityInScrollAxis, originalOffset);
}
-void ScrollAnimator::scrollAnimationDidUpdate(ScrollAnimation&, const FloatPoint& currentOffset)
-{
- setCurrentPosition(positionFromOffset(currentOffset), NotifyScrollableArea::Yes);
-}
-
-void ScrollAnimator::scrollAnimationDidEnd(ScrollAnimation&)
-{
- m_scrollableArea.setScrollBehaviorStatus(ScrollBehaviorStatus::NotInAnimation);
-}
-
-ScrollExtents ScrollAnimator::scrollExtentsForAnimation(ScrollAnimation&)
-{
- return scrollExtents();
-}
-
-
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/ScrollAnimator.h (283018 => 283019)
--- trunk/Source/WebCore/platform/ScrollAnimator.h 2021-09-23 23:08:19 UTC (rev 283018)
+++ trunk/Source/WebCore/platform/ScrollAnimator.h 2021-09-23 23:54:41 UTC (rev 283019)
@@ -33,7 +33,6 @@
#include "FloatPoint.h"
#include "PlatformWheelEvent.h"
-#include "ScrollAnimation.h"
#include "ScrollingEffectsController.h"
#include "Timer.h"
#include "WheelEventTestMonitor.h"
@@ -52,7 +51,7 @@
class ScrollingEffectsControllerTimer;
-class ScrollAnimator : private ScrollingEffectsControllerClient, public ScrollAnimationClient {
+class ScrollAnimator : private ScrollingEffectsControllerClient {
WTF_MAKE_FAST_ALLOCATED;
public:
static std::unique_ptr<ScrollAnimator> create(ScrollableArea&);
@@ -78,7 +77,7 @@
virtual bool scrollToPositionWithoutAnimation(const FloatPoint&, ScrollClamping = ScrollClamping::Clamped);
bool scrollToPositionWithAnimation(const FloatPoint&);
- void retargetRunningAnimation(const FloatPoint&);
+ void retargetRunningAnimation(const FloatPoint& newPosition);
virtual bool handleWheelEvent(const PlatformWheelEvent&);
@@ -98,7 +97,7 @@
virtual bool isRubberBandInProgress() const { return false; }
virtual bool isScrollSnapInProgress() const { return false; }
- void contentsSizeChanged() const;
+ void contentsSizeChanged();
enum NotifyScrollableArea : bool {
No, Yes
@@ -122,9 +121,6 @@
protected:
virtual bool platformAllowsScrollAnimation() const { return true; }
- // ScrollAnimationClient
- void scrollAnimationDidUpdate(ScrollAnimation&, const FloatPoint& currentOffset) override;
-
private:
void notifyPositionChanged(const FloatSize& delta);
@@ -134,6 +130,7 @@
FloatPoint offsetFromPosition(const FloatPoint& position) const;
FloatPoint positionFromOffset(const FloatPoint& offset) const;
+ FloatPoint adjustScrollPositionIfNecessary(const FloatPoint&) const;
// ScrollingEffectsControllerClient.
std::unique_ptr<ScrollingEffectsControllerTimer> createTimer(Function<void()>&&) final;
@@ -141,7 +138,6 @@
void stopAnimationCallback(ScrollingEffectsController&) final;
FloatPoint scrollOffset() const final;
- void immediateScrollOnAxis(ScrollEventAxis, float delta) final;
float pageScaleFactor() const final;
ScrollExtents scrollExtents() const final;
@@ -148,6 +144,13 @@
bool allowsHorizontalScrolling() const final;
bool allowsVerticalScrolling() const final;
+ void setScrollBehaviorStatus(ScrollBehaviorStatus) final;
+ ScrollBehaviorStatus scrollBehaviorStatus() const final;
+
+ void immediateScrollByWithoutContentEdgeConstraints(const FloatSize&) final;
+ void immediateScrollBy(const FloatSize&) final;
+ void adjustScrollPositionToBoundsIfNecessary() final;
+
#if HAVE(RUBBER_BANDING)
IntSize stretchAmount() const final;
RectEdges<bool> edgePinnedState() const final;
@@ -159,10 +162,6 @@
void removeWheelEventTestCompletionDeferralForReason(WheelEventTestMonitor::ScrollableAreaIdentifier, WheelEventTestMonitor::DeferReason) const final;
#endif
- // ScrollAnimationClient
- void scrollAnimationDidEnd(ScrollAnimation&) final;
- ScrollExtents scrollExtentsForAnimation(ScrollAnimation&) final;
-
static FloatSize deltaFromStep(ScrollbarOrientation, float step, float multiplier);
protected:
@@ -172,7 +171,6 @@
Timer m_scrollControllerAnimationTimer;
FloatPoint m_currentPosition;
- std::unique_ptr<ScrollAnimationSmooth> m_scrollAnimation;
std::unique_ptr<KeyboardScrollingAnimator> m_keyboardScrollingAnimator;
};
Modified: trunk/Source/WebCore/platform/ScrollingEffectsController.cpp (283018 => 283019)
--- trunk/Source/WebCore/platform/ScrollingEffectsController.cpp 2021-09-23 23:08:19 UTC (rev 283018)
+++ trunk/Source/WebCore/platform/ScrollingEffectsController.cpp 2021-09-23 23:54:41 UTC (rev 283019)
@@ -30,6 +30,8 @@
#include "LayoutSize.h"
#include "Logging.h"
#include "PlatformWheelEvent.h"
+#include "ScrollAnimationKinetic.h"
+#include "ScrollAnimationSmooth.h"
#include "ScrollableArea.h"
#include "WheelEventTestMonitor.h"
#include <wtf/text/TextStream.h>
@@ -76,6 +78,59 @@
setIsAnimatingKeyboardScrolling(false);
}
+bool ScrollingEffectsController::startAnimatedScrollToDestination(FloatPoint startOffset, FloatPoint destinationOffset)
+{
+ if (m_currentAnimation)
+ m_currentAnimation->stop();
+
+ m_currentAnimation = makeUnique<ScrollAnimationSmooth>(*this);
+ return downcast<ScrollAnimationSmooth>(*m_currentAnimation).startAnimatedScrollToDestination(startOffset, destinationOffset);
+}
+
+bool ScrollingEffectsController::regargetAnimatedScroll(FloatPoint newDestinationOffset)
+{
+ if (!is<ScrollAnimationSmooth>(m_currentAnimation.get()))
+ return false;
+
+ ASSERT(m_currentAnimation->isActive());
+ return downcast<ScrollAnimationSmooth>(*m_currentAnimation).retargetActiveAnimation(newDestinationOffset);
+}
+
+void ScrollingEffectsController::stopAnimatedScroll()
+{
+ if (m_currentAnimation)
+ m_currentAnimation->stop();
+}
+
+bool ScrollingEffectsController::processWheelEventForKineticScrolling(const PlatformWheelEvent& event)
+{
+#if ENABLE(KINETIC_SCROLLING)
+ if (m_currentAnimation && !is<ScrollAnimationKinetic>(m_currentAnimation.get())) {
+ m_currentAnimation->stop();
+ m_currentAnimation = nullptr;
+ }
+
+ if (!m_currentAnimation)
+ m_currentAnimation = WTF::makeUnique<ScrollAnimationKinetic>(*this);
+
+ auto& kineticAnimation = downcast<ScrollAnimationKinetic>(*m_currentAnimation);
+ kineticAnimation.appendToScrollHistory(event);
+
+ if (event.isEndOfNonMomentumScroll()) {
+ kineticAnimation.startAnimatedScrollWithInitialVelocity(m_client.scrollOffset(), kineticAnimation.computeVelocity(), 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());
+ return true;
+ }
+#else
+ UNUSED_PARAM(event);
+#endif
+ return false;
+}
+
void ScrollingEffectsController::setIsAnimatingRubberBand(bool isAnimatingRubberBand)
{
if (isAnimatingRubberBand == m_isAnimatingRubberBand)
@@ -103,6 +158,12 @@
startOrStopAnimationCallbacks();
}
+void ScrollingEffectsController::contentsSizeChanged()
+{
+ if (m_currentAnimation)
+ m_currentAnimation->updateScrollExtents();
+}
+
bool ScrollingEffectsController::usesScrollSnap() const
{
return !!m_scrollSnapState;
@@ -136,6 +197,7 @@
{
if (!usesScrollSnap())
return std::nullopt;
+
return m_scrollSnapState->activeSnapIndexForAxis(axis);
}
@@ -184,6 +246,28 @@
m_client.keyboardScrollingAnimator()->updateKeyboardScrollPosition(currentTime);
}
+void ScrollingEffectsController::scrollToOffsetForAnimation(const FloatPoint& scrollOffset)
+{
+ auto currentOffset = m_client.scrollOffset();
+ auto scrollDelta = scrollOffset - currentOffset;
+ m_client.immediateScrollBy(scrollDelta);
+}
+
+void ScrollingEffectsController::scrollAnimationDidUpdate(ScrollAnimation&, const FloatPoint& currentOffset)
+{
+ scrollToOffsetForAnimation(currentOffset);
+}
+
+void ScrollingEffectsController::scrollAnimationDidEnd(ScrollAnimation&)
+{
+ m_client.setScrollBehaviorStatus(ScrollBehaviorStatus::NotInAnimation);
+}
+
+ScrollExtents ScrollingEffectsController::scrollExtentsForAnimation(ScrollAnimation&)
+{
+ return m_client.scrollExtents();
+}
+
// Currently, only Mac supports momentum srolling-based scrollsnapping and rubber banding
// so all of these methods are a noop on non-Mac platforms.
#if !PLATFORM(MAC)
Modified: trunk/Source/WebCore/platform/ScrollingEffectsController.h (283018 => 283019)
--- trunk/Source/WebCore/platform/ScrollingEffectsController.h 2021-09-23 23:08:19 UTC (rev 283018)
+++ trunk/Source/WebCore/platform/ScrollingEffectsController.h 2021-09-23 23:54:41 UTC (rev 283019)
@@ -29,6 +29,7 @@
#include "FloatSize.h"
#include "RectEdges.h"
+#include "ScrollAnimation.h"
#include "ScrollSnapAnimatorState.h"
#include "ScrollSnapOffsetsInfo.h"
#include "ScrollTypes.h"
@@ -80,6 +81,17 @@
virtual bool allowsHorizontalScrolling() const = 0;
virtual bool allowsVerticalScrolling() const = 0;
+ // FIXME: Maybe ScrollBehaviorStatus should be stored on ScrollingEffectsController.
+ virtual void setScrollBehaviorStatus(ScrollBehaviorStatus) = 0;
+ virtual ScrollBehaviorStatus scrollBehaviorStatus() const = 0;
+
+ virtual void immediateScrollBy(const FloatSize&) = 0;
+ virtual void immediateScrollByWithoutContentEdgeConstraints(const FloatSize&) = 0;
+
+ // If the current scroll position is within the overhang area, this function will cause
+ // the page to scroll to the nearest boundary point.
+ virtual void adjustScrollPositionToBoundsIfNecessary() = 0;
+
#if HAVE(RUBBER_BANDING)
virtual bool allowsHorizontalStretching(const PlatformWheelEvent&) const = 0;
virtual bool allowsVerticalStretching(const PlatformWheelEvent&) const = 0;
@@ -92,17 +104,10 @@
virtual bool shouldRubberBandInDirection(ScrollDirection) const = 0;
// FIXME: use ScrollClamping to collapse these to one.
- virtual void immediateScrollBy(const FloatSize&) = 0;
- virtual void immediateScrollByWithoutContentEdgeConstraints(const FloatSize&) = 0;
-
virtual void willStartRubberBandSnapAnimation() { }
virtual void didStopRubberbandSnapAnimation() { }
virtual void rubberBandingStateChanged(bool) { }
-
- // If the current scroll position is within the overhang area, this function will cause
- // the page to scroll to the nearest boundary point.
- virtual void adjustScrollPositionToBoundsIfNecessary() = 0;
#endif
virtual void deferWheelEventTestCompletionForReason(WheelEventTestMonitor::ScrollableAreaIdentifier, WheelEventTestMonitor::DeferReason) const { /* Do nothing */ }
@@ -109,7 +114,6 @@
virtual void removeWheelEventTestCompletionDeferralForReason(WheelEventTestMonitor::ScrollableAreaIdentifier, WheelEventTestMonitor::DeferReason) const { /* Do nothing */ }
virtual FloatPoint scrollOffset() const = 0;
- virtual void immediateScrollOnAxis(ScrollEventAxis, float delta) = 0;
virtual void willStartScrollSnapAnimation() { }
virtual void didStopScrollSnapAnimation() { }
virtual float pageScaleFactor() const = 0;
@@ -116,17 +120,24 @@
virtual ScrollExtents scrollExtents() const = 0;
};
-class ScrollingEffectsController {
+class ScrollingEffectsController : public ScrollAnimationClient {
WTF_MAKE_NONCOPYABLE(ScrollingEffectsController);
public:
explicit ScrollingEffectsController(ScrollingEffectsControllerClient&);
- ~ScrollingEffectsController();
+ virtual ~ScrollingEffectsController();
bool usesScrollSnap() const;
void stopAllTimers();
void scrollPositionChanged();
+ bool startAnimatedScrollToDestination(FloatPoint startOffset, FloatPoint destinationOffset);
+ bool regargetAnimatedScroll(FloatPoint newDestinationOffset);
+ void stopAnimatedScroll();
+
+ // FIXME: Hack for ScrollAnimatorGeneric. Needs cleanup.
+ bool processWheelEventForKineticScrolling(const PlatformWheelEvent&);
+
void beginKeyboardScrolling();
void stopKeyboardScrolling();
@@ -134,6 +145,8 @@
void animationCallback(MonotonicTime);
void updateGestureInProgressState(const PlatformWheelEvent&);
+
+ void contentsSizeChanged();
void setSnapOffsetsInfo(const LayoutScrollSnapOffsetsInfo&);
const LayoutScrollSnapOffsetsInfo* snapOffsetsInfo() const;
@@ -162,12 +175,10 @@
// Returns true if handled.
bool processWheelEventForScrollSnap(const PlatformWheelEvent&);
-#if HAVE(RUBBER_BANDING)
void stopRubberbanding();
bool isRubberBandInProgress() const;
RectEdges<bool> rubberBandingEdges() const { return m_rubberBandingEdges; }
#endif
-#endif
private:
void updateScrollSnapAnimatingState(MonotonicTime);
@@ -188,7 +199,6 @@
void startDeferringWheelEventTestCompletionDueToScrollSnapping();
void stopDeferringWheelEventTestCompletionDueToScrollSnapping();
-#if HAVE(RUBBER_BANDING)
void startRubberbandAnimation();
void stopSnapRubberbandAnimation();
@@ -199,11 +209,19 @@
void updateRubberBandingState();
void updateRubberBandingEdges(IntSize clientStretch);
#endif
-#endif
void startOrStopAnimationCallbacks();
+ void scrollToOffsetForAnimation(const FloatPoint& scrollOffset);
+ // ScrollAnimationClient
+ void scrollAnimationDidUpdate(ScrollAnimation&, const FloatPoint& /* currentOffset */) final;
+ void scrollAnimationDidEnd(ScrollAnimation&) final;
+ ScrollExtents scrollExtentsForAnimation(ScrollAnimation&) final;
+
ScrollingEffectsControllerClient& m_client;
+
+ std::unique_ptr<ScrollAnimation> m_currentAnimation;
+
std::unique_ptr<ScrollSnapAnimatorState> m_scrollSnapState;
bool m_activeScrollSnapIndexDidChange { false };
Modified: trunk/Source/WebCore/platform/generic/ScrollAnimatorGeneric.cpp (283018 => 283019)
--- trunk/Source/WebCore/platform/generic/ScrollAnimatorGeneric.cpp 2021-09-23 23:08:19 UTC (rev 283018)
+++ trunk/Source/WebCore/platform/generic/ScrollAnimatorGeneric.cpp 2021-09-23 23:54:41 UTC (rev 283019)
@@ -31,10 +31,7 @@
#include "config.h"
#include "ScrollAnimatorGeneric.h"
-#include "ScrollAnimationKinetic.h"
-#include "ScrollAnimationSmooth.h"
#include "ScrollableArea.h"
-#include "ScrollbarTheme.h"
namespace WebCore {
@@ -45,50 +42,18 @@
ScrollAnimatorGeneric::ScrollAnimatorGeneric(ScrollableArea& scrollableArea)
: ScrollAnimator(scrollableArea)
- , m_kineticAnimation(makeUnique<ScrollAnimationKinetic>(*this))
{
}
ScrollAnimatorGeneric::~ScrollAnimatorGeneric() = default;
-bool ScrollAnimatorGeneric::scrollToPositionWithoutAnimation(const FloatPoint& position, ScrollClamping clamping)
-{
- m_kineticAnimation->stop();
- return ScrollAnimator::scrollToPositionWithoutAnimation(position, clamping);
-}
-
+// FIXME: Push this into the base class so that ScrollAnimatorGeneric can be removed.
bool ScrollAnimatorGeneric::handleWheelEvent(const PlatformWheelEvent& event)
{
- m_kineticAnimation->stop();
-
-#if ENABLE(KINETIC_SCROLLING)
- m_kineticAnimation->appendToScrollHistory(event);
-
- if (event.isEndOfNonMomentumScroll()) {
- m_kineticAnimation->startAnimatedScrollWithInitialVelocity(m_currentPosition, m_kineticAnimation->computeVelocity(), m_scrollableArea.horizontalScrollbar(), m_scrollableArea.verticalScrollbar());
+ if (m_scrollController.processWheelEventForKineticScrolling(event))
return true;
- }
- if (event.isTransitioningToMomentumScroll()) {
- m_kineticAnimation->clearScrollHistory();
- m_kineticAnimation->startAnimatedScrollWithInitialVelocity(m_currentPosition, event.swipeVelocity(), m_scrollableArea.horizontalScrollbar(), m_scrollableArea.verticalScrollbar());
- return true;
- }
-#endif
return ScrollAnimator::handleWheelEvent(event);
}
-// FIXME: Can we just use the base class implementation?
-void ScrollAnimatorGeneric::scrollAnimationDidUpdate(ScrollAnimation& animation, const FloatPoint& position)
-{
- if (&animation == m_kineticAnimation.get()) {
- // FIXME: Clarify how animations interact. There should never be more than one active at a time.
- m_scrollAnimation->stop();
- setCurrentPosition(position, NotifyScrollableArea::Yes);
- return;
- }
-
- ScrollAnimator::scrollAnimationDidUpdate(animation, position);
-}
-
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/generic/ScrollAnimatorGeneric.h (283018 => 283019)
--- trunk/Source/WebCore/platform/generic/ScrollAnimatorGeneric.h 2021-09-23 23:08:19 UTC (rev 283018)
+++ trunk/Source/WebCore/platform/generic/ScrollAnimatorGeneric.h 2021-09-23 23:54:41 UTC (rev 283019)
@@ -31,12 +31,10 @@
#pragma once
#include "ScrollAnimator.h"
-#include "Timer.h"
namespace WebCore {
class ScrollAnimation;
-class ScrollAnimationKinetic;
class ScrollAnimatorGeneric final : public ScrollAnimator {
public:
@@ -43,14 +41,7 @@
explicit ScrollAnimatorGeneric(ScrollableArea&);
virtual ~ScrollAnimatorGeneric();
-private:
- bool scrollToPositionWithoutAnimation(const FloatPoint&, ScrollClamping) final;
bool handleWheelEvent(const PlatformWheelEvent&) final;
-
- // ScrollAnimationClient
- void scrollAnimationDidUpdate(ScrollAnimation&, const FloatPoint& currentPosition) final;
-
- std::unique_ptr<ScrollAnimationKinetic> m_kineticAnimation;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.h (283018 => 283019)
--- trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.h 2021-09-23 23:08:19 UTC (rev 283018)
+++ trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.h 2021-09-23 23:54:41 UTC (rev 283019)
@@ -50,8 +50,6 @@
void handleWheelEventPhase(PlatformWheelEventPhase) final;
- FloatPoint adjustScrollPositionIfNecessary(const FloatPoint&) const;
-
bool isUserScrollInProgress() const final;
bool isRubberBandInProgress() const final;
bool isScrollSnapInProgress() const final;
@@ -62,9 +60,6 @@
bool allowsHorizontalStretching(const PlatformWheelEvent&) const final;
bool allowsVerticalStretching(const PlatformWheelEvent&) const final;
bool shouldRubberBandInDirection(ScrollDirection) const final;
- void immediateScrollByWithoutContentEdgeConstraints(const FloatSize&) final;
- void immediateScrollBy(const FloatSize&) final;
- void adjustScrollPositionToBoundsIfNecessary() final;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm (283018 => 283019)
--- trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm 2021-09-23 23:08:19 UTC (rev 283018)
+++ trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm 2021-09-23 23:54:41 UTC (rev 283019)
@@ -73,26 +73,6 @@
return enabled;
}
-FloatPoint ScrollAnimatorMac::adjustScrollPositionIfNecessary(const FloatPoint& position) const
-{
- if (!m_scrollableArea.constrainsScrollingToContentEdge())
- return position;
-
- return m_scrollableArea.constrainScrollPosition(ScrollPosition(position));
-}
-
-void ScrollAnimatorMac::adjustScrollPositionToBoundsIfNecessary()
-{
- bool currentlyConstrainsToContentEdge = m_scrollableArea.constrainsScrollingToContentEdge();
- m_scrollableArea.setConstrainsScrollingToContentEdge(true);
-
- ScrollPosition currentScrollPosition = m_scrollableArea.scrollPosition();
- ScrollPosition constrainedPosition = m_scrollableArea.constrainScrollPosition(currentScrollPosition);
- immediateScrollBy(constrainedPosition - currentScrollPosition);
-
- m_scrollableArea.setConstrainsScrollingToContentEdge(currentlyConstrainsToContentEdge);
-}
-
bool ScrollAnimatorMac::isUserScrollInProgress() const
{
return m_scrollController.isUserScrollInProgress();
@@ -220,23 +200,6 @@
return false;
}
-void ScrollAnimatorMac::immediateScrollByWithoutContentEdgeConstraints(const FloatSize& delta)
-{
- m_scrollableArea.setConstrainsScrollingToContentEdge(false);
- immediateScrollBy(delta);
- m_scrollableArea.setConstrainsScrollingToContentEdge(true);
-}
-
-void ScrollAnimatorMac::immediateScrollBy(const FloatSize& delta)
-{
- FloatPoint currentPosition = this->currentPosition();
- FloatPoint newPosition = adjustScrollPositionIfNecessary(currentPosition + delta);
- if (newPosition == currentPosition)
- return;
-
- setCurrentPosition(newPosition, NotifyScrollableArea::Yes);
-}
-
bool ScrollAnimatorMac::processWheelEventForScrollSnap(const PlatformWheelEvent& wheelEvent)
{
return m_scrollController.processWheelEventForScrollSnap(wheelEvent);
Modified: trunk/Source/WebCore/platform/mac/ScrollingEffectsController.mm (283018 => 283019)
--- trunk/Source/WebCore/platform/mac/ScrollingEffectsController.mm 2021-09-23 23:08:19 UTC (rev 283018)
+++ trunk/Source/WebCore/platform/mac/ScrollingEffectsController.mm 2021-09-23 23:54:41 UTC (rev 283019)
@@ -757,11 +757,10 @@
bool isAnimationComplete;
auto animationOffset = m_scrollSnapState->currentAnimatedScrollOffset(currentTime, isAnimationComplete);
- auto currentOffset = m_client.scrollOffset();
+ LOG_WITH_STREAM(ScrollSnap, stream << "ScrollingEffectsController " << this << " updateScrollSnapAnimatingState - isAnimationComplete " << isAnimationComplete << " animationOffset " << animationOffset << " (main thread " << isMainThread() << ")");
- LOG_WITH_STREAM(ScrollSnap, stream << "ScrollingEffectsController " << this << " updateScrollSnapAnimatingState - isAnimationComplete " << isAnimationComplete << " currentOffset " << currentOffset << " (main thread " << isMainThread() << ")");
+ scrollToOffsetForAnimation(animationOffset);
- m_client.immediateScrollByWithoutContentEdgeConstraints(FloatSize(animationOffset.x() - currentOffset.x(), animationOffset.y() - currentOffset.y()));
if (isAnimationComplete) {
m_scrollSnapState->transitionToDestinationReachedState();
stopScrollSnapAnimation();