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;
}