Title: [280171] trunk/Source
Revision
280171
Author
[email protected]
Date
2021-07-22 02:00:27 -0700 (Thu, 22 Jul 2021)

Log Message

[css-scroll-snap] Pass the full target point when selecting a snap offset
https://bugs.webkit.org/show_bug.cgi?id=228023

Reviewed by Frédéric Wang.

Source/WebCore:

Pass the full proposed destination scroll offset when calling closestSnapOffset. For
now, only the component in the scroll direction is used, but eventually the other
component will be used to avoid snapping to snap areas that are entirely off the screen.

No new tests. This change is simply a refactor in preparation for a behavior
change and shouldn't change behavior itself.

* page/scrolling/ScrollSnapOffsetsInfo.cpp:
(WebCore::closestSnapOffsetWithInfoAndAxis):
(WebCore::LayoutScrollSnapOffsetsInfo::closestSnapOffset const):
(WebCore::FloatScrollSnapOffsetsInfo::closestSnapOffset const):
* page/scrolling/ScrollSnapOffsetsInfo.h:
* page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp:
(WebCore::ScrollingTreeScrollingNodeDelegateNicosia::handleWheelEvent):
* platform/ScrollAnimator.cpp:
(WebCore::ScrollAnimator::scroll):
(WebCore::ScrollAnimator::adjustScrollOffsetForSnappingIfNeeded):
* platform/ScrollAnimator.h:
* platform/ScrollController.cpp:
(WebCore::ScrollController::setNearestScrollSnapIndexForAxisAndOffset):
(WebCore::ScrollController::adjustScrollDestination):
(WebCore::ScrollController::updateActiveScrollSnapIndexForClientOffset):
(WebCore::ScrollController::resnapAfterLayout):
* platform/ScrollController.h:
* platform/ScrollSnapAnimatorState.cpp:
(WebCore::ScrollSnapAnimatorState::setupAnimationForState):
(WebCore::ScrollSnapAnimatorState::targetOffsetForStartOffset const):
* platform/ScrollSnapAnimatorState.h:
* platform/ScrollableArea.cpp:
(WebCore::ScrollableArea::doPostThumbMoveSnapping):

Source/WebKit:

* UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h:
* UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:
(WebKit::RemoteScrollingCoordinatorProxy::adjustTargetContentOffsetForSnapping):
(WebKit::RemoteScrollingCoordinatorProxy::closestSnapOffsetForMainFrameScrolling const):
* UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm:
(-[WKScrollingNodeScrollViewDelegate scrollViewWillEndDragging:withVelocity:targetContentOffset:]):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (280170 => 280171)


--- trunk/Source/WebCore/ChangeLog	2021-07-22 03:19:39 UTC (rev 280170)
+++ trunk/Source/WebCore/ChangeLog	2021-07-22 09:00:27 UTC (rev 280171)
@@ -1,3 +1,41 @@
+2021-07-22  Martin Robinson  <[email protected]>
+
+        [css-scroll-snap] Pass the full target point when selecting a snap offset
+        https://bugs.webkit.org/show_bug.cgi?id=228023
+
+        Reviewed by Frédéric Wang.
+
+        Pass the full proposed destination scroll offset when calling closestSnapOffset. For
+        now, only the component in the scroll direction is used, but eventually the other
+        component will be used to avoid snapping to snap areas that are entirely off the screen.
+
+        No new tests. This change is simply a refactor in preparation for a behavior
+        change and shouldn't change behavior itself.
+
+        * page/scrolling/ScrollSnapOffsetsInfo.cpp:
+        (WebCore::closestSnapOffsetWithInfoAndAxis):
+        (WebCore::LayoutScrollSnapOffsetsInfo::closestSnapOffset const):
+        (WebCore::FloatScrollSnapOffsetsInfo::closestSnapOffset const):
+        * page/scrolling/ScrollSnapOffsetsInfo.h:
+        * page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp:
+        (WebCore::ScrollingTreeScrollingNodeDelegateNicosia::handleWheelEvent):
+        * platform/ScrollAnimator.cpp:
+        (WebCore::ScrollAnimator::scroll):
+        (WebCore::ScrollAnimator::adjustScrollOffsetForSnappingIfNeeded):
+        * platform/ScrollAnimator.h:
+        * platform/ScrollController.cpp:
+        (WebCore::ScrollController::setNearestScrollSnapIndexForAxisAndOffset):
+        (WebCore::ScrollController::adjustScrollDestination):
+        (WebCore::ScrollController::updateActiveScrollSnapIndexForClientOffset):
+        (WebCore::ScrollController::resnapAfterLayout):
+        * platform/ScrollController.h:
+        * platform/ScrollSnapAnimatorState.cpp:
+        (WebCore::ScrollSnapAnimatorState::setupAnimationForState):
+        (WebCore::ScrollSnapAnimatorState::targetOffsetForStartOffset const):
+        * platform/ScrollSnapAnimatorState.h:
+        * platform/ScrollableArea.cpp:
+        (WebCore::ScrollableArea::doPostThumbMoveSnapping):
+
 2021-07-21  Alex Christensen  <[email protected]>
 
         Add linkedOnOrAfter check for r269162

Modified: trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.cpp (280170 => 280171)


--- trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.cpp	2021-07-22 03:19:39 UTC (rev 280170)
+++ trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.cpp	2021-07-22 09:00:27 UTC (rev 280171)
@@ -90,9 +90,10 @@
     return { previous, next, snapStop, landedInsideSnapAreaThatConsumesViewport };
 }
 
-template <typename InfoType, typename SizeType, typename LayoutType>
-static std::pair<LayoutType, std::optional<unsigned>> closestSnapOffsetWithInfoAndAxis(const InfoType& info, ScrollEventAxis axis, const SizeType& viewportSize, LayoutType scrollDestinationOffset, float velocity, std::optional<LayoutType> originalOffsetForDirectionalSnapping)
+template <typename InfoType, typename SizeType, typename LayoutType, typename PointType>
+static std::pair<LayoutType, std::optional<unsigned>> closestSnapOffsetWithInfoAndAxis(const InfoType& info, ScrollEventAxis axis, const SizeType& viewportSize, PointType scrollDestinationOffsetPoint, float velocity, std::optional<LayoutType> originalOffsetForDirectionalSnapping)
 {
+    auto scrollDestinationOffset = axis == ScrollEventAxis::Horizontal ? scrollDestinationOffsetPoint.x() : scrollDestinationOffsetPoint.y();
     const auto& snapOffsets = info.offsetsForAxis(axis);
     auto pairForNoSnapping = std::make_pair(scrollDestinationOffset, std::nullopt);
     if (snapOffsets.isEmpty())
@@ -388,13 +389,13 @@
 }
 
 template <> template <>
-std::pair<LayoutUnit, std::optional<unsigned>> LayoutScrollSnapOffsetsInfo::closestSnapOffset(ScrollEventAxis axis, const LayoutSize& viewportSize, LayoutUnit scrollDestinationOffset, float velocity, std::optional<LayoutUnit> originalPositionForDirectionalSnapping) const
+std::pair<LayoutUnit, std::optional<unsigned>> LayoutScrollSnapOffsetsInfo::closestSnapOffset(ScrollEventAxis axis, const LayoutSize& viewportSize, LayoutPoint scrollDestinationOffset, float velocity, std::optional<LayoutUnit> originalPositionForDirectionalSnapping) const
 {
     return closestSnapOffsetWithInfoAndAxis(*this, axis, viewportSize, scrollDestinationOffset, velocity, originalPositionForDirectionalSnapping);
 }
 
 template <> template<>
-std::pair<float, std::optional<unsigned>> FloatScrollSnapOffsetsInfo::closestSnapOffset(ScrollEventAxis axis, const FloatSize& viewportSize, float scrollDestinationOffset, float velocity, std::optional<float> originalPositionForDirectionalSnapping) const
+std::pair<float, std::optional<unsigned>> FloatScrollSnapOffsetsInfo::closestSnapOffset(ScrollEventAxis axis, const FloatSize& viewportSize, FloatPoint scrollDestinationOffset, float velocity, std::optional<float> originalPositionForDirectionalSnapping) const
 {
     return closestSnapOffsetWithInfoAndAxis(*this, axis, viewportSize, scrollDestinationOffset, velocity, originalPositionForDirectionalSnapping);
 }

Modified: trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.h (280170 => 280171)


--- trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.h	2021-07-22 03:19:39 UTC (rev 280170)
+++ trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.h	2021-07-22 09:00:27 UTC (rev 280171)
@@ -70,8 +70,8 @@
     }
 
     template<typename OutputType> OutputType convertUnits(float deviceScaleFactor = 0.0) const;
-    template<typename SizeType>
-    WEBCORE_EXPORT std::pair<UnitType, std::optional<unsigned>> closestSnapOffset(ScrollEventAxis, const SizeType& viewportSize, UnitType scrollDestinationOffset, float velocity, std::optional<UnitType> originalPositionForDirectionalSnapping = std::nullopt) const;
+    template<typename SizeType, typename PointType>
+    WEBCORE_EXPORT std::pair<UnitType, std::optional<unsigned>> closestSnapOffset(ScrollEventAxis, const SizeType& viewportSize, PointType scrollDestinationOffset, float velocity, std::optional<UnitType> originalPositionForDirectionalSnapping = std::nullopt) const;
 };
 
 using LayoutScrollSnapOffsetsInfo = ScrollSnapOffsetsInfo<LayoutUnit, LayoutRect>;
@@ -80,13 +80,13 @@
 template <> template <>
 LayoutScrollSnapOffsetsInfo FloatScrollSnapOffsetsInfo::convertUnits(float /* unusedScaleFactor */) const;
 template <> template <>
-WEBCORE_EXPORT std::pair<float, std::optional<unsigned>> FloatScrollSnapOffsetsInfo::closestSnapOffset(ScrollEventAxis, const FloatSize& viewportSize, float scrollDestinationOffset, float velocity, std::optional<float> originalPositionForDirectionalSnapping) const;
+WEBCORE_EXPORT std::pair<float, std::optional<unsigned>> FloatScrollSnapOffsetsInfo::closestSnapOffset(ScrollEventAxis, const FloatSize& viewportSize, FloatPoint scrollDestinationOffset, float velocity, std::optional<float> originalPositionForDirectionalSnapping) const;
 
 
 template <> template <>
 FloatScrollSnapOffsetsInfo LayoutScrollSnapOffsetsInfo::convertUnits(float deviceScaleFactor) const;
 template <> template <>
-WEBCORE_EXPORT std::pair<LayoutUnit, std::optional<unsigned>> LayoutScrollSnapOffsetsInfo::closestSnapOffset(ScrollEventAxis, const LayoutSize& viewportSize, LayoutUnit scrollDestinationOffset, float velocity, std::optional<LayoutUnit> originalPositionForDirectionalSnapping) const;
+WEBCORE_EXPORT std::pair<LayoutUnit, std::optional<unsigned>> LayoutScrollSnapOffsetsInfo::closestSnapOffset(ScrollEventAxis, const LayoutSize& viewportSize, LayoutPoint scrollDestinationOffset, float velocity, std::optional<LayoutUnit> originalPositionForDirectionalSnapping) const;
 
 // Update the snap offsets for this scrollable area, given the RenderBox of the scroll container, the RenderStyle
 // which defines the scroll-snap properties, and the viewport rectangle with the origin at the top left of

Modified: trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp (280170 => 280171)


--- trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp	2021-07-22 03:19:39 UTC (rev 280170)
+++ trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp	2021-07-22 09:00:27 UTC (rev 280171)
@@ -169,11 +169,11 @@
     if (!scrollingNode().snapOffsetsInfo().isEmpty()) {
         float scale = pageScaleFactor();
         FloatPoint originalOffset = LayoutPoint(scrollingNode().currentScrollOffset().x() / scale, scrollingNode().currentScrollOffset().y() / scale);
-        FloatPoint newFloatOffset = scrollingNode().currentScrollOffset() + FloatSize(deltaX, deltaY);
-        auto newOffset = LayoutPoint(newFloatOffset.x() / scale, newFloatOffset.y() / scale);
+        auto newOffset = (scrollingNode().currentScrollOffset() + FloatSize(deltaX, deltaY));
+        newOffset.scale(1.0 / scale);
 
-        auto offsetX = scrollingNode().snapOffsetsInfo().closestSnapOffset(ScrollEventAxis::Horizontal, scrollableAreaSize(), newOffset.x(), deltaX, originalOffset.x()).first;
-        auto offsetY = scrollingNode().snapOffsetsInfo().closestSnapOffset(ScrollEventAxis::Vertical, scrollableAreaSize(), newOffset.y(), deltaY, originalOffset.y()).first;
+        auto offsetX = scrollingNode().snapOffsetsInfo().closestSnapOffset(ScrollEventAxis::Horizontal, scrollableAreaSize(), newOffset, deltaX, originalOffset.x()).first;
+        auto offsetY = scrollingNode().snapOffsetsInfo().closestSnapOffset(ScrollEventAxis::Vertical, scrollableAreaSize(), newOffset, deltaY, originalOffset.y()).first;
 
         deltaX = (offsetX - originalOffset.x()) * scale;
         deltaY = (offsetY - originalOffset.y()) * scale;

Modified: trunk/Source/WebCore/platform/ScrollAnimator.cpp (280170 => 280171)


--- trunk/Source/WebCore/platform/ScrollAnimator.cpp	2021-07-22 03:19:39 UTC (rev 280170)
+++ trunk/Source/WebCore/platform/ScrollAnimator.cpp	2021-07-22 09:00:27 UTC (rev 280171)
@@ -86,9 +86,9 @@
         auto currentOffset = offsetFromPosition(currentPosition());
         auto newOffset = currentOffset + delta;
         if (orientation == HorizontalScrollbar)
-            newOffset.setX(m_scrollController.adjustScrollDestination(ScrollEventAxis::Horizontal, newOffset.x(), multiplier, currentOffset.x()));
+            newOffset.setX(m_scrollController.adjustScrollDestination(ScrollEventAxis::Horizontal, newOffset, multiplier, currentOffset.x()));
         else
-            newOffset.setY(m_scrollController.adjustScrollDestination(ScrollEventAxis::Vertical, newOffset.y(), multiplier, currentOffset.y()));
+            newOffset.setY(m_scrollController.adjustScrollDestination(ScrollEventAxis::Vertical, newOffset, multiplier, currentOffset.y()));
         auto newDelta = newOffset - currentOffset;
 
         if (orientation == HorizontalScrollbar)
@@ -397,26 +397,27 @@
         return offset;
 
     FloatPoint newOffset = offset;
-    newOffset.setX(adjustScrollOffsetForSnappingIfNeeded(ScrollEventAxis::Horizontal, newOffset.x(), method));
-    newOffset.setY(adjustScrollOffsetForSnappingIfNeeded(ScrollEventAxis::Vertical, newOffset.y(), method));
+    newOffset.setX(adjustScrollOffsetForSnappingIfNeeded(ScrollEventAxis::Horizontal, newOffset, method));
+    newOffset.setY(adjustScrollOffsetForSnappingIfNeeded(ScrollEventAxis::Vertical, newOffset, method));
     return newOffset;
 }
 
-float ScrollAnimator::adjustScrollOffsetForSnappingIfNeeded(ScrollEventAxis axis, float newOffset, ScrollSnapPointSelectionMethod method)
+float ScrollAnimator::adjustScrollOffsetForSnappingIfNeeded(ScrollEventAxis axis, const FloatPoint& newOffset, ScrollSnapPointSelectionMethod method)
 {
     if (!m_scrollController.usesScrollSnap())
-        return newOffset;
+        return axis == ScrollEventAxis::Horizontal ? newOffset.x() : newOffset.y();
 
     std::optional<float> originalOffset;
-    float velocity = 0.;
+    float velocityInScrollAxis = 0.;
     if (method == ScrollSnapPointSelectionMethod::Directional) {
         FloatSize scrollOrigin = toFloatSize(m_scrollableArea.scrollOrigin());
         auto currentOffset = ScrollableArea::scrollOffsetFromPosition(this->currentPosition(), scrollOrigin);
+        auto velocity = newOffset - currentOffset;
         originalOffset = axis == ScrollEventAxis::Horizontal ? currentOffset.x() : currentOffset.y();
-        velocity = newOffset - (axis == ScrollEventAxis::Horizontal ? currentOffset.x() : currentOffset.y());
+        velocityInScrollAxis = axis == ScrollEventAxis::Horizontal ? velocity.width() : velocity.height();
     }
 
-    return m_scrollController.adjustScrollDestination(axis, newOffset, velocity, originalOffset);
+    return m_scrollController.adjustScrollDestination(axis, newOffset, velocityInScrollAxis, originalOffset);
 }
 
 

Modified: trunk/Source/WebCore/platform/ScrollAnimator.h (280170 => 280171)


--- trunk/Source/WebCore/platform/ScrollAnimator.h	2021-07-22 03:19:39 UTC (rev 280170)
+++ trunk/Source/WebCore/platform/ScrollAnimator.h	2021-07-22 09:00:27 UTC (rev 280171)
@@ -134,7 +134,7 @@
     void setWheelEventTestMonitor(RefPtr<WheelEventTestMonitor>&& testMonitor) { m_wheelEventTestMonitor = testMonitor; }
 
     FloatPoint adjustScrollOffsetForSnappingIfNeeded(const FloatPoint& offset, ScrollSnapPointSelectionMethod);
-    float adjustScrollOffsetForSnappingIfNeeded(ScrollEventAxis, float newOffset, ScrollSnapPointSelectionMethod);
+    float adjustScrollOffsetForSnappingIfNeeded(ScrollEventAxis, const FloatPoint& newOffset, ScrollSnapPointSelectionMethod);
 
     std::unique_ptr<ScrollControllerTimer> createTimer(Function<void()>&&) final;
 

Modified: trunk/Source/WebCore/platform/ScrollController.cpp (280170 => 280171)


--- trunk/Source/WebCore/platform/ScrollController.cpp	2021-07-22 03:19:39 UTC (rev 280170)
+++ trunk/Source/WebCore/platform/ScrollController.cpp	2021-07-22 09:00:27 UTC (rev 280171)
@@ -127,12 +127,13 @@
     m_scrollSnapState->setActiveSnapIndexForAxis(axis, index);
 }
 
-void ScrollController::setNearestScrollSnapIndexForAxisAndOffset(ScrollEventAxis axis, int offset)
+void ScrollController::setNearestScrollSnapIndexForAxisAndOffset(ScrollEventAxis axis, ScrollOffset scrollOffset)
 {
     if (!usesScrollSnap())
         return;
 
     float scaleFactor = m_client.pageScaleFactor();
+    LayoutPoint layoutScrollOffset(scrollOffset.x() / scaleFactor, scrollOffset.y() / scaleFactor);
     ScrollSnapAnimatorState& snapState = *m_scrollSnapState;
 
     auto snapOffsets = snapState.snapOffsetsForAxis(axis);
@@ -139,7 +140,7 @@
     LayoutSize viewportSize(m_client.viewportSize().width(), m_client.viewportSize().height());
     std::optional<unsigned> activeIndex;
     if (snapOffsets.size())
-        activeIndex = snapState.snapOffsetInfo().closestSnapOffset(axis, viewportSize, LayoutUnit(offset / scaleFactor), 0).second;
+        activeIndex = snapState.snapOffsetInfo().closestSnapOffset(axis, viewportSize, layoutScrollOffset, 0).second;
 
     if (activeIndex == activeScrollSnapIndexForAxis(axis))
         return;
@@ -148,22 +149,24 @@
     setActiveScrollSnapIndexForAxis(axis, activeIndex);
 }
 
-float ScrollController::adjustScrollDestination(ScrollEventAxis axis, float destinationOffset, float velocity, std::optional<float> originalOffset)
+float ScrollController::adjustScrollDestination(ScrollEventAxis axis, FloatPoint destinationOffset, float velocity, std::optional<float> originalOffset)
 {
     if (!usesScrollSnap())
-        return destinationOffset;
+        return axis == ScrollEventAxis::Horizontal ? destinationOffset.x() : destinationOffset.y();
 
     ScrollSnapAnimatorState& snapState = *m_scrollSnapState;
     auto snapOffsets = snapState.snapOffsetsForAxis(axis);
     if (!snapOffsets.size())
-        return destinationOffset;
+        return axis == ScrollEventAxis::Horizontal ? destinationOffset.x() : destinationOffset.y();
 
+    float scaleFactor = m_client.pageScaleFactor();
     std::optional<LayoutUnit> originalOffsetInLayoutUnits;
     if (originalOffset)
-        originalOffsetInLayoutUnits = LayoutUnit(*originalOffset / m_client.pageScaleFactor());
+        originalOffsetInLayoutUnits = LayoutUnit(*originalOffset / scaleFactor);
     LayoutSize viewportSize(m_client.viewportSize().width(), m_client.viewportSize().height());
-    LayoutUnit offset = snapState.snapOffsetInfo().closestSnapOffset(axis, viewportSize, LayoutUnit(destinationOffset / m_client.pageScaleFactor()), velocity, originalOffsetInLayoutUnits).first;
-    return offset * m_client.pageScaleFactor();
+    LayoutPoint layoutDestinationOffset(destinationOffset.x() / scaleFactor, destinationOffset.y() / scaleFactor);
+    LayoutUnit offset = snapState.snapOffsetInfo().closestSnapOffset(axis, viewportSize, layoutDestinationOffset, velocity, originalOffsetInLayoutUnits).first;
+    return offset * scaleFactor;
 }
 
 
@@ -173,8 +176,8 @@
         return;
 
     ScrollOffset offset = roundedIntPoint(m_client.scrollOffset());
-    setNearestScrollSnapIndexForAxisAndOffset(ScrollEventAxis::Horizontal, offset.x());
-    setNearestScrollSnapIndexForAxisAndOffset(ScrollEventAxis::Vertical, offset.y());
+    setNearestScrollSnapIndexForAxisAndOffset(ScrollEventAxis::Horizontal, offset);
+    setNearestScrollSnapIndexForAxisAndOffset(ScrollEventAxis::Vertical, offset);
 }
 
 void ScrollController::resnapAfterLayout()
@@ -188,11 +191,11 @@
 
     auto activeHorizontalIndex = m_scrollSnapState->activeSnapIndexForAxis(ScrollEventAxis::Horizontal);
     if (!activeHorizontalIndex || *activeHorizontalIndex >= snapState.snapOffsetsForAxis(ScrollEventAxis::Horizontal).size())
-        setNearestScrollSnapIndexForAxisAndOffset(ScrollEventAxis::Horizontal, offset.x());
+        setNearestScrollSnapIndexForAxisAndOffset(ScrollEventAxis::Horizontal, offset);
 
     auto activeVerticalIndex = m_scrollSnapState->activeSnapIndexForAxis(ScrollEventAxis::Vertical);
     if (!activeVerticalIndex || *activeVerticalIndex >= snapState.snapOffsetsForAxis(ScrollEventAxis::Vertical).size())
-        setNearestScrollSnapIndexForAxisAndOffset(ScrollEventAxis::Vertical, offset.y());
+        setNearestScrollSnapIndexForAxisAndOffset(ScrollEventAxis::Vertical, offset);
 
 }
 // Currently, only Mac supports momentum srolling-based scrollsnapping and rubber banding

Modified: trunk/Source/WebCore/platform/ScrollController.h (280170 => 280171)


--- trunk/Source/WebCore/platform/ScrollController.h	2021-07-22 03:19:39 UTC (rev 280170)
+++ trunk/Source/WebCore/platform/ScrollController.h	2021-07-22 09:00:27 UTC (rev 280171)
@@ -135,7 +135,7 @@
     std::optional<unsigned> activeScrollSnapIndexForAxis(ScrollEventAxis) const;
     void updateScrollSnapState(const ScrollableArea&);
     void updateGestureInProgressState(const PlatformWheelEvent&);
-    float adjustScrollDestination(ScrollEventAxis, float destinationOffset, float velocity, std::optional<float> originalOffset);
+    float adjustScrollDestination(ScrollEventAxis, FloatPoint destinationOffset, float velocity, std::optional<float> originalOffset);
 
 #if PLATFORM(MAC)
     // Returns true if handled.
@@ -159,7 +159,7 @@
 #endif
 
 private:
-    void setNearestScrollSnapIndexForAxisAndOffset(ScrollEventAxis, int);
+    void setNearestScrollSnapIndexForAxisAndOffset(ScrollEventAxis, ScrollOffset);
 
     void updateScrollSnapAnimatingState(MonotonicTime);
     void updateRubberBandAnimatingState(MonotonicTime);

Modified: trunk/Source/WebCore/platform/ScrollSnapAnimatorState.cpp (280170 => 280171)


--- trunk/Source/WebCore/platform/ScrollSnapAnimatorState.cpp	2021-07-22 03:19:39 UTC (rev 280170)
+++ trunk/Source/WebCore/platform/ScrollSnapAnimatorState.cpp	2021-07-22 09:00:27 UTC (rev 280171)
@@ -48,11 +48,11 @@
         return;
 
     m_momentumCalculator = ScrollingMomentumCalculator::create(viewportSize, contentSize, initialOffset, initialDelta, initialVelocity);
-    auto predictedScrollTarget = m_momentumCalculator->predictedDestinationOffset();
+    FloatPoint predictedScrollTarget { m_momentumCalculator->predictedDestinationOffset() };
 
     float targetOffsetX, targetOffsetY;
-    std::tie(targetOffsetX, m_activeSnapIndexX) = targetOffsetForStartOffset(ScrollEventAxis::Horizontal, viewportSize, contentSize.width() - viewportSize.width(), initialOffset.x(), predictedScrollTarget.width(), pageScale, initialDelta.width());
-    std::tie(targetOffsetY, m_activeSnapIndexY) = targetOffsetForStartOffset(ScrollEventAxis::Vertical, viewportSize, contentSize.height() - viewportSize.height(), initialOffset.y(), predictedScrollTarget.height(), pageScale, initialDelta.height());
+    std::tie(targetOffsetX, m_activeSnapIndexX) = targetOffsetForStartOffset(ScrollEventAxis::Horizontal, viewportSize, contentSize.width() - viewportSize.width(), initialOffset.x(), predictedScrollTarget, pageScale, initialDelta.width());
+    std::tie(targetOffsetY, m_activeSnapIndexY) = targetOffsetForStartOffset(ScrollEventAxis::Vertical, viewportSize, contentSize.height() - viewportSize.height(), initialOffset.y(), predictedScrollTarget, pageScale, initialDelta.height());
     m_momentumCalculator->setRetargetedScrollOffset({ targetOffsetX, targetOffsetY });
     m_startTime = MonotonicTime::now();
     m_currentState = state;
@@ -91,13 +91,14 @@
     return m_momentumCalculator->scrollOffsetAfterElapsedTime(elapsedTime);
 }
 
-std::pair<float, std::optional<unsigned>> ScrollSnapAnimatorState::targetOffsetForStartOffset(ScrollEventAxis axis, const FloatSize& viewportSize, float maxScrollOffset, float startOffset, float predictedOffset, float pageScale, float initialDelta) const
+std::pair<float, std::optional<unsigned>> ScrollSnapAnimatorState::targetOffsetForStartOffset(ScrollEventAxis axis, const FloatSize& viewportSize, float maxScrollOffset, float startOffset, FloatPoint predictedOffset, float pageScale, float initialDelta) const
 {
     const auto& snapOffsets = m_snapOffsetsInfo.offsetsForAxis(axis);
     if (snapOffsets.isEmpty())
-        return std::make_pair(clampTo<float>(predictedOffset, 0, maxScrollOffset), std::nullopt);
+        return std::make_pair(clampTo<float>(axis == ScrollEventAxis::Horizontal ? predictedOffset.x() : predictedOffset.y(), 0, maxScrollOffset), std::nullopt);
 
-    auto [targetOffset, snapIndex] = m_snapOffsetsInfo.closestSnapOffset(axis, LayoutSize { viewportSize }, LayoutUnit(predictedOffset / pageScale), initialDelta, LayoutUnit(startOffset / pageScale));
+    LayoutPoint predictedLayoutOffset(predictedOffset.x() / pageScale, predictedOffset.y() / pageScale);
+    auto [targetOffset, snapIndex] = m_snapOffsetsInfo.closestSnapOffset(axis, LayoutSize { viewportSize }, predictedLayoutOffset, initialDelta, LayoutUnit(startOffset / pageScale));
     return std::make_pair(pageScale * clampTo<float>(float { targetOffset }, 0, maxScrollOffset), snapIndex);
 }
 

Modified: trunk/Source/WebCore/platform/ScrollSnapAnimatorState.h (280170 => 280171)


--- trunk/Source/WebCore/platform/ScrollSnapAnimatorState.h	2021-07-22 03:19:39 UTC (rev 280170)
+++ trunk/Source/WebCore/platform/ScrollSnapAnimatorState.h	2021-07-22 09:00:27 UTC (rev 280171)
@@ -82,7 +82,7 @@
     void transitionToDestinationReachedState();
 
 private:
-    std::pair<float, std::optional<unsigned>> targetOffsetForStartOffset(ScrollEventAxis, const FloatSize& viewportSize, float maxScrollOffset, float startOffset, float predictedOffset, float pageScale, float initialDelta) const;
+    std::pair<float, std::optional<unsigned>> targetOffsetForStartOffset(ScrollEventAxis, const FloatSize& viewportSize, float maxScrollOffset, float startOffset, FloatPoint predictedOffset, float pageScale, float initialDelta) const;
     void teardownAnimationForState(ScrollSnapState);
     void setupAnimationForState(ScrollSnapState, const FloatSize& contentSize, const FloatSize& viewportSize, float pageScale, const FloatPoint& initialOffset, const FloatSize& initialVelocity, const FloatSize& initialDelta);
 

Modified: trunk/Source/WebCore/platform/ScrollableArea.cpp (280170 => 280171)


--- trunk/Source/WebCore/platform/ScrollableArea.cpp	2021-07-22 03:19:39 UTC (rev 280170)
+++ trunk/Source/WebCore/platform/ScrollableArea.cpp	2021-07-22 09:00:27 UTC (rev 280171)
@@ -563,9 +563,9 @@
     auto currentOffset = scrollOffset();
     auto newOffset = currentOffset;
     if (orientation == HorizontalScrollbar)
-        newOffset.setX(scrollAnimator->adjustScrollOffsetForSnappingIfNeeded(ScrollEventAxis::Horizontal, currentOffset.x(), ScrollSnapPointSelectionMethod::Closest));
+        newOffset.setX(scrollAnimator->adjustScrollOffsetForSnappingIfNeeded(ScrollEventAxis::Horizontal, currentOffset, ScrollSnapPointSelectionMethod::Closest));
     else
-        newOffset.setY(scrollAnimator->adjustScrollOffsetForSnappingIfNeeded(ScrollEventAxis::Vertical, currentOffset.y(), ScrollSnapPointSelectionMethod::Closest));
+        newOffset.setY(scrollAnimator->adjustScrollOffsetForSnappingIfNeeded(ScrollEventAxis::Vertical, currentOffset, ScrollSnapPointSelectionMethod::Closest));
     if (newOffset == currentOffset)
         return;
 

Modified: trunk/Source/WebKit/ChangeLog (280170 => 280171)


--- trunk/Source/WebKit/ChangeLog	2021-07-22 03:19:39 UTC (rev 280170)
+++ trunk/Source/WebKit/ChangeLog	2021-07-22 09:00:27 UTC (rev 280171)
@@ -1,3 +1,17 @@
+2021-07-22  Martin Robinson  <[email protected]>
+
+        [css-scroll-snap] Pass the full target point when selecting a snap offset
+        https://bugs.webkit.org/show_bug.cgi?id=228023
+
+        Reviewed by Frédéric Wang.
+
+        * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h:
+        * UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:
+        (WebKit::RemoteScrollingCoordinatorProxy::adjustTargetContentOffsetForSnapping):
+        (WebKit::RemoteScrollingCoordinatorProxy::closestSnapOffsetForMainFrameScrolling const):
+        * UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm:
+        (-[WKScrollingNodeScrollViewDelegate scrollViewWillEndDragging:withVelocity:targetContentOffset:]):
+
 2021-07-21  Chris Dumez  <[email protected]>
 
         RunningBoard kills the network process if it is still holding the "holding locked file" assertion upon suspension

Modified: trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h (280170 => 280171)


--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h	2021-07-22 03:19:39 UTC (rev 280170)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h	2021-07-22 09:00:27 UTC (rev 280171)
@@ -118,7 +118,7 @@
     void establishLayerTreeScrollingRelations(const RemoteLayerTreeHost&);
 
     bool shouldSnapForMainFrameScrolling(WebCore::ScrollEventAxis) const;
-    std::pair<float, std::optional<unsigned>> closestSnapOffsetForMainFrameScrolling(WebCore::ScrollEventAxis, float currentScrollOffset, float scrollDestination, float velocity) const;
+    std::pair<float, std::optional<unsigned>> closestSnapOffsetForMainFrameScrolling(WebCore::ScrollEventAxis, float currentScrollOffset, WebCore::FloatPoint scrollDestination, float velocity) const;
 
     void sendUIStateChangedIfNecessary();
 

Modified: trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm (280170 => 280171)


--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm	2021-07-22 03:19:39 UTC (rev 280170)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm	2021-07-22 09:00:27 UTC (rev 280171)
@@ -197,7 +197,7 @@
     // The bounds checking with maxScrollOffsets is to ensure that we won't interfere with rubber-banding when scrolling to the edge of the page.
     if (shouldSnapForMainFrameScrolling(WebCore::ScrollEventAxis::Horizontal)) {
         float potentialSnapPosition;
-        std::tie(potentialSnapPosition, m_currentHorizontalSnapPointIndex) = closestSnapOffsetForMainFrameScrolling(WebCore::ScrollEventAxis::Horizontal, currentContentOffset.x, targetContentOffset->x, velocity.x);
+        std::tie(potentialSnapPosition, m_currentHorizontalSnapPointIndex) = closestSnapOffsetForMainFrameScrolling(WebCore::ScrollEventAxis::Horizontal, currentContentOffset.x, FloatPoint(*targetContentOffset), velocity.x);
         if (targetContentOffset->x > 0 && targetContentOffset->x < maxScrollOffsets.width)
             targetContentOffset->x = std::min<float>(maxScrollOffsets.width, potentialSnapPosition);
     }
@@ -204,7 +204,7 @@
 
     if (shouldSnapForMainFrameScrolling(WebCore::ScrollEventAxis::Vertical)) {
         float potentialSnapPosition;
-        std::tie(potentialSnapPosition, m_currentVerticalSnapPointIndex) = closestSnapOffsetForMainFrameScrolling(WebCore::ScrollEventAxis::Vertical, currentContentOffset.y + topInset, targetContentOffset->y, velocity.y);
+        std::tie(potentialSnapPosition, m_currentVerticalSnapPointIndex) = closestSnapOffsetForMainFrameScrolling(WebCore::ScrollEventAxis::Vertical, currentContentOffset.y + topInset, FloatPoint(*targetContentOffset), velocity.y);
         if (m_currentVerticalSnapPointIndex)
             potentialSnapPosition -= topInset;
 
@@ -228,7 +228,7 @@
     return false;
 }
 
-std::pair<float, std::optional<unsigned>> RemoteScrollingCoordinatorProxy::closestSnapOffsetForMainFrameScrolling(ScrollEventAxis axis, float currentScrollOffset, float scrollDestination, float velocity) const
+std::pair<float, std::optional<unsigned>> RemoteScrollingCoordinatorProxy::closestSnapOffsetForMainFrameScrolling(ScrollEventAxis axis, float currentScrollOffset, FloatPoint scrollDestination, float velocity) const
 {
     ScrollingTreeNode* root = m_scrollingTree->rootNode();
     ASSERT(root && root->isFrameScrollingNode());
@@ -235,9 +235,9 @@
     ScrollingTreeFrameScrollingNode* rootScrollingNode = static_cast<ScrollingTreeFrameScrollingNode*>(root);
     const auto& snapOffsetsInfo = rootScrollingNode->snapOffsetsInfo();
 
-    float scaledScrollDestination = scrollDestination / m_webPageProxy.displayedContentScale();
+    scrollDestination.scale(1.0 / m_webPageProxy.displayedContentScale());
     float scaledCurrentScrollOffset = currentScrollOffset / m_webPageProxy.displayedContentScale();
-    auto [rawClosestSnapOffset, newIndex] = snapOffsetsInfo.closestSnapOffset(axis, rootScrollingNode->layoutViewport().size(), scaledScrollDestination, velocity, scaledCurrentScrollOffset);
+    auto [rawClosestSnapOffset, newIndex] = snapOffsetsInfo.closestSnapOffset(axis, rootScrollingNode->layoutViewport().size(), scrollDestination, velocity, scaledCurrentScrollOffset);
     return std::make_pair(rawClosestSnapOffset * m_webPageProxy.displayedContentScale(), newIndex);
 }
 

Modified: trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm (280170 => 280171)


--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm	2021-07-22 03:19:39 UTC (rev 280170)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm	2021-07-22 09:00:27 UTC (rev 280171)
@@ -96,9 +96,6 @@
         }
     }
 
-    CGFloat horizontalTarget = targetContentOffset->x;
-    CGFloat verticalTarget = targetContentOffset->y;
-
     std::optional<unsigned> originalHorizontalSnapPosition = _scrollingTreeNodeDelegate->scrollingNode().currentHorizontalSnapPointIndex();
     std::optional<unsigned> originalVerticalSnapPosition = _scrollingTreeNodeDelegate->scrollingNode().currentVerticalSnapPointIndex();
 
@@ -105,16 +102,16 @@
     WebCore::FloatSize viewportSize(static_cast<float>(CGRectGetWidth([scrollView bounds])), static_cast<float>(CGRectGetHeight([scrollView bounds])));
     const auto& snapOffsetsInfo = _scrollingTreeNodeDelegate->scrollingNode().snapOffsetsInfo();
     if (!snapOffsetsInfo.horizontalSnapOffsets.isEmpty()) {
-        auto [potentialSnapPosition, index] = snapOffsetsInfo.closestSnapOffset(WebCore::ScrollEventAxis::Horizontal, viewportSize, horizontalTarget, velocity.x, scrollView.contentOffset.x);
+        auto [potentialSnapPosition, index] = snapOffsetsInfo.closestSnapOffset(WebCore::ScrollEventAxis::Horizontal, viewportSize, WebCore::FloatPoint(*targetContentOffset), velocity.x, scrollView.contentOffset.x);
         _scrollingTreeNodeDelegate->scrollingNode().setCurrentHorizontalSnapPointIndex(index);
-        if (horizontalTarget >= 0 && horizontalTarget <= scrollView.contentSize.width)
+        if (targetContentOffset->x >= 0 && targetContentOffset->x <= scrollView.contentSize.width)
             targetContentOffset->x = potentialSnapPosition;
     }
 
     if (!snapOffsetsInfo.verticalSnapOffsets.isEmpty()) {
-        auto [potentialSnapPosition, index] = snapOffsetsInfo.closestSnapOffset(WebCore::ScrollEventAxis::Vertical, viewportSize, verticalTarget, velocity.y, scrollView.contentOffset.y);
+        auto [potentialSnapPosition, index] = snapOffsetsInfo.closestSnapOffset(WebCore::ScrollEventAxis::Vertical, viewportSize, WebCore::FloatPoint(*targetContentOffset), velocity.y, scrollView.contentOffset.y);
         _scrollingTreeNodeDelegate->scrollingNode().setCurrentVerticalSnapPointIndex(index);
-        if (verticalTarget >= 0 && verticalTarget <= scrollView.contentSize.height)
+        if (targetContentOffset->y >= 0 && targetContentOffset->y <= scrollView.contentSize.height)
             targetContentOffset->y = potentialSnapPosition;
     }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to