[iOS] scrollIntoViewIfNeeded is not working with scroll-snap points
authorbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 19 Jun 2015 19:24:59 +0000 (19:24 +0000)
committerbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 19 Jun 2015 19:24:59 +0000 (19:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=145318
<rdar://problem/21081501>

Reviewed by Simon Fraser.

Source/WebCore:

Use the ScrollController in iOS to track the scroll snap point state.
We do not need the animation implementation or timers since the actual
animation is handled by UIKit.

This change lets us communicate the current offset into the scroll snap
offset vector between the WebProcess and RemoteScrollingTree so that
both sides stay in sync regardless of whether user gestures or style
updates have caused us to shift to a different snap point.

* page/scrolling/AsyncScrollingCoordinator.cpp:
(WebCore::AsyncScrollingCoordinator::frameViewLayoutUpdated): Set the
current horizontal and vertical scroll snap offset indices.
(WebCore::AsyncScrollingCoordinator::updateOverflowScrollingNode): Ditto.
* page/scrolling/AsyncScrollingCoordinator.h: Mark the setActiveScrollSnapIndices
for export so that it can be reached by the UIProcess.
* page/scrolling/ScrollingCoordinator.h: Keep track of horizontal and
vertical scroll snap offset indices.
* page/scrolling/ScrollingStateScrollingNode.cpp:
(WebCore::ScrollingStateScrollingNode::setCurrentHorizontalSnapPointIndex): Added.
(WebCore::ScrollingStateScrollingNode::setCurrentVerticalSnapPointIndex): Added.
* page/scrolling/ScrollingStateScrollingNode.h:
(WebCore::ScrollingStateScrollingNode::currentHorizontalSnapPointIndex): Added.
(WebCore::ScrollingStateScrollingNode::currentVerticalSnapPointIndex): Added.
* page/scrolling/ScrollingTree.h:
* page/scrolling/ScrollingTreeScrollingNode.cpp:
(WebCore::ScrollingTreeScrollingNode::updateBeforeChildren): Update the scroll snap
point offset indices if either has changed.
* page/scrolling/ScrollingTreeScrollingNode.h:
(WebCore::ScrollingTreeScrollingNode::currentHorizontalSnapPointIndex): Added.
(WebCore::ScrollingTreeScrollingNode::currentVerticalSnapPointIndex): Added.
(WebCore::ScrollingTreeScrollingNode::setCurrentHorizontalSnapPointIndex): Added.
(WebCore::ScrollingTreeScrollingNode::setCurrentVerticalSnapPointIndex): Added.
* page/scrolling/ThreadedScrollingTree.cpp:
(WebCore::ThreadedScrollingTree::currentSnapPointIndicesDidChange): New method
to handle notifications about scroll snap index changes from the UIProcess.
* page/scrolling/ThreadedScrollingTree.h:
* page/scrolling/ios/ScrollingTreeIOS.cpp:
(WebCore::ScrollingTreeIOS::currentSnapPointIndicesDidChange): New method
to handle notifications about scroll snap index changes from the UIProcess.
* page/scrolling/ios/ScrollingTreeIOS.h:
* page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm:
(WebCore::ScrollingTreeFrameScrollingNodeMac::updateBeforeChildren): Update scroll
snap point current offset indices if they have changed.
(WebCore::ScrollingTreeFrameScrollingNodeMac::scrollOffsetOnAxis): Remove unneeded
PLATFORM(MAC) macro.
* platform/ScrollAnimator.cpp:
(WebCore::ScrollAnimator::ScrollAnimator): We have a ScrollController if we are
supporting scroll snap points or rubber banding.
(WebCore::ScrollAnimator::processWheelEventForScrollSnap): This method is not needed
for iOS builds.
(WebCore::ScrollAnimator::updateActiveScrollSnapIndexForOffset): Enable this on iOS.
(WebCore::ScrollAnimator::updateScrollSnapState): Renamed from 'updateScrollAnimatorsAndTimers'
and enabled on iOS.
(WebCore::ScrollAnimator::updateScrollAnimatorsAndTimers): Deleted.
* platform/ScrollAnimator.h: Enable some scroll snap methods on iOS.
* platform/ScrollableArea.cpp:
(WebCore::ScrollableArea::handleWheelEvent): Enable scroll snap index bookkeeping on iOS, too.
(WebCore::ScrollableArea::updateScrollSnapState): Revise to call 'updateScrollSnapState' instead
of 'updateScrollAnimatorsAndTimers'.
* platform/cocoa/ScrollController.h: Enable some methods on iOS. Reorder methods to
reduce the number of macros needed to do so.
* platform/cocoa/ScrollController.mm:
(systemUptime): Only build for Mac.
(WebCore::ScrollController::ScrollController): Disable rubber band-specific members on iOS.
(WebCore::ScrollController::handleWheelEvent): Only build this on Mac.
(WebCore::ScrollController::isRubberBandInProgress): Always return 'false' on iOS.
(WebCore::ScrollController::startSnapRubberbandTimer): Only build this on Mac.
(WebCore::ScrollController::shouldRubberBandInHorizontalDirection): Ditto.
(WebCore::ScrollController::scrollSnapPointState): Enable on iOS.
(WebCore::ScrollController::hasActiveScrollSnapTimerForAxis): Only build on Mac.
(WebCore::ScrollController::updateScrollSnapState): renamed from 'updateScrollAnimatorsAndTimers'
(WebCore::ScrollController::startScrollSnapTimer): Only build on Mac.
(WebCore::ScrollController::initializeGlideParameters): Ditto.
(WebCore::ScrollController::activeScrollSnapIndexForAxis): Enable on iOS.
(WebCore::ScrollController::setActiveScrollSnapIndicesForOffset): Ditto.
(WebCore::ScrollController::beginScrollSnapAnimation): Only build on Mac.
(WebCore::ScrollController::computeGlideDelta): Ditto.
(WebCore::ScrollController::updateScrollAnimatorsAndTimers): Deleted.
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::updateScrollCoordinatedLayer): Capture any changes in scroll
snap offset indices.

Source/WebKit2:

* Shared/Scrolling/RemoteScrollingCoordinatorTransaction.cpp:
(ArgumentCoder<ScrollingStateScrollingNode>::encode): Handle scroll snap point offset indices.
(ArgumentCoder<ScrollingStateScrollingNode>::decode): Ditto.
* UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp:
(WebKit::RemoteScrollingCoordinatorProxy::currentSnapPointIndicesDidChange): Added. Send message
to WebProcess when scroll snap indices have changed.
* UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h:
* UIProcess/Scrolling/RemoteScrollingTree.cpp:
(WebKit::RemoteScrollingTree::currentSnapPointIndicesDidChange): Added. Notify the
RemoteScrollingCoordinatorProxy when scroll snap indices have changed.
* UIProcess/Scrolling/RemoteScrollingTree.h:
* UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.h:
* UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.mm:
(-[WKOverflowScrollViewDelegate scrollViewWillEndDragging:withVelocity:targetContentOffset:]): Revised.
Identify changes in the current scroll snap point offset index (in either the horizontal or vertical
directions), and send a notification when this happens.
(WebKit::ScrollingTreeOverflowScrollingNodeIOS::currentSnapPointIndicesDidChange): Added. Notify the
Scrolling Tree when indices changed.
* UIProcess/ios/RemoteScrollingCoordinatorProxyIOS.mm:
(WebKit::RemoteScrollingCoordinatorProxy::adjustTargetContentOffsetForSnapping): Revised. Always compute
the new scroll snap offset index (even when we will rubber band).
* WebProcess/Scrolling/RemoteScrollingCoordinator.h:
* WebProcess/Scrolling/RemoteScrollingCoordinator.messages.in: Add a new message to relay changes in scroll
snap index.
* WebProcess/Scrolling/RemoteScrollingCoordinator.mm:
(WebKit::RemoteScrollingCoordinator::currentSnapPointIndicesChangedForNode): Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@185762 268f45cc-cd09-0410-ab3c-d52691b4dbfc

32 files changed:
Source/WebCore/ChangeLog
Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp
Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h
Source/WebCore/page/scrolling/ScrollingCoordinator.h
Source/WebCore/page/scrolling/ScrollingStateScrollingNode.cpp
Source/WebCore/page/scrolling/ScrollingStateScrollingNode.h
Source/WebCore/page/scrolling/ScrollingTree.h
Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp
Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h
Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp
Source/WebCore/page/scrolling/ThreadedScrollingTree.h
Source/WebCore/page/scrolling/ios/ScrollingTreeIOS.cpp
Source/WebCore/page/scrolling/ios/ScrollingTreeIOS.h
Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm
Source/WebCore/platform/ScrollAnimator.cpp
Source/WebCore/platform/ScrollAnimator.h
Source/WebCore/platform/ScrollableArea.cpp
Source/WebCore/platform/cocoa/ScrollController.h
Source/WebCore/platform/cocoa/ScrollController.mm
Source/WebCore/rendering/RenderLayerCompositor.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/Scrolling/RemoteScrollingCoordinatorTransaction.cpp
Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp
Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h
Source/WebKit2/UIProcess/Scrolling/RemoteScrollingTree.cpp
Source/WebKit2/UIProcess/Scrolling/RemoteScrollingTree.h
Source/WebKit2/UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.h
Source/WebKit2/UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.mm
Source/WebKit2/UIProcess/ios/RemoteScrollingCoordinatorProxyIOS.mm
Source/WebKit2/WebProcess/Scrolling/RemoteScrollingCoordinator.h
Source/WebKit2/WebProcess/Scrolling/RemoteScrollingCoordinator.messages.in
Source/WebKit2/WebProcess/Scrolling/RemoteScrollingCoordinator.mm

index f5b4baa..e56f6ea 100644 (file)
@@ -1,3 +1,93 @@
+2015-06-18  Brent Fulgham  <bfulgham@apple.com>
+
+        [iOS] scrollIntoViewIfNeeded is not working with scroll-snap points
+        https://bugs.webkit.org/show_bug.cgi?id=145318
+        <rdar://problem/21081501>
+
+        Reviewed by Simon Fraser.
+
+        Use the ScrollController in iOS to track the scroll snap point state.
+        We do not need the animation implementation or timers since the actual
+        animation is handled by UIKit.
+
+        This change lets us communicate the current offset into the scroll snap
+        offset vector between the WebProcess and RemoteScrollingTree so that
+        both sides stay in sync regardless of whether user gestures or style
+        updates have caused us to shift to a different snap point.
+
+        * page/scrolling/AsyncScrollingCoordinator.cpp:
+        (WebCore::AsyncScrollingCoordinator::frameViewLayoutUpdated): Set the
+        current horizontal and vertical scroll snap offset indices.
+        (WebCore::AsyncScrollingCoordinator::updateOverflowScrollingNode): Ditto.
+        * page/scrolling/AsyncScrollingCoordinator.h: Mark the setActiveScrollSnapIndices
+        for export so that it can be reached by the UIProcess.
+        * page/scrolling/ScrollingCoordinator.h: Keep track of horizontal and
+        vertical scroll snap offset indices.
+        * page/scrolling/ScrollingStateScrollingNode.cpp:
+        (WebCore::ScrollingStateScrollingNode::setCurrentHorizontalSnapPointIndex): Added.
+        (WebCore::ScrollingStateScrollingNode::setCurrentVerticalSnapPointIndex): Added.
+        * page/scrolling/ScrollingStateScrollingNode.h:
+        (WebCore::ScrollingStateScrollingNode::currentHorizontalSnapPointIndex): Added.
+        (WebCore::ScrollingStateScrollingNode::currentVerticalSnapPointIndex): Added.
+        * page/scrolling/ScrollingTree.h:
+        * page/scrolling/ScrollingTreeScrollingNode.cpp:
+        (WebCore::ScrollingTreeScrollingNode::updateBeforeChildren): Update the scroll snap
+        point offset indices if either has changed.
+        * page/scrolling/ScrollingTreeScrollingNode.h:
+        (WebCore::ScrollingTreeScrollingNode::currentHorizontalSnapPointIndex): Added.
+        (WebCore::ScrollingTreeScrollingNode::currentVerticalSnapPointIndex): Added.
+        (WebCore::ScrollingTreeScrollingNode::setCurrentHorizontalSnapPointIndex): Added.
+        (WebCore::ScrollingTreeScrollingNode::setCurrentVerticalSnapPointIndex): Added.
+        * page/scrolling/ThreadedScrollingTree.cpp:
+        (WebCore::ThreadedScrollingTree::currentSnapPointIndicesDidChange): New method
+        to handle notifications about scroll snap index changes from the UIProcess.
+        * page/scrolling/ThreadedScrollingTree.h:
+        * page/scrolling/ios/ScrollingTreeIOS.cpp:
+        (WebCore::ScrollingTreeIOS::currentSnapPointIndicesDidChange): New method
+        to handle notifications about scroll snap index changes from the UIProcess.
+        * page/scrolling/ios/ScrollingTreeIOS.h:
+        * page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm:
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::updateBeforeChildren): Update scroll
+        snap point current offset indices if they have changed.
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::scrollOffsetOnAxis): Remove unneeded
+        PLATFORM(MAC) macro.
+        * platform/ScrollAnimator.cpp:
+        (WebCore::ScrollAnimator::ScrollAnimator): We have a ScrollController if we are
+        supporting scroll snap points or rubber banding.
+        (WebCore::ScrollAnimator::processWheelEventForScrollSnap): This method is not needed
+        for iOS builds.
+        (WebCore::ScrollAnimator::updateActiveScrollSnapIndexForOffset): Enable this on iOS.
+        (WebCore::ScrollAnimator::updateScrollSnapState): Renamed from 'updateScrollAnimatorsAndTimers'
+        and enabled on iOS.
+        (WebCore::ScrollAnimator::updateScrollAnimatorsAndTimers): Deleted.
+        * platform/ScrollAnimator.h: Enable some scroll snap methods on iOS.
+        * platform/ScrollableArea.cpp:
+        (WebCore::ScrollableArea::handleWheelEvent): Enable scroll snap index bookkeeping on iOS, too.
+        (WebCore::ScrollableArea::updateScrollSnapState): Revise to call 'updateScrollSnapState' instead
+        of 'updateScrollAnimatorsAndTimers'.
+        * platform/cocoa/ScrollController.h: Enable some methods on iOS. Reorder methods to
+        reduce the number of macros needed to do so.
+        * platform/cocoa/ScrollController.mm:
+        (systemUptime): Only build for Mac.
+        (WebCore::ScrollController::ScrollController): Disable rubber band-specific members on iOS.
+        (WebCore::ScrollController::handleWheelEvent): Only build this on Mac.
+        (WebCore::ScrollController::isRubberBandInProgress): Always return 'false' on iOS.
+        (WebCore::ScrollController::startSnapRubberbandTimer): Only build this on Mac.
+        (WebCore::ScrollController::shouldRubberBandInHorizontalDirection): Ditto.
+        (WebCore::ScrollController::scrollSnapPointState): Enable on iOS.
+        (WebCore::ScrollController::hasActiveScrollSnapTimerForAxis): Only build on Mac.
+        (WebCore::ScrollController::updateScrollSnapState): renamed from 'updateScrollAnimatorsAndTimers'
+        (WebCore::ScrollController::startScrollSnapTimer): Only build on Mac.
+        (WebCore::ScrollController::initializeGlideParameters): Ditto.
+        (WebCore::ScrollController::activeScrollSnapIndexForAxis): Enable on iOS.
+        (WebCore::ScrollController::setActiveScrollSnapIndicesForOffset): Ditto.
+        (WebCore::ScrollController::beginScrollSnapAnimation): Only build on Mac.
+        (WebCore::ScrollController::computeGlideDelta): Ditto.
+        (WebCore::ScrollController::updateScrollAnimatorsAndTimers): Deleted.
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::updateScrollCoordinatedLayer): Capture any changes in scroll
+        snap offset indices.
+
 2015-06-19  Jeremy Jones  <jeremyj@apple.com>
 
         Fullscreen view should not update bounds of video when in PiP.
index 55cb842..29c66f1 100644 (file)
@@ -146,6 +146,9 @@ void AsyncScrollingCoordinator::frameViewLayoutUpdated(FrameView& frameView)
 
     if (const Vector<LayoutUnit>* verticalSnapOffsets = frameView.verticalSnapOffsets())
         setStateScrollingNodeSnapOffsetsAsFloat(*node, ScrollEventAxis::Vertical, *verticalSnapOffsets, m_page->deviceScaleFactor());
+
+    node->setCurrentHorizontalSnapPointIndex(frameView.currentHorizontalSnapPointIndex());
+    node->setCurrentVerticalSnapPointIndex(frameView.currentVerticalSnapPointIndex());
 #endif
 
 #if PLATFORM(COCOA)
@@ -484,6 +487,8 @@ void AsyncScrollingCoordinator::updateOverflowScrollingNode(ScrollingNodeID node
 #if ENABLE(CSS_SCROLL_SNAP)
         setStateScrollingNodeSnapOffsetsAsFloat(*node, ScrollEventAxis::Horizontal, scrollingGeometry->horizontalSnapOffsets, m_page->deviceScaleFactor());
         setStateScrollingNodeSnapOffsetsAsFloat(*node, ScrollEventAxis::Vertical, scrollingGeometry->verticalSnapOffsets, m_page->deviceScaleFactor());
+        node->setCurrentHorizontalSnapPointIndex(scrollingGeometry->currentHorizontalSnapPointIndex);
+        node->setCurrentVerticalSnapPointIndex(scrollingGeometry->currentVerticalSnapPointIndex);
 #endif
     }
 }
index 68b1afc..8e427b9 100644 (file)
@@ -57,7 +57,7 @@ public:
     WEBCORE_EXPORT void scheduleUpdateScrollPositionAfterAsyncScroll(ScrollingNodeID, const FloatPoint&, bool programmaticScroll, SetOrSyncScrollingLayerPosition);
 
 #if PLATFORM(COCOA)
-    void setActiveScrollSnapIndices(ScrollingNodeID, unsigned horizontalIndex, unsigned verticalIndex);
+    WEBCORE_EXPORT void setActiveScrollSnapIndices(ScrollingNodeID, unsigned horizontalIndex, unsigned verticalIndex);
     void deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const;
     void removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const;
 #endif
index db16b06..446b8cc 100644 (file)
@@ -168,6 +168,8 @@ public:
 #if ENABLE(CSS_SCROLL_SNAP)
         Vector<LayoutUnit> horizontalSnapOffsets;
         Vector<LayoutUnit> verticalSnapOffsets;
+        unsigned currentHorizontalSnapPointIndex;
+        unsigned currentVerticalSnapPointIndex;
 #endif
     };
 
index fd7319a..c53b9b5 100644 (file)
@@ -123,6 +123,24 @@ void ScrollingStateScrollingNode::setVerticalSnapOffsets(const Vector<float>& sn
     m_verticalSnapOffsets = snapOffsets;
     setPropertyChanged(VerticalSnapOffsets);
 }
+
+void ScrollingStateScrollingNode::setCurrentHorizontalSnapPointIndex(unsigned index)
+{
+    if (m_currentHorizontalSnapPointIndex == index)
+        return;
+    
+    m_currentHorizontalSnapPointIndex = index;
+    setPropertyChanged(CurrentHorizontalSnapOffsetIndex);
+}
+
+void ScrollingStateScrollingNode::setCurrentVerticalSnapPointIndex(unsigned index)
+{
+    if (m_currentVerticalSnapPointIndex == index)
+        return;
+    
+    m_currentVerticalSnapPointIndex = index;
+    setPropertyChanged(CurrentVerticalSnapOffsetIndex);
+}
 #endif
 
 void ScrollingStateScrollingNode::setScrollableAreaParameters(const ScrollableAreaParameters& parameters)
index 0fd0307..091efd1 100644 (file)
@@ -50,6 +50,8 @@ public:
 #if ENABLE(CSS_SCROLL_SNAP)
         HorizontalSnapOffsets,
         VerticalSnapOffsets,
+        CurrentHorizontalSnapOffsetIndex,
+        CurrentVerticalSnapOffsetIndex,
 #endif
         ExpectsWheelEventTestTrigger,
     };
@@ -75,6 +77,12 @@ public:
 
     const Vector<float>& verticalSnapOffsets() const { return m_verticalSnapOffsets; }
     WEBCORE_EXPORT void setVerticalSnapOffsets(const Vector<float>&);
+
+    unsigned currentHorizontalSnapPointIndex() const { return m_currentHorizontalSnapPointIndex; }
+    WEBCORE_EXPORT void setCurrentHorizontalSnapPointIndex(unsigned);
+
+    unsigned currentVerticalSnapPointIndex() const { return m_currentVerticalSnapPointIndex; }
+    WEBCORE_EXPORT void setCurrentVerticalSnapPointIndex(unsigned);
 #endif
 
     const ScrollableAreaParameters& scrollableAreaParameters() const { return m_scrollableAreaParameters; }
@@ -103,6 +111,8 @@ private:
 #if ENABLE(CSS_SCROLL_SNAP)
     Vector<float> m_horizontalSnapOffsets;
     Vector<float> m_verticalSnapOffsets;
+    unsigned m_currentHorizontalSnapPointIndex { 0 };
+    unsigned m_currentVerticalSnapPointIndex { 0 };
 #endif
     ScrollableAreaParameters m_scrollableAreaParameters;
     bool m_requestedScrollPositionRepresentsProgrammaticScroll { false };
index 335c02c..12cb26f 100644 (file)
@@ -89,6 +89,8 @@ public:
     // and call scrollingTreeNodeDidScroll().
     WEBCORE_EXPORT virtual void scrollPositionChangedViaDelegatedScrolling(ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, bool inUserInteration);
 
+    WEBCORE_EXPORT virtual void currentSnapPointIndicesDidChange(ScrollingNodeID, unsigned horizontal, unsigned vertical) = 0;
+
     FloatPoint mainFrameScrollPosition();
     
 #if PLATFORM(IOS)
index 7032e2d..9a4ff95 100644 (file)
@@ -73,6 +73,12 @@ void ScrollingTreeScrollingNode::updateBeforeChildren(const ScrollingStateNode&
 
     if (state.hasChangedProperty(ScrollingStateScrollingNode::VerticalSnapOffsets))
         m_verticalSnapOffsets = state.verticalSnapOffsets();
+
+    if (state.hasChangedProperty(ScrollingStateScrollingNode::CurrentHorizontalSnapOffsetIndex))
+        m_currentHorizontalSnapPointIndex = state.currentHorizontalSnapPointIndex();
+
+    if (state.hasChangedProperty(ScrollingStateScrollingNode::CurrentVerticalSnapOffsetIndex))
+        m_currentVerticalSnapPointIndex = state.currentVerticalSnapPointIndex();
 #endif
 
     if (state.hasChangedProperty(ScrollingStateScrollingNode::ScrollableAreaParams))
index 1e1dc1b..07c896c 100644 (file)
@@ -59,6 +59,10 @@ public:
 #if ENABLE(CSS_SCROLL_SNAP)
     const Vector<float>& horizontalSnapOffsets() const { return m_horizontalSnapOffsets; }
     const Vector<float>& verticalSnapOffsets() const { return m_verticalSnapOffsets; }
+    unsigned currentHorizontalSnapPointIndex() const { return m_currentHorizontalSnapPointIndex; }
+    unsigned currentVerticalSnapPointIndex() const { return m_currentVerticalSnapPointIndex; }
+    void setCurrentHorizontalSnapPointIndex(unsigned index) { m_currentHorizontalSnapPointIndex = index; }
+    void setCurrentVerticalSnapPointIndex(unsigned index) { m_currentVerticalSnapPointIndex = index; }
 #endif
 
 protected:
@@ -99,6 +103,8 @@ private:
 #if ENABLE(CSS_SCROLL_SNAP)
     Vector<float> m_horizontalSnapOffsets;
     Vector<float> m_verticalSnapOffsets;
+    unsigned m_currentHorizontalSnapPointIndex { 0 };
+    unsigned m_currentVerticalSnapPointIndex { 0 };
 #endif
     ScrollableAreaParameters m_scrollableAreaParameters;
 };
index 355ad22..d813dae 100644 (file)
@@ -111,6 +111,17 @@ void ThreadedScrollingTree::scrollingTreeNodeDidScroll(ScrollingNodeID nodeID, c
     });
 }
 
+void ThreadedScrollingTree::currentSnapPointIndicesDidChange(ScrollingNodeID nodeID, unsigned horizontal, unsigned vertical)
+{
+    if (!m_scrollingCoordinator)
+        return;
+
+    RefPtr<AsyncScrollingCoordinator> scrollingCoordinator = m_scrollingCoordinator;
+    RunLoop::main().dispatch([scrollingCoordinator, nodeID, horizontal, vertical] {
+        scrollingCoordinator->setActiveScrollSnapIndices(nodeID, horizontal, vertical);
+    });
+}
+
 #if PLATFORM(MAC)
 void ThreadedScrollingTree::handleWheelEventPhase(PlatformWheelEventPhase phase)
 {
index 2547923..6bc801b 100644 (file)
@@ -60,6 +60,7 @@ protected:
     explicit ThreadedScrollingTree(AsyncScrollingCoordinator*);
 
     virtual void scrollingTreeNodeDidScroll(ScrollingNodeID, const FloatPoint& scrollPosition, SetOrSyncScrollingLayerPosition = SyncScrollingLayerPosition) override;
+    void currentSnapPointIndicesDidChange(ScrollingNodeID, unsigned horizontal, unsigned vertical) override;
 #if PLATFORM(MAC)
     void handleWheelEventPhase(PlatformWheelEventPhase) override;
     void setActiveScrollSnapIndices(ScrollingNodeID, unsigned horizontalIndex, unsigned verticalIndex) override;
index 6325a5f..eec1c9e 100644 (file)
@@ -118,6 +118,17 @@ FloatRect ScrollingTreeIOS::fixedPositionRect()
     return FloatRect();
 }
 
+void ScrollingTreeIOS::currentSnapPointIndicesDidChange(WebCore::ScrollingNodeID nodeID, unsigned horizontal, unsigned vertical)
+{
+    if (!m_scrollingCoordinator)
+        return;
+    
+    RefPtr<AsyncScrollingCoordinator> scrollingCoordinator = m_scrollingCoordinator;
+    callOnMainThread([scrollingCoordinator, nodeID, horizontal, vertical] {
+        scrollingCoordinator->setActiveScrollSnapIndices(nodeID, horizontal, vertical);
+    });
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(ASYNC_SCROLLING)
index f90ca1d..161f057 100644 (file)
@@ -58,6 +58,8 @@ private:
 
     virtual void scrollingTreeNodeDidScroll(ScrollingNodeID, const FloatPoint& scrollPosition, SetOrSyncScrollingLayerPosition = SyncScrollingLayerPosition) override;
 
+    void currentSnapPointIndicesDidChange(WebCore::ScrollingNodeID, unsigned horizontal, unsigned vertical) override;
+
     virtual FloatRect fixedPositionRect() override;
 
     RefPtr<AsyncScrollingCoordinator> m_scrollingCoordinator;
index 08630d8..2a637cb 100644 (file)
@@ -137,6 +137,12 @@ void ScrollingTreeFrameScrollingNodeMac::updateBeforeChildren(const ScrollingSta
 
     if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::VerticalSnapOffsets))
         m_scrollController.updateScrollSnapPoints(ScrollEventAxis::Vertical, convertToLayoutUnits(scrollingStateNode.verticalSnapOffsets()));
+
+    if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::CurrentHorizontalSnapOffsetIndex))
+        m_scrollController.setActiveScrollSnapIndexForAxis(ScrollEventAxis::Horizontal, scrollingStateNode.currentHorizontalSnapPointIndex());
+    
+    if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::CurrentVerticalSnapOffsetIndex))
+        m_scrollController.setActiveScrollSnapIndexForAxis(ScrollEventAxis::Vertical, scrollingStateNode.currentVerticalSnapPointIndex());
 #endif
 
     if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ExpectsWheelEventTestTrigger))
@@ -553,7 +559,7 @@ static void logThreadedScrollingMode(unsigned synchronousScrollingReasons)
         WTFLogAlways("SCROLLING: Switching to threaded scrolling mode. Time: %f\n", WTF::monotonicallyIncreasingTime());
 }
 
-#if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
+#if ENABLE(CSS_SCROLL_SNAP)
 LayoutUnit ScrollingTreeFrameScrollingNodeMac::scrollOffsetOnAxis(ScrollEventAxis axis) const
 {
     const FloatPoint& currentPosition = scrollPosition();
index 5a9d813..b97c63e 100644 (file)
@@ -49,7 +49,7 @@ std::unique_ptr<ScrollAnimator> ScrollAnimator::create(ScrollableArea& scrollabl
 
 ScrollAnimator::ScrollAnimator(ScrollableArea& scrollableArea)
     : m_scrollableArea(scrollableArea)
-#if (ENABLE(CSS_SCROLL_SNAP) || ENABLE(RUBBER_BANDING)) && PLATFORM(MAC)
+#if ENABLE(CSS_SCROLL_SNAP) || ENABLE(RUBBER_BANDING)
     , m_scrollController(*this)
 #endif
     , m_currentPosX(0)
@@ -84,11 +84,13 @@ void ScrollAnimator::scrollToOffsetWithoutAnimation(const FloatPoint& offset)
     updateActiveScrollSnapIndexForOffset();
 }
 
-#if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
+#if ENABLE(CSS_SCROLL_SNAP)
+#if PLATFORM(MAC)
 bool ScrollAnimator::processWheelEventForScrollSnap(const PlatformWheelEvent& wheelEvent)
 {
     return m_scrollController.processWheelEventForScrollSnap(wheelEvent);
 }
+#endif
 
 bool ScrollAnimator::activeScrollSnapIndexDidChange() const
 {
@@ -180,7 +182,7 @@ FloatPoint ScrollAnimator::currentPosition() const
 
 void ScrollAnimator::updateActiveScrollSnapIndexForOffset()
 {
-#if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
+#if ENABLE(CSS_SCROLL_SNAP)
     m_scrollController.setActiveScrollSnapIndicesForOffset(m_currentPosX, m_currentPosY);
     if (m_scrollController.activeScrollSnapIndexDidChange()) {
         m_scrollableArea.setCurrentHorizontalSnapPointIndex(m_scrollController.activeScrollSnapIndexForAxis(ScrollEventAxis::Horizontal));
@@ -195,10 +197,10 @@ void ScrollAnimator::notifyPositionChanged(const FloatSize& delta)
     m_scrollableArea.setScrollOffsetFromAnimation(IntPoint(m_currentPosX, m_currentPosY));
 }
 
-#if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
-void ScrollAnimator::updateScrollAnimatorsAndTimers()
+#if ENABLE(CSS_SCROLL_SNAP)
+void ScrollAnimator::updateScrollSnapState()
 {
-    m_scrollController.updateScrollAnimatorsAndTimers(m_scrollableArea);
+    m_scrollController.updateScrollSnapState(m_scrollableArea);
 }
 
 LayoutUnit ScrollAnimator::scrollOffsetOnAxis(ScrollEventAxis axis) const
index d4b1bc9..654fe10 100644 (file)
@@ -40,7 +40,7 @@
 #include <wtf/FastMalloc.h>
 #include <wtf/Forward.h>
 
-#if (ENABLE(RUBBER_BANDING) || ENABLE(CSS_SCROLL_SNAP)) && PLATFORM(MAC)
+#if ENABLE(RUBBER_BANDING) || ENABLE(CSS_SCROLL_SNAP)
 #include "ScrollController.h"
 #endif
 
@@ -52,7 +52,7 @@ class ScrollableArea;
 class Scrollbar;
 class WheelEventTestTrigger;
 
-#if (ENABLE(CSS_SCROLL_SNAP) || ENABLE(RUBBER_BANDING)) && PLATFORM(MAC)
+#if ENABLE(CSS_SCROLL_SNAP) || ENABLE(RUBBER_BANDING)
 class ScrollAnimator : private ScrollControllerClient {
 #else
 class ScrollAnimator {
@@ -128,9 +128,11 @@ public:
     void removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const override;
 #endif
     
-#if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
+#if ENABLE(CSS_SCROLL_SNAP)
+#if PLATFORM(MAC)
     bool processWheelEventForScrollSnap(const PlatformWheelEvent&);
-    void updateScrollAnimatorsAndTimers();
+#endif
+    void updateScrollSnapState();
     LayoutUnit scrollOffsetOnAxis(ScrollEventAxis) const override;
     void immediateScrollOnAxis(ScrollEventAxis, float delta) override;
     bool activeScrollSnapIndexDidChange() const;
@@ -144,7 +146,7 @@ protected:
 
     ScrollableArea& m_scrollableArea;
     RefPtr<WheelEventTestTrigger> m_wheelEventTestTrigger;
-#if (ENABLE(CSS_SCROLL_SNAP) || ENABLE(RUBBER_BANDING)) && PLATFORM(MAC)
+#if ENABLE(CSS_SCROLL_SNAP) || ENABLE(RUBBER_BANDING)
     ScrollController m_scrollController;
 #endif
     float m_currentPosX; // We avoid using a FloatPoint in order to reduce
index 889d618..ad48793 100644 (file)
@@ -190,7 +190,7 @@ bool ScrollableArea::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
         return false;
 
     bool handledEvent = scrollAnimator().handleWheelEvent(wheelEvent);
-#if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
+#if ENABLE(CSS_SCROLL_SNAP)
     if (scrollAnimator().activeScrollSnapIndexDidChange()) {
         setCurrentHorizontalSnapPointIndex(scrollAnimator().activeScrollSnapIndexForAxis(ScrollEventAxis::Horizontal));
         setCurrentVerticalSnapPointIndex(scrollAnimator().activeScrollSnapIndexForAxis(ScrollEventAxis::Vertical));
@@ -461,10 +461,8 @@ IntPoint ScrollableArea::nearestActiveSnapPoint(const IntPoint& currentPosition)
 
 void ScrollableArea::updateScrollSnapState()
 {
-#if PLATFORM(MAC)
     if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
-        scrollAnimator->updateScrollAnimatorsAndTimers();
-#endif
+        scrollAnimator->updateScrollSnapState();
 
     if (isScrollSnapInProgress())
         return;
index 452c728..92cf12e 100644 (file)
@@ -26,7 +26,7 @@
 #ifndef ScrollController_h
 #define ScrollController_h
 
-#if ENABLE(RUBBER_BANDING)
+#if ENABLE(RUBBER_BANDING) || ENABLE(CSS_SCROLL_SNAP)
 
 #include "FloatPoint.h"
 #include "FloatSize.h"
@@ -51,6 +51,7 @@ protected:
     virtual ~ScrollControllerClient() { }
 
 public:
+#if ENABLE(RUBBER_BANDING)
     virtual bool allowsHorizontalStretching(const PlatformWheelEvent&) = 0;
     virtual bool allowsVerticalStretching(const PlatformWheelEvent&) = 0;
     virtual IntSize stretchAmount() = 0;
@@ -77,11 +78,12 @@ public:
     // 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 deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const { /* Do nothing */ }
     virtual void removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const { /* Do nothing */ }
 
-#if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
+#if ENABLE(CSS_SCROLL_SNAP)
     virtual LayoutUnit scrollOffsetOnAxis(ScrollEventAxis) const = 0;
     virtual void immediateScrollOnAxis(ScrollEventAxis, float delta) = 0;
     virtual void startScrollSnapTimer(ScrollEventAxis)
@@ -114,41 +116,50 @@ class ScrollController {
 public:
     explicit ScrollController(ScrollControllerClient&);
 
+#if PLATFORM(MAC)
     bool handleWheelEvent(const PlatformWheelEvent&);
+#endif
 
     bool isRubberBandInProgress() const;
     bool isScrollSnapInProgress() const;
 
-#if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
-    bool processWheelEventForScrollSnap(const PlatformWheelEvent&);
-    void updateScrollAnimatorsAndTimers(const ScrollableArea&);
+#if ENABLE(CSS_SCROLL_SNAP)
     void updateScrollSnapPoints(ScrollEventAxis, const Vector<LayoutUnit>&);
-    unsigned activeScrollSnapIndexForAxis(ScrollEventAxis) const;
     void setActiveScrollSnapIndexForAxis(ScrollEventAxis, unsigned);
     void setActiveScrollSnapIndicesForOffset(int x, int y);
     bool activeScrollSnapIndexDidChange() const { return m_activeScrollSnapIndexDidChange; }
     void setScrollSnapIndexDidChange(bool state) { m_activeScrollSnapIndexDidChange = state; }
+    unsigned activeScrollSnapIndexForAxis(ScrollEventAxis) const;
+    void updateScrollSnapState(const ScrollableArea&);
+#if PLATFORM(MAC)
+    bool processWheelEventForScrollSnap(const PlatformWheelEvent&);
     bool hasActiveScrollSnapTimerForAxis(ScrollEventAxis) const;
 #endif
+#endif
 
 private:
+#if ENABLE(RUBBER_BANDING)
     void startSnapRubberbandTimer();
     void stopSnapRubberbandTimer();
     void snapRubberBand();
     void snapRubberBandTimerFired();
 
     bool shouldRubberBandInHorizontalDirection(const PlatformWheelEvent&);
+#endif
 
-#if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
+#if ENABLE(CSS_SCROLL_SNAP)
+    LayoutUnit scrollOffsetOnAxis(ScrollEventAxis) const;
+    void setNearestScrollSnapIndexForAxisAndOffset(ScrollEventAxis, int);
+    ScrollSnapAnimatorState& scrollSnapPointState(ScrollEventAxis);
+    const ScrollSnapAnimatorState& scrollSnapPointState(ScrollEventAxis) const;
+#if PLATFORM(MAC)
     void horizontalScrollSnapTimerFired();
     void verticalScrollSnapTimerFired();
     void startScrollSnapTimer(ScrollEventAxis);
     void stopScrollSnapTimer(ScrollEventAxis);
 
-    LayoutUnit scrollOffsetOnAxis(ScrollEventAxis) const;
     void processWheelEventForScrollSnapOnAxis(ScrollEventAxis, const PlatformWheelEvent&);
     bool shouldOverrideWheelEvent(ScrollEventAxis, const PlatformWheelEvent&) const;
-    void setNearestScrollSnapIndexForAxisAndOffset(ScrollEventAxis, int);
 
     void beginScrollSnapAnimation(ScrollEventAxis, ScrollSnapState);
     void scrollSnapAnimationUpdate(ScrollEventAxis);
@@ -157,32 +168,34 @@ private:
     void initializeGlideParameters(ScrollEventAxis, bool);
     float computeSnapDelta(ScrollEventAxis) const;
     float computeGlideDelta(ScrollEventAxis) const;
-
-    ScrollSnapAnimatorState& scrollSnapPointState(ScrollEventAxis);
-    const ScrollSnapAnimatorState& scrollSnapPointState(ScrollEventAxis) const;
+#endif
 #endif
 
     ScrollControllerClient& m_client;
     
-    CFTimeInterval m_lastMomentumScrollTimestamp;
+    CFTimeInterval m_lastMomentumScrollTimestamp { 0 };
     FloatSize m_overflowScrollDelta;
     FloatSize m_stretchScrollForce;
     FloatSize m_momentumVelocity;
 
+#if ENABLE(RUBBER_BANDING)
     // Rubber band state.
-    CFTimeInterval m_startTime;
+    CFTimeInterval m_startTime { 0 };
     FloatSize m_startStretch;
     FloatPoint m_origOrigin;
     FloatSize m_origVelocity;
     RunLoop::Timer<ScrollController> m_snapRubberbandTimer;
+#endif
 
-#if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
-    // FIXME: Find a way to consolidate both timers into one variable.
+#if ENABLE(CSS_SCROLL_SNAP)
     std::unique_ptr<ScrollSnapAnimatorState> m_horizontalScrollSnapState;
     std::unique_ptr<ScrollSnapAnimatorState> m_verticalScrollSnapState;
+#if PLATFORM(MAC)
+    // FIXME: Find a way to consolidate both timers into one variable.
     RunLoop::Timer<ScrollController> m_horizontalScrollSnapTimer;
     RunLoop::Timer<ScrollController> m_verticalScrollSnapTimer;
 #endif
+#endif
 
     bool m_inScrollGesture { false };
     bool m_momentumScrollInProgress { false };
index e592fbe..048adb9 100644 (file)
@@ -38,8 +38,9 @@
 #include "ScrollableArea.h"
 #endif
 
-#if ENABLE(RUBBER_BANDING)
+#if ENABLE(RUBBER_BANDING) || ENABLE(CSS_SCROLL_SNAP)
 
+#if PLATFORM(MAC)
 static NSTimeInterval systemUptime()
 {
     if ([[NSProcessInfo processInfo] respondsToSelector:@selector(systemUptime)])
@@ -62,13 +63,15 @@ static NSTimeInterval systemUptime()
     }
     return 0;
 }
-
+#endif
 
 namespace WebCore {
 
+#if ENABLE(RUBBER_BANDING)
 static const float scrollVelocityZeroingTimeout = 0.10f;
 static const float rubberbandDirectionLockStretchRatio = 1;
 static const float rubberbandMinimumRequiredDeltaBeforeStretch = 10;
+#endif
 
 #if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
 static const float snapMagnitudeMax = 25;
@@ -85,6 +88,7 @@ static const float maxTargetWheelDelta = 7;
 static const float minTargetWheelDelta = 3.5;
 #endif
 
+#if PLATFORM(MAC)
 enum class WheelEventStatus {
     UserScrollBegin,
     UserScrolling,
@@ -121,12 +125,13 @@ static float scrollWheelMultiplier()
     }
     return multiplier;
 }
+#endif
 
 ScrollController::ScrollController(ScrollControllerClient& client)
     : m_client(client)
-    , m_lastMomentumScrollTimestamp(0)
-    , m_startTime(0)
+#if ENABLE(RUBBER_BANDING)
     , m_snapRubberbandTimer(RunLoop::current(), this, &ScrollController::snapRubberBandTimerFired)
+#endif
 #if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
     , m_horizontalScrollSnapTimer(RunLoop::current(), this, &ScrollController::horizontalScrollSnapTimerFired)
     , m_verticalScrollSnapTimer(RunLoop::current(), this, &ScrollController::verticalScrollSnapTimerFired)
@@ -134,9 +139,10 @@ ScrollController::ScrollController(ScrollControllerClient& client)
 {
 }
 
+#if PLATFORM(MAC)
 bool ScrollController::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
 {
-#if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
+#if ENABLE(CSS_SCROLL_SNAP)
     if (!processWheelEventForScrollSnap(wheelEvent))
         return false;
 #endif
@@ -320,7 +326,9 @@ bool ScrollController::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
 
     return true;
 }
+#endif
 
+#if ENABLE(RUBBER_BANDING)
 static inline float roundTowardZero(float num)
 {
     return num > 0 ? ceilf(num - 0.5f) : floorf(num + 0.5f);
@@ -396,13 +404,18 @@ void ScrollController::snapRubberBandTimerFired()
             stopSnapRubberbandTimer();
     }
 }
+#endif
 
 bool ScrollController::isRubberBandInProgress() const
 {
+#if ENABLE(RUBBER_BANDING) && PLATFORM(MAC)
     if (!m_inScrollGesture && !m_momentumScrollInProgress && !m_snapRubberbandTimerIsActive)
         return false;
 
     return !m_client.stretchAmount().isZero();
+#else
+    return false;
+#endif
 }
 
 bool ScrollController::isScrollSnapInProgress() const
@@ -414,6 +427,7 @@ bool ScrollController::isScrollSnapInProgress() const
     return false;
 }
 
+#if ENABLE(RUBBER_BANDING)
 void ScrollController::startSnapRubberbandTimer()
 {
     m_client.startSnapRubberbandTimer();
@@ -460,8 +474,9 @@ bool ScrollController::shouldRubberBandInHorizontalDirection(const PlatformWheel
 
     return true;
 }
+#endif
 
-#if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
+#if ENABLE(CSS_SCROLL_SNAP)
 ScrollSnapAnimatorState& ScrollController::scrollSnapPointState(ScrollEventAxis axis)
 {
     ASSERT(axis != ScrollEventAxis::Horizontal || m_horizontalScrollSnapState);
@@ -478,6 +493,7 @@ const ScrollSnapAnimatorState& ScrollController::scrollSnapPointState(ScrollEven
     return (axis == ScrollEventAxis::Horizontal) ? *m_horizontalScrollSnapState : *m_verticalScrollSnapState;
 }
 
+#if PLATFORM(MAC)
 bool ScrollController::hasActiveScrollSnapTimerForAxis(ScrollEventAxis axis) const
 {
     return (axis == ScrollEventAxis::Horizontal) ? m_horizontalScrollSnapTimer.isActive() : m_verticalScrollSnapTimer.isActive();
@@ -597,8 +613,9 @@ bool ScrollController::processWheelEventForScrollSnap(const PlatformWheelEvent&
 
     return true;
 }
+#endif
 
-void ScrollController::updateScrollAnimatorsAndTimers(const ScrollableArea& scrollableArea)
+void ScrollController::updateScrollSnapState(const ScrollableArea& scrollableArea)
 {
     // FIXME: Currently, scroll snap animators are recreated even though the snap offsets alone can be updated.
     if (scrollableArea.horizontalSnapOffsets())
@@ -622,6 +639,7 @@ void ScrollController::updateScrollSnapPoints(ScrollEventAxis axis, const Vector
         m_verticalScrollSnapState = !snapPoints.isEmpty() ? std::make_unique<ScrollSnapAnimatorState>(ScrollEventAxis::Vertical, snapPoints) : nullptr;
 }
 
+#if PLATFORM(MAC)
 void ScrollController::startScrollSnapTimer(ScrollEventAxis axis)
 {
     RunLoop::Timer<ScrollController>& scrollSnapTimer = axis == ScrollEventAxis::Horizontal ? m_horizontalScrollSnapTimer : m_verticalScrollSnapTimer;
@@ -699,6 +717,7 @@ void ScrollController::initializeGlideParameters(ScrollEventAxis axis, bool shou
     snapState.m_glideMagnitude = (snapState.m_glideInitialWheelDelta + targetFinalWheelDelta) / 2;
     snapState.m_glidePhaseShift = acos((snapState.m_glideInitialWheelDelta - targetFinalWheelDelta) / (snapState.m_glideInitialWheelDelta + targetFinalWheelDelta));
 }
+#endif
 
 unsigned ScrollController::activeScrollSnapIndexForAxis(ScrollEventAxis axis) const
 {
@@ -745,6 +764,7 @@ void ScrollController::setActiveScrollSnapIndicesForOffset(int x, int y)
         setNearestScrollSnapIndexForAxisAndOffset(ScrollEventAxis::Vertical, y);
 }
 
+#if PLATFORM(MAC)
 void ScrollController::beginScrollSnapAnimation(ScrollEventAxis axis, ScrollSnapState newState)
 {
     ASSERT(newState == ScrollSnapState::Gliding || newState == ScrollSnapState::Snapping);
@@ -886,6 +906,7 @@ float ScrollController::computeGlideDelta(ScrollEventAxis axis) const
     return glideDelta;
 }
 #endif
+#endif
 
 } // namespace WebCore
 
index f217e79..0295dd0 100644 (file)
@@ -3933,6 +3933,8 @@ void RenderLayerCompositor::updateScrollCoordinatedLayer(RenderLayer& layer, Lay
                 scrollingGeometry.horizontalSnapOffsets = *offsets;
             if (const Vector<LayoutUnit>* offsets = layer.verticalSnapOffsets())
                 scrollingGeometry.verticalSnapOffsets = *offsets;
+            scrollingGeometry.currentHorizontalSnapPointIndex = layer.currentHorizontalSnapPointIndex();
+            scrollingGeometry.currentVerticalSnapPointIndex = layer.currentVerticalSnapPointIndex();
 #endif
             scrollingCoordinator->updateOverflowScrollingNode(nodeID, backing->scrollingLayer(), backing->scrollingContentsLayer(), &scrollingGeometry);
         }
index 4b17f85..ae56f9f 100644 (file)
@@ -1,3 +1,38 @@
+2015-06-18  Brent Fulgham  <bfulgham@apple.com>
+
+        [iOS] scrollIntoViewIfNeeded is not working with scroll-snap points
+        https://bugs.webkit.org/show_bug.cgi?id=145318
+        <rdar://problem/21081501>
+
+        Reviewed by Simon Fraser.
+
+        * Shared/Scrolling/RemoteScrollingCoordinatorTransaction.cpp:
+        (ArgumentCoder<ScrollingStateScrollingNode>::encode): Handle scroll snap point offset indices.
+        (ArgumentCoder<ScrollingStateScrollingNode>::decode): Ditto.
+        * UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp:
+        (WebKit::RemoteScrollingCoordinatorProxy::currentSnapPointIndicesDidChange): Added. Send message
+        to WebProcess when scroll snap indices have changed.
+        * UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h:
+        * UIProcess/Scrolling/RemoteScrollingTree.cpp:
+        (WebKit::RemoteScrollingTree::currentSnapPointIndicesDidChange): Added. Notify the
+        RemoteScrollingCoordinatorProxy when scroll snap indices have changed.
+        * UIProcess/Scrolling/RemoteScrollingTree.h:
+        * UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.h:
+        * UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.mm:
+        (-[WKOverflowScrollViewDelegate scrollViewWillEndDragging:withVelocity:targetContentOffset:]): Revised.
+        Identify changes in the current scroll snap point offset index (in either the horizontal or vertical
+        directions), and send a notification when this happens.
+        (WebKit::ScrollingTreeOverflowScrollingNodeIOS::currentSnapPointIndicesDidChange): Added. Notify the
+        Scrolling Tree when indices changed.
+        * UIProcess/ios/RemoteScrollingCoordinatorProxyIOS.mm:
+        (WebKit::RemoteScrollingCoordinatorProxy::adjustTargetContentOffsetForSnapping): Revised. Always compute
+        the new scroll snap offset index (even when we will rubber band).
+        * WebProcess/Scrolling/RemoteScrollingCoordinator.h:
+        * WebProcess/Scrolling/RemoteScrollingCoordinator.messages.in: Add a new message to relay changes in scroll
+        snap index.
+        * WebProcess/Scrolling/RemoteScrollingCoordinator.mm:
+        (WebKit::RemoteScrollingCoordinator::currentSnapPointIndicesChangedForNode): Added.
+
 2015-06-19  Jeremy Jones  <jeremyj@apple.com>
 
         Revert switch to _synchronizedDrawingFence.
index 804fcc8..f16bf11 100644 (file)
@@ -131,6 +131,8 @@ void ArgumentCoder<ScrollingStateScrollingNode>::encode(ArgumentEncoder& encoder
 #if ENABLE(CSS_SCROLL_SNAP)
     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::HorizontalSnapOffsets, horizontalSnapOffsets)
     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::VerticalSnapOffsets, verticalSnapOffsets)
+    SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::CurrentHorizontalSnapOffsetIndex, currentHorizontalSnapPointIndex)
+    SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::CurrentVerticalSnapOffsetIndex, currentVerticalSnapPointIndex)
 #endif
     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::ScrollableAreaParams, scrollableAreaParameters)
     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::RequestedScrollPosition, requestedScrollPosition)
@@ -200,6 +202,8 @@ bool ArgumentCoder<ScrollingStateScrollingNode>::decode(ArgumentDecoder& decoder
 #if ENABLE(CSS_SCROLL_SNAP)
     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::HorizontalSnapOffsets, Vector<float>, setHorizontalSnapOffsets);
     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::VerticalSnapOffsets, Vector<float>, setVerticalSnapOffsets);
+    SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::CurrentHorizontalSnapOffsetIndex, unsigned, setCurrentHorizontalSnapPointIndex);
+    SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::CurrentVerticalSnapOffsetIndex, unsigned, setCurrentVerticalSnapPointIndex);
 #endif
     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::ScrollableAreaParams, ScrollableAreaParameters, setScrollableAreaParameters);
     
index 774c0ca..90de4ac 100644 (file)
@@ -159,6 +159,11 @@ void RemoteScrollingCoordinatorProxy::viewportChangedViaDelegatedScrolling(Scrol
     m_scrollingTree->viewportChangedViaDelegatedScrolling(nodeID, fixedPositionRect, scale);
 }
 
+void RemoteScrollingCoordinatorProxy::currentSnapPointIndicesDidChange(WebCore::ScrollingNodeID nodeID, unsigned horizontal, unsigned vertical)
+{
+    m_webPageProxy.send(Messages::RemoteScrollingCoordinator::CurrentSnapPointIndicesChangedForNode(nodeID, horizontal, vertical));
+}
+
 // This comes from the scrolling tree.
 void RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll(ScrollingNodeID scrolledNodeID, const FloatPoint& newScrollPosition, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction)
 {
index ab7dd5f..a7bb60f 100644 (file)
@@ -61,6 +61,8 @@ public:
     // Called externally when native views move around.
     void viewportChangedViaDelegatedScrolling(WebCore::ScrollingNodeID, const WebCore::FloatRect& fixedPositionRect, double scale);
 
+    void currentSnapPointIndicesDidChange(WebCore::ScrollingNodeID, unsigned horizontal, unsigned vertical);
+
     // FIXME: expose the tree and pass this to that?
     bool handleWheelEvent(const WebCore::PlatformWheelEvent&);
     
index 41ab7c5..28f3ae3 100644 (file)
@@ -134,6 +134,11 @@ PassRefPtr<ScrollingTreeNode> RemoteScrollingTree::createScrollingTreeNode(Scrol
     return nullptr;
 }
 
+void RemoteScrollingTree::currentSnapPointIndicesDidChange(ScrollingNodeID nodeID, unsigned horizontal, unsigned vertical)
+{
+    m_scrollingCoordinatorProxy.currentSnapPointIndicesDidChange(nodeID, horizontal, vertical);
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(ASYNC_SCROLLING)
index 3bcc584..a448262 100644 (file)
@@ -48,6 +48,7 @@ public:
 
     virtual void scrollingTreeNodeDidScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, WebCore::SetOrSyncScrollingLayerPosition = WebCore::SyncScrollingLayerPosition) override;
     virtual void scrollingTreeNodeRequestsScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, bool representsProgrammaticScroll) override;
+    void currentSnapPointIndicesDidChange(WebCore::ScrollingNodeID, unsigned horizontal, unsigned vertical) override;
 
 private:
     explicit RemoteScrollingTree(RemoteScrollingCoordinatorProxy&);
index aa06ed2..ce4dd96 100644 (file)
@@ -44,6 +44,7 @@ public:
     void overflowScrollDidEnd();
     void overflowScrollViewWillStartPanGesture();
     void scrollViewDidScroll(const WebCore::FloatPoint&, bool inUserInteration);
+    void currentSnapPointIndicesDidChange(unsigned horizontal, unsigned vertical);
 
     CALayer *scrollLayer() const { return m_scrollLayer.get(); }
 
index 0c24bfc..220193b 100644 (file)
@@ -83,11 +83,29 @@ using namespace WebCore;
     CGFloat horizontalTarget = targetContentOffset->x;
     CGFloat verticalTarget = targetContentOffset->y;
 
-    unsigned ignore;
-    if (!_scrollingTreeNode->horizontalSnapOffsets().isEmpty() && horizontalTarget >= 0 && horizontalTarget <= scrollView.contentSize.width)
-        targetContentOffset->x = closestSnapOffset<float, CGFloat>(_scrollingTreeNode->horizontalSnapOffsets(), horizontalTarget, velocity.x, ignore);
-    if (!_scrollingTreeNode->verticalSnapOffsets().isEmpty() && verticalTarget >= 0 && verticalTarget <= scrollView.contentSize.height)
-        targetContentOffset->y = closestSnapOffset<float, CGFloat>(_scrollingTreeNode->verticalSnapOffsets(), verticalTarget, velocity.y, ignore);
+    unsigned originalHorizontalSnapPosition = _scrollingTreeNode->currentHorizontalSnapPointIndex();
+    unsigned originalVerticalSnapPosition = _scrollingTreeNode->currentVerticalSnapPointIndex();
+
+    if (!_scrollingTreeNode->horizontalSnapOffsets().isEmpty()) {
+        unsigned index;
+        float potentialSnapPosition = closestSnapOffset<float, CGFloat>(_scrollingTreeNode->horizontalSnapOffsets(), horizontalTarget, velocity.x, index);
+        _scrollingTreeNode->setCurrentHorizontalSnapPointIndex(index);
+        if (horizontalTarget >= 0 && horizontalTarget <= scrollView.contentSize.width)
+            targetContentOffset->x = potentialSnapPosition;
+    }
+
+    if (!_scrollingTreeNode->verticalSnapOffsets().isEmpty()) {
+        unsigned index;
+        float potentialSnapPosition = closestSnapOffset<float, CGFloat>(_scrollingTreeNode->verticalSnapOffsets(), verticalTarget, velocity.y, index);
+        _scrollingTreeNode->setCurrentVerticalSnapPointIndex(index);
+        if (verticalTarget >= 0 && verticalTarget <= scrollView.contentSize.height)
+            targetContentOffset->y = potentialSnapPosition;
+    }
+
+    if (originalHorizontalSnapPosition != _scrollingTreeNode->currentHorizontalSnapPointIndex()
+        || originalVerticalSnapPosition != _scrollingTreeNode->currentVerticalSnapPointIndex()) {
+        _scrollingTreeNode->currentSnapPointIndicesDidChange(_scrollingTreeNode->currentHorizontalSnapPointIndex(), _scrollingTreeNode->currentVerticalSnapPointIndex());
+    }
 }
 #endif
 
@@ -283,6 +301,14 @@ void ScrollingTreeOverflowScrollingNodeIOS::scrollViewDidScroll(const FloatPoint
     scrollingTree().scrollPositionChangedViaDelegatedScrolling(scrollingNodeID(), scrollPosition, inUserInteration);
 }
 
+void ScrollingTreeOverflowScrollingNodeIOS::currentSnapPointIndicesDidChange(unsigned horizontal, unsigned vertical)
+{
+    if (m_updatingFromStateNode)
+        return;
+    
+    scrollingTree().currentSnapPointIndicesDidChange(scrollingNodeID(), horizontal, vertical);
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(ASYNC_SCROLLING)
index bef55be..f14cf89 100644 (file)
@@ -116,15 +116,17 @@ void RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidEndScroll()
 void RemoteScrollingCoordinatorProxy::adjustTargetContentOffsetForSnapping(CGSize maxScrollOffsets, CGPoint velocity, CGFloat topInset, CGPoint* targetContentOffset)
 {
     // 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) && targetContentOffset->x > 0 && targetContentOffset->x < maxScrollOffsets.width) {
+    if (shouldSnapForMainFrameScrolling(WebCore::ScrollEventAxis::Horizontal)) {
         float potentialSnapPosition = closestSnapOffsetForMainFrameScrolling(WebCore::ScrollEventAxis::Horizontal, targetContentOffset->x, velocity.x, m_currentHorizontalSnapPointIndex);
-        targetContentOffset->x = std::min<float>(maxScrollOffsets.width, potentialSnapPosition);
+        if (targetContentOffset->x > 0 && targetContentOffset->x < maxScrollOffsets.width)
+            targetContentOffset->x = std::min<float>(maxScrollOffsets.width, potentialSnapPosition);
     }
 
-    if (shouldSnapForMainFrameScrolling(WebCore::ScrollEventAxis::Vertical) && targetContentOffset->y > 0 && targetContentOffset->y < maxScrollOffsets.height) {
+    if (shouldSnapForMainFrameScrolling(WebCore::ScrollEventAxis::Vertical)) {
         float potentialSnapPosition = closestSnapOffsetForMainFrameScrolling(WebCore::ScrollEventAxis::Vertical, targetContentOffset->y, velocity.y, m_currentVerticalSnapPointIndex);
         potentialSnapPosition -= topInset;
-        targetContentOffset->y = std::min<float>(maxScrollOffsets.height, potentialSnapPosition);
+        if (targetContentOffset->y > 0 && targetContentOffset->y < maxScrollOffsets.height)
+            targetContentOffset->y = std::min<float>(maxScrollOffsets.height, potentialSnapPosition);
     }
 }
 
index fe08868..1ed400f 100644 (file)
@@ -73,6 +73,7 @@ private:
     
     // Respond to UI process changes.
     void scrollPositionChangedForNode(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, bool syncLayerPosition);
+    void currentSnapPointIndicesChangedForNode(WebCore::ScrollingNodeID, unsigned horizontal, unsigned vertical);
 
     WebPage* m_webPage;
 };
index 00b3d97..2c098a1 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2014 Apple Inc. All rights reserved.
+# Copyright (C) 2014-2015 Apple Inc. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
@@ -24,6 +24,7 @@
 
 messages -> RemoteScrollingCoordinator {
     ScrollPositionChangedForNode(uint64_t nodeID, WebCore::FloatPoint scrollPosition, bool syncLayerPosition);
+    CurrentSnapPointIndicesChangedForNode(uint64_t nodeID, unsigned horizontal, unsigned vertical);
 }
 
 #endif // ENABLE(ASYNC_SCROLLING)
index 00e3d92..2084b8c 100644 (file)
@@ -102,6 +102,11 @@ void RemoteScrollingCoordinator::scrollPositionChangedForNode(ScrollingNodeID no
     scheduleUpdateScrollPositionAfterAsyncScroll(nodeID, scrollPosition, false /* FIXME */, syncLayerPosition ? SyncScrollingLayerPosition : SetScrollingLayerPosition);
 }
 
+void RemoteScrollingCoordinator::currentSnapPointIndicesChangedForNode(ScrollingNodeID nodeID, unsigned horizontal, unsigned vertical)
+{
+    setActiveScrollSnapIndices(nodeID, horizontal, vertical);
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(ASYNC_SCROLLING)