Changeset 255037 in webkit


Ignore:
Timestamp:
Jan 23, 2020, 1:51:37 PM (6 years ago)
Author:
Simon Fraser
Message:

Fixed elements no longer stay fixed with elastic overscroll
https://bugs.webkit.org/show_bug.cgi?id=206227
rdar://problem/58707084

Reviewed by Antti Koivisto.
Source/WebCore:

Intended behavior on iOS and macOS is for position:fixed and sticky elements to maintain
their position relative to the view bounds when rubber-banding ("overscrolling"). This broke
some time back. This change restores the correct behavior with the call to layoutViewportRespectingRubberBanding()
in ScrollingTreeFixedNode::applyLayerPositions() and ScrollingTreeStickyNode::computeLayerPosition().
layoutViewportRespectingRubberBanding() computes a layout viewport without clamping.

The rest of the changes are to support testing. internals.unconstrainedScrollTo()
didn't work for main frame scrolling because of scroll position clamping in various places,
so propagate ScrollClamping in more places (and replace the redundant ScrollPositionClamp with ScrollClamping).

"requested scroll position" updates now carry along both clamping and "is programmatic" data, wrapped in a struct
which is passed around the scrolling tree. This allows us to not clamp the scroll position (for testing) in more places.

Internals::unconstrainedScrollTo() needs one weird hack to trigger a layout (and thus a scrolling tree commit),
because the layout is normally triggered by a layout viewport change, but when rubber-banding we clamp the layoutViewport
used for layout, so those layouts are never triggered.

Tests: tiled-drawing/scrolling/fixed/fixed-during-rubberband.html

tiled-drawing/scrolling/sticky/sticky-during-rubberband.html

  • Sources.txt:
  • WebCore.xcodeproj/project.pbxproj:
  • dom/Element.cpp:

(WebCore::Element::scrollTo):

  • page/DOMWindow.cpp:

(WebCore::DOMWindow::scrollTo const):

  • page/FrameView.cpp:

(WebCore::FrameView::setScrollPosition):
(WebCore::FrameView::requestScrollPositionUpdate):

  • page/FrameView.h:
  • page/scrolling/AsyncScrollingCoordinator.cpp:

(WebCore::AsyncScrollingCoordinator::requestScrollPositionUpdate):

  • page/scrolling/AsyncScrollingCoordinator.h:
  • page/scrolling/ScrollingCoordinator.cpp:
  • page/scrolling/ScrollingCoordinator.h:

(WebCore::ScrollingCoordinator::requestScrollPositionUpdate):

  • page/scrolling/ScrollingStateScrollingNode.cpp:

(WebCore::ScrollingStateScrollingNode::ScrollingStateScrollingNode):
(WebCore::ScrollingStateScrollingNode::setRequestedScrollData):
(WebCore::ScrollingStateScrollingNode::dumpProperties const):
(WebCore::ScrollingStateScrollingNode::setRequestedScrollPosition): Deleted.

  • page/scrolling/ScrollingStateScrollingNode.h:

(WebCore::RequestedScrollData::operator== const):
(WebCore::ScrollingStateScrollingNode::requestedScrollData const):
(WebCore::ScrollingStateScrollingNode::requestedScrollPosition const): Deleted.
(WebCore::ScrollingStateScrollingNode::requestedScrollPositionRepresentsProgrammaticScroll const): Deleted.

  • page/scrolling/ScrollingTree.h:

(WebCore::ScrollingTree::scrollingTreeNodeRequestsScroll):

  • page/scrolling/ScrollingTreeFrameScrollingNode.cpp:

(WebCore::ScrollingTreeFrameScrollingNode::layoutViewportForScrollPosition const):
(WebCore::ScrollingTreeFrameScrollingNode::layoutViewportRespectingRubberBanding const):

  • page/scrolling/ScrollingTreeFrameScrollingNode.h:
  • page/scrolling/ScrollingTreeScrollingNode.cpp:

(WebCore::ScrollingTreeScrollingNode::commitStateAfterChildren):
(WebCore::ScrollingTreeScrollingNode::adjustedScrollPosition const):
(WebCore::ScrollingTreeScrollingNode::scrollBy):
(WebCore::ScrollingTreeScrollingNode::scrollTo):
(WebCore::ScrollingTreeScrollingNode::wasScrolledByDelegatedScrolling):

  • page/scrolling/ScrollingTreeScrollingNode.h:
  • page/scrolling/cocoa/ScrollingTreeFixedNode.mm:

(WebCore::ScrollingTreeFixedNode::applyLayerPositions):

  • page/scrolling/cocoa/ScrollingTreeStickyNode.mm:

(WebCore::ScrollingTreeStickyNode::computeLayerPosition const):

  • page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h:
  • page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm:

(WebCore::ScrollingTreeFrameScrollingNodeMac::commitStateAfterChildren):
(WebCore::ScrollingTreeFrameScrollingNodeMac::adjustedScrollPosition const):

  • page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.h:
  • page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm:

(WebCore::ScrollingTreeOverflowScrollingNodeMac::commitStateAfterChildren):
(WebCore::ScrollingTreeOverflowScrollingNodeMac::adjustedScrollPosition const):

  • page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm:

(WebCore::ScrollingTreeScrollingNodeDelegateMac::immediateScrollByWithoutContentEdgeConstraints):

  • platform/ScrollTypes.cpp: Added.

(WebCore::operator<<):

  • platform/ScrollTypes.h:
  • platform/ScrollView.cpp:

(WebCore::ScrollView::setContentsScrollPosition):
(WebCore::ScrollView::setScrollPosition):

  • platform/ScrollView.h:
  • platform/ScrollableArea.cpp:

(WebCore::ScrollableArea::setScrollOffsetFromAnimation):

  • platform/ScrollableArea.h:

(WebCore::ScrollableArea::requestScrollPositionUpdate):

  • rendering/RenderLayer.cpp:

(WebCore::RenderLayer::scrollToOffset):

  • testing/Internals.cpp:

(WebCore::Internals::unconstrainedScrollTo):

Source/WebKit:

Intended behavior on iOS and macOS is for position:fixed and sticky elements to maintain
their position relative to the view bounds when rubber-banding ("overscrolling"). This broke
some time back. This change restores the correct behavior with the call to layoutViewportRespectingRubberBanding()
in ScrollingTreeFixedNode::applyLayerPositions() and ScrollingTreeStickyNode::computeLayerPosition().
layoutViewportRespectingRubberBanding() computes a layout viewport without clamping.

The rest of the changes are to support testing. internals.unconstrainedScrollTo()
didn't work for main frame scrolling because of scroll position clamping in various places,
so propagate ScrollClamping in more places (and replace the redundant ScrollPositionClamp with ScrollClamping).

"requested scroll position" updates now carry along both clamping and "is programmatic" data, wrapped in a struct
which is passed around the scrolling tree. This allows us to not clamp the scroll position (for testing) in more places.

  • Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp:

(ArgumentCoder<ScrollingStateScrollingNode>::encode):
(ArgumentCoder<ScrollingStateScrollingNode>::decode):
(ArgumentCoder<RequestedScrollData>::encode):
(ArgumentCoder<RequestedScrollData>::decode):
(WebKit::dump):

  • UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp:

(WebKit::RemoteScrollingCoordinatorProxy::scrollingTreeNodeRequestsScroll):

  • UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h:
  • UIProcess/RemoteLayerTree/RemoteScrollingTree.cpp:

(WebKit::RemoteScrollingTree::scrollingTreeNodeRequestsScroll):

  • UIProcess/RemoteLayerTree/RemoteScrollingTree.h:
  • UIProcess/RemoteLayerTree/ios/ScrollingTreeFrameScrollingNodeRemoteIOS.mm:

(WebKit::ScrollingTreeFrameScrollingNodeRemoteIOS::commitStateAfterChildren):

  • UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm:

(WebKit::ScrollingTreeScrollingNodeDelegateIOS::commitStateAfterChildren):

LayoutTests:

  • tiled-drawing/scrolling/fixed/fixed-during-rubberband-expected.html: Added.
  • tiled-drawing/scrolling/fixed/fixed-during-rubberband.html: Added.
  • tiled-drawing/scrolling/sticky/sticky-during-rubberband-expected.html: Added.
  • tiled-drawing/scrolling/sticky/sticky-during-rubberband.html: Added.
Location:
trunk
Files:
5 added
45 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r254980 r255037  
    190190        * http/wpt/webauthn/public-key-credential-create-failure-local.https.html:
    191191
     1922020-01-22  Simon Fraser  <simon.fraser@apple.com>
     193
     194        Fixed elements no longer stay fixed with elastic overscroll
     195        https://bugs.webkit.org/show_bug.cgi?id=206227
     196        rdar://problem/58707084
     197
     198        Reviewed by Antti Koivisto.
     199
     200        * tiled-drawing/scrolling/fixed/fixed-during-rubberband-expected.html: Added.
     201        * tiled-drawing/scrolling/fixed/fixed-during-rubberband.html: Added.
     202        * tiled-drawing/scrolling/sticky/sticky-during-rubberband-expected.html: Added.
     203        * tiled-drawing/scrolling/sticky/sticky-during-rubberband.html: Added.
     204
    1922052020-01-21  Commit Queue  <commit-queue@webkit.org>
    193206
     
    195208        https://bugs.webkit.org/show_bug.cgi?id=206559
    196209
    197         Broke page up/page down on macOW (Requested by smfr on
     210        Broke page up/page down on macOS (Requested by smfr on
    198211        #webkit).
    199212
  • trunk/Source/WebCore/ChangeLog

    r255036 r255037  
    849849        (WebCore::SVGImage::nativeImageForCurrentFrame):
    850850
     8512020-01-22  Simon Fraser  <simon.fraser@apple.com>
     852
     853        Fixed elements no longer stay fixed with elastic overscroll
     854        https://bugs.webkit.org/show_bug.cgi?id=206227
     855        rdar://problem/58707084
     856
     857        Reviewed by Antti Koivisto.
     858       
     859        Intended behavior on iOS and macOS is for position:fixed and sticky elements to maintain
     860        their position relative to the view bounds when rubber-banding ("overscrolling"). This broke
     861        some time back. This change restores the correct behavior with the call to layoutViewportRespectingRubberBanding()
     862        in ScrollingTreeFixedNode::applyLayerPositions() and ScrollingTreeStickyNode::computeLayerPosition().
     863        layoutViewportRespectingRubberBanding() computes a layout viewport without clamping.
     864
     865        The rest of the changes are to support testing. internals.unconstrainedScrollTo()
     866        didn't work for main frame scrolling because of scroll position clamping in various places,
     867        so propagate ScrollClamping in more places (and replace the redundant ScrollPositionClamp with ScrollClamping).
     868
     869        "requested scroll position" updates now carry along both clamping and "is programmatic" data, wrapped in a struct
     870        which is passed around the scrolling tree. This allows us to not clamp the scroll position (for testing) in more places.
     871       
     872        Internals::unconstrainedScrollTo() needs one weird hack to trigger a layout (and thus a scrolling tree commit),
     873        because the layout is normally triggered by a layout viewport change, but when rubber-banding we clamp the layoutViewport
     874        used for layout, so those layouts are never triggered.
     875
     876        Tests: tiled-drawing/scrolling/fixed/fixed-during-rubberband.html
     877               tiled-drawing/scrolling/sticky/sticky-during-rubberband.html
     878
     879        * Sources.txt:
     880        * WebCore.xcodeproj/project.pbxproj:
     881        * dom/Element.cpp:
     882        (WebCore::Element::scrollTo):
     883        * page/DOMWindow.cpp:
     884        (WebCore::DOMWindow::scrollTo const):
     885        * page/FrameView.cpp:
     886        (WebCore::FrameView::setScrollPosition):
     887        (WebCore::FrameView::requestScrollPositionUpdate):
     888        * page/FrameView.h:
     889        * page/scrolling/AsyncScrollingCoordinator.cpp:
     890        (WebCore::AsyncScrollingCoordinator::requestScrollPositionUpdate):
     891        * page/scrolling/AsyncScrollingCoordinator.h:
     892        * page/scrolling/ScrollingCoordinator.cpp:
     893        * page/scrolling/ScrollingCoordinator.h:
     894        (WebCore::ScrollingCoordinator::requestScrollPositionUpdate):
     895        * page/scrolling/ScrollingStateScrollingNode.cpp:
     896        (WebCore::ScrollingStateScrollingNode::ScrollingStateScrollingNode):
     897        (WebCore::ScrollingStateScrollingNode::setRequestedScrollData):
     898        (WebCore::ScrollingStateScrollingNode::dumpProperties const):
     899        (WebCore::ScrollingStateScrollingNode::setRequestedScrollPosition): Deleted.
     900        * page/scrolling/ScrollingStateScrollingNode.h:
     901        (WebCore::RequestedScrollData::operator== const):
     902        (WebCore::ScrollingStateScrollingNode::requestedScrollData const):
     903        (WebCore::ScrollingStateScrollingNode::requestedScrollPosition const): Deleted.
     904        (WebCore::ScrollingStateScrollingNode::requestedScrollPositionRepresentsProgrammaticScroll const): Deleted.
     905        * page/scrolling/ScrollingTree.h:
     906        (WebCore::ScrollingTree::scrollingTreeNodeRequestsScroll):
     907        * page/scrolling/ScrollingTreeFrameScrollingNode.cpp:
     908        (WebCore::ScrollingTreeFrameScrollingNode::layoutViewportForScrollPosition const):
     909        (WebCore::ScrollingTreeFrameScrollingNode::layoutViewportRespectingRubberBanding const):
     910        * page/scrolling/ScrollingTreeFrameScrollingNode.h:
     911        * page/scrolling/ScrollingTreeScrollingNode.cpp:
     912        (WebCore::ScrollingTreeScrollingNode::commitStateAfterChildren):
     913        (WebCore::ScrollingTreeScrollingNode::adjustedScrollPosition const):
     914        (WebCore::ScrollingTreeScrollingNode::scrollBy):
     915        (WebCore::ScrollingTreeScrollingNode::scrollTo):
     916        (WebCore::ScrollingTreeScrollingNode::wasScrolledByDelegatedScrolling):
     917        * page/scrolling/ScrollingTreeScrollingNode.h:
     918        * page/scrolling/cocoa/ScrollingTreeFixedNode.mm:
     919        (WebCore::ScrollingTreeFixedNode::applyLayerPositions):
     920        * page/scrolling/cocoa/ScrollingTreeStickyNode.mm:
     921        (WebCore::ScrollingTreeStickyNode::computeLayerPosition const):
     922        * page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h:
     923        * page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm:
     924        (WebCore::ScrollingTreeFrameScrollingNodeMac::commitStateAfterChildren):
     925        (WebCore::ScrollingTreeFrameScrollingNodeMac::adjustedScrollPosition const):
     926        * page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.h:
     927        * page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm:
     928        (WebCore::ScrollingTreeOverflowScrollingNodeMac::commitStateAfterChildren):
     929        (WebCore::ScrollingTreeOverflowScrollingNodeMac::adjustedScrollPosition const):
     930        * page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm:
     931        (WebCore::ScrollingTreeScrollingNodeDelegateMac::immediateScrollByWithoutContentEdgeConstraints):
     932        * platform/ScrollTypes.cpp: Added.
     933        (WebCore::operator<<):
     934        * platform/ScrollTypes.h:
     935        * platform/ScrollView.cpp:
     936        (WebCore::ScrollView::setContentsScrollPosition):
     937        (WebCore::ScrollView::setScrollPosition):
     938        * platform/ScrollView.h:
     939        * platform/ScrollableArea.cpp:
     940        (WebCore::ScrollableArea::setScrollOffsetFromAnimation):
     941        * platform/ScrollableArea.h:
     942        (WebCore::ScrollableArea::requestScrollPositionUpdate):
     943        * rendering/RenderLayer.cpp:
     944        (WebCore::RenderLayer::scrollToOffset):
     945        * testing/Internals.cpp:
     946        (WebCore::Internals::unconstrainedScrollTo):
     947
    8519482020-01-21  Commit Queue  <commit-queue@webkit.org>
    852949
     
    854951        https://bugs.webkit.org/show_bug.cgi?id=206559
    855952
    856         Broke page up/page down on macOW (Requested by smfr on
     953        Broke page up/page down on macOS (Requested by smfr on
    857954        #webkit).
    858955
  • trunk/Source/WebCore/Sources.txt

    r254890 r255037  
    17641764platform/SSLKeyGenerator.cpp
    17651765platform/ScrollAnimator.cpp
     1766platform/ScrollTypes.cpp
    17661767platform/ScrollView.cpp
    17671768platform/ScrollableArea.cpp
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r254995 r255037  
    57485748                0F4966A81DB40C4300A274BB /* JSDOMPointReadOnly.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMPointReadOnly.cpp; sourceTree = "<group>"; };
    57495749                0F4966A91DB40C4300A274BB /* JSDOMPointReadOnly.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMPointReadOnly.h; sourceTree = "<group>"; };
     5750                0F4CDEAA23D91A8A00251B02 /* ScrollTypes.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollTypes.cpp; sourceTree = "<group>"; };
    57505751                0F53FB81213B1BB800C40D34 /* CSSFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSFilter.cpp; sourceTree = "<group>"; };
    57515752                0F53FB83213B1BB800C40D34 /* CSSFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSFilter.h; sourceTree = "<group>"; };
     
    2608526086                                BC1402880E83680800319717 /* ScrollbarThemeComposite.cpp */,
    2608626087                                BC1402890E83680800319717 /* ScrollbarThemeComposite.h */,
     26088                                0F4CDEAA23D91A8A00251B02 /* ScrollTypes.cpp */,
    2608726089                                93C09C850B0657AA005ABD4D /* ScrollTypes.h */,
    2608826090                                BC2441C30E8B65D00055320F /* ScrollView.cpp */,
  • trunk/Source/WebCore/dom/Element.cpp

    r254890 r255037  
    943943            return;
    944944
    945         window->scrollTo(options);
     945        window->scrollTo(options, clamping);
    946946        return;
    947947    }
  • trunk/Source/WebCore/page/DOMWindow.cpp

    r254890 r255037  
    16991699}
    17001700
    1701 void DOMWindow::scrollTo(const ScrollToOptions& options, ScrollClamping) const
     1701void DOMWindow::scrollTo(const ScrollToOptions& options, ScrollClamping clamping) const
    17021702{
    17031703    if (!isCurrentlyDisplayedInFrame())
     
    17181718
    17191719    IntPoint layoutPos(view->mapFromCSSToLayoutUnits(scrollToOptions.left.value()), view->mapFromCSSToLayoutUnits(scrollToOptions.top.value()));
    1720     view->setContentsScrollPosition(layoutPos);
     1720    view->setContentsScrollPosition(layoutPos, clamping);
    17211721}
    17221722
  • trunk/Source/WebCore/page/FrameView.cpp

    r254890 r255037  
    22802280}
    22812281
    2282 void FrameView::setScrollPosition(const ScrollPosition& scrollPosition)
     2282void FrameView::setScrollPosition(const ScrollPosition& scrollPosition, ScrollClamping clamping)
    22832283{
    22842284    LOG_WITH_STREAM(Scrolling, stream << "FrameView::setScrollPosition " << scrollPosition << " , clearing anchor");
     
    22932293    if (page && page->isMonitoringWheelEvents())
    22942294        scrollAnimator().setWheelEventTestMonitor(page->wheelEventTestMonitor());
    2295     ScrollView::setScrollPosition(scrollPosition);
     2295    ScrollView::setScrollPosition(scrollPosition, clamping);
    22962296
    22972297    setCurrentScrollType(oldScrollType);
     
    26172617}
    26182618
    2619 bool FrameView::requestScrollPositionUpdate(const ScrollPosition& position)
     2619bool FrameView::requestScrollPositionUpdate(const ScrollPosition& position, ScrollType scrollType, ScrollClamping clamping)
    26202620{
    26212621    LOG_WITH_STREAM(Scrolling, stream << "FrameView::requestScrollPositionUpdate " << position);
     
    26292629    if (Page* page = frame().page()) {
    26302630        if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
    2631             return scrollingCoordinator->requestScrollPositionUpdate(*this, position);
     2631            return scrollingCoordinator->requestScrollPositionUpdate(*this, position, scrollType, clamping);
    26322632    }
    26332633#else
  • trunk/Source/WebCore/page/FrameView.h

    r254890 r255037  
    118118    void setNeedsCompositingGeometryUpdate();
    119119
    120     void setViewportConstrainedObjectsNeedLayout();
     120    WEBCORE_EXPORT void setViewportConstrainedObjectsNeedLayout();
    121121
    122122    WEBCORE_EXPORT bool renderedCharactersExceed(unsigned threshold);
     
    224224    WEBCORE_EXPORT void setFixedVisibleContentRect(const IntRect&) final;
    225225#endif
    226     WEBCORE_EXPORT void setScrollPosition(const ScrollPosition&) final;
     226    WEBCORE_EXPORT void setScrollPosition(const ScrollPosition&, ScrollClamping = ScrollClamping::Clamped) final;
    227227    void restoreScrollbar();
    228228    void scheduleScrollToFocusedElement(SelectionRevealMode);
     
    230230    void updateLayerPositionsAfterScrolling() final;
    231231    void updateCompositingLayersAfterScrolling() final;
    232     bool requestScrollPositionUpdate(const ScrollPosition&) final;
     232    bool requestScrollPositionUpdate(const ScrollPosition&, ScrollType = ScrollType::User, ScrollClamping = ScrollClamping::Clamped) final;
    233233    bool isRubberBandInProgress() const final;
    234234    WEBCORE_EXPORT ScrollPosition minimumScrollPosition() const final;
  • trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp

    r251262 r255037  
    231231}
    232232
    233 bool AsyncScrollingCoordinator::requestScrollPositionUpdate(ScrollableArea& scrollableArea, const IntPoint& scrollPosition)
     233bool AsyncScrollingCoordinator::requestScrollPositionUpdate(ScrollableArea& scrollableArea, const IntPoint& scrollPosition, ScrollType scrollType, ScrollClamping clamping)
    234234{
    235235    ASSERT(isMainThread());
     
    252252        updateScrollPositionAfterAsyncScroll(scrollingNodeID, scrollPosition, { }, ScrollType::Programmatic, ScrollingLayerPositionAction::Set);
    253253
     254    ASSERT(inProgrammaticScroll == (scrollType == ScrollType::Programmatic));
     255
    254256    // If this frame view's document is being put into the back/forward cache, we don't want to update our
    255257    // main frame scroll position. Just let the FrameView think that we did.
     
    261263        return false;
    262264
    263     stateNode->setRequestedScrollPosition(scrollPosition, inProgrammaticScroll);
     265    stateNode->setRequestedScrollData({ scrollPosition, scrollType, clamping });
    264266    return true;
    265267}
  • trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h

    r250946 r255037  
    9999    WEBCORE_EXPORT void frameViewEventTrackingRegionsChanged(FrameView&) override;
    100100
    101     WEBCORE_EXPORT bool requestScrollPositionUpdate(ScrollableArea&, const IntPoint&) override;
     101    WEBCORE_EXPORT bool requestScrollPositionUpdate(ScrollableArea&, const IntPoint&, ScrollType, ScrollClamping) override;
    102102
    103103    WEBCORE_EXPORT void applyScrollingTreeLayerPositions() override;
  • trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp

    r251041 r255037  
    499499}
    500500
    501 TextStream& operator<<(TextStream& ts, ScrollType scrollType)
    502 {
    503     switch (scrollType) {
    504     case ScrollType::User: ts << "user"; break;
    505     case ScrollType::Programmatic: ts << "programmatic"; break;
    506     }
    507     return ts;
    508 }
    509 
    510501} // namespace WebCore
  • trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h

    r250946 r255037  
    122122    // These virtual functions are currently unique to the threaded scrolling architecture.
    123123    virtual void commitTreeStateIfNeeded() { }
    124     virtual bool requestScrollPositionUpdate(ScrollableArea&, const IntPoint&) { return false; }
     124    virtual bool requestScrollPositionUpdate(ScrollableArea&, const IntPoint&, ScrollType = ScrollType::Programmatic, ScrollClamping = ScrollClamping::Clamped) { return false; }
    125125    virtual ScrollingEventResult handleWheelEvent(FrameView&, const PlatformWheelEvent&) { return ScrollingEventResult::DidNotHandleEvent; }
    126126
     
    222222WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, ScrollingLayerPositionAction);
    223223WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, ViewportRectStability);
    224 WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, ScrollType);
    225224
    226225} // namespace WebCore
  • trunk/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.cpp

    r250946 r255037  
    4646    , m_parentRelativeScrollableRect(stateNode.parentRelativeScrollableRect())
    4747    , m_scrollPosition(stateNode.scrollPosition())
    48     , m_requestedScrollPosition(stateNode.requestedScrollPosition())
    4948    , m_scrollOrigin(stateNode.scrollOrigin())
    5049#if ENABLE(CSS_SCROLL_SNAP)
     
    5655#endif
    5756    , m_scrollableAreaParameters(stateNode.scrollableAreaParameters())
    58     , m_requestedScrollPositionRepresentsProgrammaticScroll(stateNode.requestedScrollPositionRepresentsProgrammaticScroll())
     57    , m_requestedScrollData(stateNode.requestedScrollData())
    5958    , m_isMonitoringWheelEvents(stateNode.isMonitoringWheelEvents())
    6059{
     
    220219}
    221220
    222 void ScrollingStateScrollingNode::setRequestedScrollPosition(const FloatPoint& requestedScrollPosition, bool representsProgrammaticScroll)
    223 {
    224     m_requestedScrollPosition = requestedScrollPosition;
    225     m_requestedScrollPositionRepresentsProgrammaticScroll = representsProgrammaticScroll;
     221void ScrollingStateScrollingNode::setRequestedScrollData(const RequestedScrollData& scrollData)
     222{
     223    if (scrollData == m_requestedScrollData)
     224        return;
     225
     226    m_requestedScrollData = scrollData;
    226227    setPropertyChanged(RequestedScrollPosition);
    227228}
     
    306307        ts.dumpProperty("reachable contents size", m_reachableContentsSize);
    307308
    308     if (m_requestedScrollPosition != IntPoint()) {
     309    if (!m_requestedScrollData.scrollPosition.isZero()) {
    309310        TextStream::GroupScope scope(ts);
    310311        ts << "requested scroll position "
    311             << TextStream::FormatNumberRespectingIntegers(m_requestedScrollPosition.x()) << " "
    312             << TextStream::FormatNumberRespectingIntegers(m_requestedScrollPosition.y());
    313     }
    314     if (m_requestedScrollPositionRepresentsProgrammaticScroll)
    315         ts.dumpProperty("requested scroll position represents programmatic scroll", m_requestedScrollPositionRepresentsProgrammaticScroll);
     312            << TextStream::FormatNumberRespectingIntegers(m_requestedScrollData.scrollPosition.x()) << " "
     313            << TextStream::FormatNumberRespectingIntegers(m_requestedScrollData.scrollPosition.y());
     314    }
     315    if (m_requestedScrollData.scrollType == ScrollType::Programmatic)
     316        ts.dumpProperty("requested scroll position represents programmatic scroll", true);
     317
     318    if (m_requestedScrollData.clamping == ScrollClamping::Unclamped)
     319        ts.dumpProperty("requested scroll position clamping", m_requestedScrollData.clamping);
    316320
    317321    if (!m_parentRelativeScrollableRect.isEmpty())
  • trunk/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.h

    r250946 r255037  
    3838
    3939namespace WebCore {
     40
     41struct RequestedScrollData {
     42    FloatPoint scrollPosition;
     43    ScrollType scrollType { ScrollType::User };
     44    ScrollClamping clamping { ScrollClamping::Clamped };
     45   
     46    bool operator==(const RequestedScrollData& other) const
     47    {
     48        return scrollPosition == other.scrollPosition
     49            && scrollType == other.scrollType
     50            && clamping == other.clamping;
     51    }
     52};
    4053
    4154class ScrollingStateScrollingNode : public ScrollingStateNode {
     
    110123    WEBCORE_EXPORT void setScrollableAreaParameters(const ScrollableAreaParameters& params);
    111124
    112     const FloatPoint& requestedScrollPosition() const { return m_requestedScrollPosition; }
    113     bool requestedScrollPositionRepresentsProgrammaticScroll() const { return m_requestedScrollPositionRepresentsProgrammaticScroll; }
    114     WEBCORE_EXPORT void setRequestedScrollPosition(const FloatPoint&, bool representsProgrammaticScroll);
     125    const RequestedScrollData& requestedScrollData() const { return m_requestedScrollData; }
     126    WEBCORE_EXPORT void setRequestedScrollData(const RequestedScrollData&);
    115127
    116128    bool isMonitoringWheelEvents() const { return m_isMonitoringWheelEvents; }
     
    150162    LayoutRect m_parentRelativeScrollableRect;
    151163    FloatPoint m_scrollPosition;
    152     FloatPoint m_requestedScrollPosition;
    153164    IntPoint m_scrollOrigin;
    154165
     
    170181
    171182    ScrollableAreaParameters m_scrollableAreaParameters;
     183    RequestedScrollData m_requestedScrollData;
    172184
    173     bool m_requestedScrollPositionRepresentsProgrammaticScroll { false };
    174185    bool m_isMonitoringWheelEvents { false };
    175186};
  • trunk/Source/WebCore/page/scrolling/ScrollingTree.h

    r252742 r255037  
    8484
    8585    // Called for requested scroll position updates.
    86     virtual void scrollingTreeNodeRequestsScroll(ScrollingNodeID, const FloatPoint& /*scrollPosition*/, bool /*representsProgrammaticScroll*/) { }
     86    virtual void scrollingTreeNodeRequestsScroll(ScrollingNodeID, const FloatPoint& /*scrollPosition*/, ScrollType, ScrollClamping) { }
    8787
    8888    // Delegated scrolling/zooming has caused the viewport to change, so update viewport-constrained layers
  • trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.cpp

    r249815 r255037  
    9696}
    9797
    98 FloatRect ScrollingTreeFrameScrollingNode::layoutViewportForScrollPosition(const FloatPoint& visibleContentOrigin, float scale) const
     98FloatRect ScrollingTreeFrameScrollingNode::layoutViewportForScrollPosition(const FloatPoint& visibleContentOrigin, float scale, ScrollBehaviorForFixedElements fixedBehavior) const
    9999{
    100100    FloatSize visualViewportSize = m_overrideVisualViewportSize.valueOr(scrollableAreaSize());
     
    108108    LOG_WITH_STREAM(Scrolling, stream << "  scroll positions: min: " << minLayoutViewportOrigin() << " max: "<< maxLayoutViewportOrigin());
    109109
    110     LayoutPoint newLocation = FrameView::computeLayoutViewportOrigin(LayoutRect(visualViewport), LayoutPoint(minLayoutViewportOrigin()), LayoutPoint(maxLayoutViewportOrigin()), layoutViewport, StickToDocumentBounds);
     110    LayoutPoint newLocation = FrameView::computeLayoutViewportOrigin(LayoutRect(visualViewport), LayoutPoint(minLayoutViewportOrigin()), LayoutPoint(maxLayoutViewportOrigin()), layoutViewport, fixedBehavior);
    111111
    112112    if (layoutViewport.location() != newLocation) {
     
    124124    else
    125125        setLayoutViewport(layoutViewportForScrollPosition(currentScrollPosition(), frameScaleFactor()));
     126}
     127
     128FloatRect ScrollingTreeFrameScrollingNode::layoutViewportRespectingRubberBanding() const
     129{
     130    return layoutViewportForScrollPosition(currentScrollPosition(), frameScaleFactor(), StickToViewportBounds);
    126131}
    127132
  • trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.h

    r247839 r255037  
    4848
    4949    FloatSize viewToContentsOffset(const FloatPoint& scrollPosition) const;
    50     FloatRect layoutViewportForScrollPosition(const FloatPoint& visibleContentOrigin, float scale) const;
    5150
    5251    FloatRect layoutViewport() const { return m_layoutViewport; };
    5352    void setLayoutViewport(const FloatRect& r) { m_layoutViewport = r; };
     53
     54    FloatRect layoutViewportRespectingRubberBanding() const;
    5455
    5556    float frameScaleFactor() const { return m_frameScaleFactor; }
     
    7374    void updateViewportForCurrentScrollPosition(Optional<FloatRect>) override;
    7475    bool scrollPositionAndLayoutViewportMatch(const FloatPoint& position, Optional<FloatRect> overrideLayoutViewport) override;
     76    FloatRect layoutViewportForScrollPosition(const FloatPoint&, float scale, ScrollBehaviorForFixedElements = StickToDocumentBounds) const;
    7577
    7678    void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override;
  • trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp

    r251262 r255037  
    108108{
    109109    const ScrollingStateScrollingNode& scrollingStateNode = downcast<ScrollingStateScrollingNode>(stateNode);
    110     if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition))
    111         scrollingTree().scrollingTreeNodeRequestsScroll(scrollingNodeID(), scrollingStateNode.requestedScrollPosition(), scrollingStateNode.requestedScrollPositionRepresentsProgrammaticScroll());
     110    if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition)) {
     111        const auto& requestedScrollData = scrollingStateNode.requestedScrollData();
     112        scrollingTree().scrollingTreeNodeRequestsScroll(scrollingNodeID(), requestedScrollData.scrollPosition, requestedScrollData.scrollType, requestedScrollData.clamping);
     113    }
    112114
    113115    m_isFirstCommit = false;
     
    145147}
    146148
    147 FloatPoint ScrollingTreeScrollingNode::adjustedScrollPosition(const FloatPoint& scrollPosition, ScrollPositionClamp clamp) const
    148 {
    149     if (clamp == ScrollPositionClamp::ToContentEdges)
     149FloatPoint ScrollingTreeScrollingNode::adjustedScrollPosition(const FloatPoint& scrollPosition, ScrollClamping clamping) const
     150{
     151    if (clamping == ScrollClamping::Clamped)
    150152        return clampScrollPosition(scrollPosition);
    151153
     
    153155}
    154156
    155 void ScrollingTreeScrollingNode::scrollBy(const FloatSize& delta, ScrollPositionClamp clamp)
     157void ScrollingTreeScrollingNode::scrollBy(const FloatSize& delta, ScrollClamping clamp)
    156158{
    157159    scrollTo(currentScrollPosition() + delta, ScrollType::User, clamp);
    158160}
    159161
    160 void ScrollingTreeScrollingNode::scrollTo(const FloatPoint& position, ScrollType scrollType, ScrollPositionClamp clamp)
     162void ScrollingTreeScrollingNode::scrollTo(const FloatPoint& position, ScrollType scrollType, ScrollClamping clamp)
    161163{
    162164    if (position == m_currentScrollPosition)
     
    201203        return;
    202204
    203     m_currentScrollPosition = adjustedScrollPosition(position, ScrollPositionClamp::None);
     205    m_currentScrollPosition = adjustedScrollPosition(position, ScrollClamping::Unclamped);
    204206    updateViewportForCurrentScrollPosition(overrideLayoutViewport);
    205207
  • trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h

    r251262 r255037  
    6161
    6262    // These are imperative; they adjust the scrolling layers.
    63     void scrollTo(const FloatPoint&, ScrollType = ScrollType::User, ScrollPositionClamp = ScrollPositionClamp::ToContentEdges);
    64     void scrollBy(const FloatSize&, ScrollPositionClamp = ScrollPositionClamp::ToContentEdges);
     63    void scrollTo(const FloatPoint&, ScrollType = ScrollType::User, ScrollClamping = ScrollClamping::Clamped);
     64    void scrollBy(const FloatSize&, ScrollClamping = ScrollClamping::Clamped);
    6565
    6666    void wasScrolledByDelegatedScrolling(const FloatPoint& position, Optional<FloatRect> overrideLayoutViewport = { }, ScrollingLayerPositionAction = ScrollingLayerPositionAction::Sync);
     
    100100    FloatPoint clampScrollPosition(const FloatPoint&) const;
    101101   
    102     virtual FloatPoint adjustedScrollPosition(const FloatPoint&, ScrollPositionClamp = ScrollPositionClamp::ToContentEdges) const;
     102    virtual FloatPoint adjustedScrollPosition(const FloatPoint&, ScrollClamping = ScrollClamping::Clamped) const;
    103103
    104104    virtual void currentScrollPositionChanged();
  • trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeFixedNode.mm

    r250491 r255037  
    7878                // Fixed nodes are positioned relative to the containing frame scrolling node.
    7979                // We bail out after finding one.
    80                 auto layoutViewport = downcast<ScrollingTreeFrameScrollingNode>(*ancestor).layoutViewport();
     80                auto layoutViewport = downcast<ScrollingTreeFrameScrollingNode>(*ancestor).layoutViewportRespectingRubberBanding();
    8181                return m_constraints.layerPositionForViewportRect(layoutViewport) - overflowScrollDelta;
    8282            }
  • trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.mm

    r250491 r255037  
    7474        if (is<ScrollingTreeFrameScrollingNode>(scrollingNode)) {
    7575            auto& frameScrollingNode = downcast<ScrollingTreeFrameScrollingNode>(scrollingNode);
    76             constrainingRect = frameScrollingNode.layoutViewport();
     76            constrainingRect = frameScrollingNode.layoutViewportRespectingRubberBanding();
    7777        } else {
    7878            auto& overflowScrollingNode = downcast<ScrollingTreeOverflowScrollingNode>(scrollingNode);
  • trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h

    r251173 r255037  
    6262
    6363private:
    64     FloatPoint adjustedScrollPosition(const FloatPoint&, ScrollPositionClamp) const override;
     64    FloatPoint adjustedScrollPosition(const FloatPoint&, ScrollClamping) const override;
    6565
    6666    void currentScrollPositionChanged() override;
  • trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm

    r251173 r255037  
    138138    // Update the scroll position after child nodes have been updated, because they need to have updated their constraints before any scrolling happens.
    139139    if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition)) {
    140         auto scrollType = scrollingStateNode.requestedScrollPositionRepresentsProgrammaticScroll() ? ScrollType::Programmatic : ScrollType::User;
    141         scrollTo(scrollingStateNode.requestedScrollPosition(), scrollType);
     140        const auto& requestedScrollData = scrollingStateNode.requestedScrollData();
     141        scrollTo(requestedScrollData.scrollPosition, requestedScrollData.scrollType, requestedScrollData.clamping);
    142142    }
    143143
     
    170170}
    171171
    172 FloatPoint ScrollingTreeFrameScrollingNodeMac::adjustedScrollPosition(const FloatPoint& position, ScrollPositionClamp clamp) const
     172FloatPoint ScrollingTreeFrameScrollingNodeMac::adjustedScrollPosition(const FloatPoint& position, ScrollClamping clamp) const
    173173{
    174174    FloatPoint scrollPosition(roundf(position.x()), roundf(position.y()));
  • trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.h

    r242359 r255037  
    4646    void commitStateAfterChildren(const ScrollingStateNode&) override;
    4747   
    48     FloatPoint adjustedScrollPosition(const FloatPoint&, ScrollPositionClamp) const override;
     48    FloatPoint adjustedScrollPosition(const FloatPoint&, ScrollClamping) const override;
    4949
    5050    void repositionScrollingLayers() override;
  • trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm

    r250498 r255037  
    6363
    6464    if (overflowStateNode.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition)) {
    65         auto scrollType = overflowStateNode.requestedScrollPositionRepresentsProgrammaticScroll() ? ScrollType::Programmatic : ScrollType::User;
    66         scrollTo(overflowStateNode.requestedScrollPosition(), scrollType);
     65        const auto& requestedScrollData = overflowStateNode.requestedScrollData();
     66        scrollTo(requestedScrollData.scrollPosition, requestedScrollData.scrollType, requestedScrollData.clamping);
    6767    }
    6868}
     
    8484}
    8585
    86 FloatPoint ScrollingTreeOverflowScrollingNodeMac::adjustedScrollPosition(const FloatPoint& position, ScrollPositionClamp clamp) const
     86FloatPoint ScrollingTreeOverflowScrollingNodeMac::adjustedScrollPosition(const FloatPoint& position, ScrollClamping clamp) const
    8787{
    8888    FloatPoint scrollPosition(roundf(position.x()), roundf(position.y()));
  • trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm

    r251262 r255037  
    236236void ScrollingTreeScrollingNodeDelegateMac::immediateScrollByWithoutContentEdgeConstraints(const FloatSize& offset)
    237237{
    238     scrollingNode().scrollBy(offset, ScrollPositionClamp::None);
     238    scrollingNode().scrollBy(offset, ScrollClamping::Unclamped);
    239239}
    240240
  • trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp

    r250857 r255037  
    9292    // Update the scroll position after child nodes have been updated, because they need to have updated their constraints before any scrolling happens.
    9393    if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition)) {
    94         auto scrollType = scrollingStateNode.requestedScrollPositionRepresentsProgrammaticScroll() ? ScrollType::Programmatic : ScrollType::User;
    95         scrollTo(scrollingStateNode.requestedScrollPosition(), scrollType);
     94        const auto& requestedScrollData = scrollingStateNode.requestedScrollData();
     95        scrollTo(requestedScrollData.scrollPosition, requestedScrollData.scrollType, requestedScrollData.clamping);
    9696    }
    9797}
     
    117117}
    118118
    119 FloatPoint ScrollingTreeFrameScrollingNodeNicosia::adjustedScrollPosition(const FloatPoint& position, ScrollPositionClamp clamp) const
     119FloatPoint ScrollingTreeFrameScrollingNodeNicosia::adjustedScrollPosition(const FloatPoint& position, ScrollClamping clamping) const
    120120{
    121121    FloatPoint scrollPosition(roundf(position.x()), roundf(position.y()));
    122     return ScrollingTreeFrameScrollingNode::adjustedScrollPosition(scrollPosition, clamp);
     122    return ScrollingTreeFrameScrollingNode::adjustedScrollPosition(scrollPosition, clamping);
    123123}
    124124
  • trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.h

    r250420 r255037  
    5454    ScrollingEventResult handleWheelEvent(const PlatformWheelEvent&) override;
    5555
    56     FloatPoint adjustedScrollPosition(const FloatPoint&, ScrollPositionClamp) const override;
     56    FloatPoint adjustedScrollPosition(const FloatPoint&, ScrollClamping) const override;
    5757
    5858    void currentScrollPositionChanged() override;
  • trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.cpp

    r250857 r255037  
    5656    const auto& overflowStateNode = downcast<ScrollingStateOverflowScrollingNode>(stateNode);
    5757    if (overflowStateNode.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition)) {
    58         auto scrollType = overflowStateNode.requestedScrollPositionRepresentsProgrammaticScroll() ? ScrollType::Programmatic : ScrollType::User;
    59         scrollTo(overflowStateNode.requestedScrollPosition(), scrollType);
     58        const auto& requestedScrollData = overflowStateNode.requestedScrollData();
     59        scrollTo(requestedScrollData.scrollPosition, requestedScrollData.scrollType, requestedScrollData.clamping);
    6060    }
    6161}
    6262
    63 FloatPoint ScrollingTreeOverflowScrollingNodeNicosia::adjustedScrollPosition(const FloatPoint& position, ScrollPositionClamp clamp) const
     63FloatPoint ScrollingTreeOverflowScrollingNodeNicosia::adjustedScrollPosition(const FloatPoint& position, ScrollClamping clamping) const
    6464{
    6565    FloatPoint scrollPosition(roundf(position.x()), roundf(position.y()));
    66     return ScrollingTreeOverflowScrollingNode::adjustedScrollPosition(scrollPosition, clamp);
     66    return ScrollingTreeOverflowScrollingNode::adjustedScrollPosition(scrollPosition, clamping);
    6767}
    6868
  • trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.h

    r250489 r255037  
    4545    void commitStateAfterChildren(const ScrollingStateNode&) override;
    4646
    47     FloatPoint adjustedScrollPosition(const FloatPoint&, ScrollPositionClamp) const override;
     47    FloatPoint adjustedScrollPosition(const FloatPoint&, ScrollClamping) const override;
    4848
    4949    void repositionScrollingLayers() override;
  • trunk/Source/WebCore/platform/ScrollTypes.h

    r254890 r255037  
    2929#include <wtf/Assertions.h>
    3030
     31namespace WTF {
     32class TextStream;
     33}
     34
    3135namespace WebCore {
    3236
     
    4852    ScrollInlineDirectionBackward,
    4953    ScrollInlineDirectionForward
    50 };
    51 
    52 enum class ScrollPositionClamp : uint8_t {
    53     None,
    54     ToContentEdges,
    5554};
    5655
     
    230229using ScrollingNodeID = uint64_t;
    231230
     231WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, ScrollType);
     232WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, ScrollClamping);
     233
    232234} // namespace WebCore
  • trunk/Source/WebCore/platform/ScrollView.cpp

    r254890 r255037  
    212212}
    213213
    214 void ScrollView::setContentsScrollPosition(const IntPoint& position)
     214void ScrollView::setContentsScrollPosition(const IntPoint& position, ScrollClamping clamping)
    215215{
    216216#if PLATFORM(IOS_FAMILY)
     
    218218        setActualScrollPosition(position);
    219219#endif
    220     setScrollPosition(position);
     220    setScrollPosition(position, clamping);
    221221}
    222222
     
    519519}
    520520
    521 void ScrollView::setScrollPosition(const ScrollPosition& scrollPosition)
     521void ScrollView::setScrollPosition(const ScrollPosition& scrollPosition, ScrollClamping clamping)
    522522{
    523523    LOG_WITH_STREAM(Scrolling, stream << "ScrollView::setScrollPosition " << scrollPosition);
     
    531531    }
    532532
    533     ScrollPosition newScrollPosition = !delegatesScrolling() ? adjustScrollPositionWithinRange(scrollPosition) : scrollPosition;
     533    ScrollPosition newScrollPosition = (!delegatesScrolling() && clamping == ScrollClamping::Clamped) ? adjustScrollPositionWithinRange(scrollPosition) : scrollPosition;
    534534
    535535    if ((!delegatesScrolling() || currentScrollType() == ScrollType::User) && newScrollPosition == this->scrollPosition())
    536536        return;
    537537
    538     if (requestScrollPositionUpdate(newScrollPosition))
     538    if (requestScrollPositionUpdate(newScrollPosition, currentScrollType(), clamping))
    539539        return;
    540540
  • trunk/Source/WebCore/platform/ScrollView.h

    r254890 r255037  
    235235    // Scroll position used by web-exposed features (has legacy iOS behavior).
    236236    WEBCORE_EXPORT IntPoint contentsScrollPosition() const;
    237     void setContentsScrollPosition(const IntPoint&);
     237    void setContentsScrollPosition(const IntPoint&, ScrollClamping = ScrollClamping::Clamped);
    238238
    239239#if PLATFORM(IOS_FAMILY)
     
    265265
    266266    // Functions for scrolling the view.
    267     virtual void setScrollPosition(const ScrollPosition&);
     267    virtual void setScrollPosition(const ScrollPosition&, ScrollClamping = ScrollClamping::Clamped);
    268268    void scrollBy(const IntSize& s) { return setScrollPosition(scrollPosition() + s); }
    269269
  • trunk/Source/WebCore/platform/ScrollableArea.cpp

    r254890 r255037  
    228228{
    229229    ScrollPosition position = scrollPositionFromOffset(offset);
    230     if (requestScrollPositionUpdate(position))
     230    if (requestScrollPositionUpdate(position, currentScrollType()))
    231231        return;
    232232
  • trunk/Source/WebCore/platform/ScrollableArea.h

    r254890 r255037  
    7474    // returns true, the scrollable area won't actually update the scroll position and instead
    7575    // expect it to happen sometime in the future.
    76     virtual bool requestScrollPositionUpdate(const ScrollPosition&) { return false; }
     76    virtual bool requestScrollPositionUpdate(const ScrollPosition&, ScrollType = ScrollType::User, ScrollClamping = ScrollClamping::Clamped) { return false; }
    7777
    7878    WEBCORE_EXPORT bool handleWheelEvent(const PlatformWheelEvent&);
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r254893 r255037  
    26092609#if ENABLE(ASYNC_SCROLLING)
    26102610    if (ScrollingCoordinator* scrollingCoordinator = page().scrollingCoordinator())
    2611         handled = scrollingCoordinator->requestScrollPositionUpdate(*this, scrollPositionFromOffset(clampedScrollOffset));
     2611        handled = scrollingCoordinator->requestScrollPositionUpdate(*this, scrollPositionFromOffset(clampedScrollOffset), scrollType, clamping);
    26122612#endif
    26132613
  • trunk/Source/WebCore/testing/Internals.cpp

    r254995 r255037  
    17731773
    17741774    element.scrollTo({ x, y }, ScrollClamping::Unclamped);
     1775
     1776    auto& frameView = *document->view();
     1777    frameView.setViewportConstrainedObjectsNeedLayout();
     1778
    17751779    return { };
    17761780}
  • trunk/Source/WebKit/ChangeLog

    r254999 r255037  
    391391        * WebProcess/Cache/WebCacheStorageConnection.cpp:
    392392        (WebKit::WebCacheStorageConnection::updateQuotaBasedOnSpaceUsage):
     393
     3942020-01-22  Simon Fraser  <simon.fraser@apple.com>
     395
     396        Fixed elements no longer stay fixed with elastic overscroll
     397        https://bugs.webkit.org/show_bug.cgi?id=206227
     398        rdar://problem/58707084
     399
     400        Reviewed by Antti Koivisto.
     401
     402        Intended behavior on iOS and macOS is for position:fixed and sticky elements to maintain
     403        their position relative to the view bounds when rubber-banding ("overscrolling"). This broke
     404        some time back. This change restores the correct behavior with the call to layoutViewportRespectingRubberBanding()
     405        in ScrollingTreeFixedNode::applyLayerPositions() and ScrollingTreeStickyNode::computeLayerPosition().
     406        layoutViewportRespectingRubberBanding() computes a layout viewport without clamping.
     407
     408        The rest of the changes are to support testing. internals.unconstrainedScrollTo()
     409        didn't work for main frame scrolling because of scroll position clamping in various places,
     410        so propagate ScrollClamping in more places (and replace the redundant ScrollPositionClamp with ScrollClamping).
     411
     412        "requested scroll position" updates now carry along both clamping and "is programmatic" data, wrapped in a struct
     413        which is passed around the scrolling tree. This allows us to not clamp the scroll position (for testing) in more places.
     414
     415        * Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp:
     416        (ArgumentCoder<ScrollingStateScrollingNode>::encode):
     417        (ArgumentCoder<ScrollingStateScrollingNode>::decode):
     418        (ArgumentCoder<RequestedScrollData>::encode):
     419        (ArgumentCoder<RequestedScrollData>::decode):
     420        (WebKit::dump):
     421        * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp:
     422        (WebKit::RemoteScrollingCoordinatorProxy::scrollingTreeNodeRequestsScroll):
     423        * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h:
     424        * UIProcess/RemoteLayerTree/RemoteScrollingTree.cpp:
     425        (WebKit::RemoteScrollingTree::scrollingTreeNodeRequestsScroll):
     426        * UIProcess/RemoteLayerTree/RemoteScrollingTree.h:
     427        * UIProcess/RemoteLayerTree/ios/ScrollingTreeFrameScrollingNodeRemoteIOS.mm:
     428        (WebKit::ScrollingTreeFrameScrollingNodeRemoteIOS::commitStateAfterChildren):
     429        * UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm:
     430        (WebKit::ScrollingTreeScrollingNodeDelegateIOS::commitStateAfterChildren):
    393431
    3944322020-01-21  Daniel Bates  <dabates@apple.com>
  • trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp

    r254311 r255037  
    3333#include "WebCoreArgumentCoders.h"
    3434#include <WebCore/GraphicsLayer.h>
     35#include <WebCore/ScrollTypes.h>
    3536#include <WebCore/ScrollingStateFixedNode.h>
    3637#include <WebCore/ScrollingStateFrameHostingNode.h>
     
    9192    static void encode(Encoder&, const ScrollingStatePositionedNode&);
    9293    static bool decode(Decoder&, ScrollingStatePositionedNode&);
     94};
     95
     96template<> struct ArgumentCoder<RequestedScrollData> {
     97    static void encode(Encoder&, const RequestedScrollData&);
     98    static bool decode(Decoder&, RequestedScrollData&);
    9399};
    94100
     
    152158#endif
    153159    SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::ScrollableAreaParams, scrollableAreaParameters)
    154     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::RequestedScrollPosition, requestedScrollPosition)
    155     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::RequestedScrollPosition, requestedScrollPositionRepresentsProgrammaticScroll)
     160    SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::RequestedScrollPosition, requestedScrollData)
    156161
    157162    if (node.hasChangedProperty(ScrollingStateScrollingNode::ScrollContainerLayer))
     
    252257#endif
    253258    SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::ScrollableAreaParams, ScrollableAreaParameters, setScrollableAreaParameters);
    254    
    255     if (node.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition)) {
    256         FloatPoint scrollPosition;
    257         if (!decoder.decode(scrollPosition))
    258             return false;
    259 
    260         bool representsProgrammaticScroll;
    261         if (!decoder.decode(representsProgrammaticScroll))
    262             return false;
    263 
    264         node.setRequestedScrollPosition(scrollPosition, representsProgrammaticScroll);
    265     }
     259    SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::RequestedScrollPosition, RequestedScrollData, setRequestedScrollData);
    266260
    267261    if (node.hasChangedProperty(ScrollingStateScrollingNode::ScrollContainerLayer)) {
     
    447441        node.updateConstraints(decodedValue);
    448442    }
     443
     444    return true;
     445}
     446
     447
     448void ArgumentCoder<RequestedScrollData>::encode(Encoder& encoder, const RequestedScrollData& scrollData)
     449{
     450    encoder << scrollData.scrollPosition;
     451    encoder.encodeEnum(scrollData.scrollType);
     452    encoder.encodeEnum(scrollData.clamping);
     453}
     454
     455bool ArgumentCoder<RequestedScrollData>::decode(Decoder& decoder, RequestedScrollData& scrollData)
     456{
     457    if (!decoder.decode(scrollData.scrollPosition))
     458        return false;
     459
     460    if (!decoder.decodeEnum(scrollData.scrollType))
     461        return false;
     462
     463    if (!decoder.decodeEnum(scrollData.clamping))
     464        return false;
    449465
    450466    return true;
     
    608624
    609625    if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition)) {
    610         ts.dumpProperty("requested-scroll-position", node.requestedScrollPosition());
    611         ts.dumpProperty("requested-scroll-position-is-programatic", node.requestedScrollPositionRepresentsProgrammaticScroll());
     626        const auto& requestedScrollData = node.requestedScrollData();
     627        ts.dumpProperty("requested-scroll-position", requestedScrollData.scrollPosition);
     628        ts.dumpProperty("requested-scroll-position-is-programatic", requestedScrollData.scrollType);
     629        ts.dumpProperty("requested-scroll-position-clamping", requestedScrollData.clamping);
    612630    }
    613631
  • trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp

    r254311 r255037  
    229229}
    230230
    231 void RemoteScrollingCoordinatorProxy::scrollingTreeNodeRequestsScroll(ScrollingNodeID scrolledNodeID, const FloatPoint& scrollPosition, bool representsProgrammaticScroll)
     231void RemoteScrollingCoordinatorProxy::scrollingTreeNodeRequestsScroll(ScrollingNodeID scrolledNodeID, const FloatPoint& scrollPosition, ScrollType scrollType, ScrollClamping)
    232232{
    233233    if (scrolledNodeID == rootScrollingNodeID() && m_requestedScrollInfo) {
    234234        m_requestedScrollInfo->requestsScrollPositionUpdate = true;
    235         m_requestedScrollInfo->requestIsProgrammaticScroll = representsProgrammaticScroll;
     235        m_requestedScrollInfo->requestIsProgrammaticScroll = scrollType == ScrollType::Programmatic;
    236236        m_requestedScrollInfo->requestedScrollPosition = scrollPosition;
    237237    }
  • trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h

    r254311 r255037  
    5858    // Inform the web process that the scroll position changed (called from the scrolling tree)
    5959    void scrollingTreeNodeDidScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& newScrollPosition, const Optional<WebCore::FloatPoint>& layoutViewportOrigin, WebCore::ScrollingLayerPositionAction);
    60     void scrollingTreeNodeRequestsScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, bool representsProgrammaticScroll);
     60    void scrollingTreeNodeRequestsScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, WebCore::ScrollType, WebCore::ScrollClamping);
    6161
    6262    WebCore::TrackingType eventTrackingTypeForPoint(const AtomString& eventName, WebCore::IntPoint) const;
  • trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingTree.cpp

    r254311 r255037  
    108108}
    109109
    110 void RemoteScrollingTree::scrollingTreeNodeRequestsScroll(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, bool representsProgrammaticScroll)
     110void RemoteScrollingTree::scrollingTreeNodeRequestsScroll(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, ScrollType scrollType, ScrollClamping clamping)
    111111{
    112     m_scrollingCoordinatorProxy.scrollingTreeNodeRequestsScroll(nodeID, scrollPosition, representsProgrammaticScroll);
     112    m_scrollingCoordinatorProxy.scrollingTreeNodeRequestsScroll(nodeID, scrollPosition, scrollType, clamping);
    113113}
    114114
  • trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingTree.h

    r254311 r255037  
    5353
    5454    void scrollingTreeNodeDidScroll(WebCore::ScrollingTreeScrollingNode&, WebCore::ScrollingLayerPositionAction = WebCore::ScrollingLayerPositionAction::Sync) override;
    55     void scrollingTreeNodeRequestsScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, bool representsProgrammaticScroll) override;
     55    void scrollingTreeNodeRequestsScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, WebCore::ScrollType, WebCore::ScrollClamping) override;
    5656
    5757    void currentSnapPointIndicesDidChange(WebCore::ScrollingNodeID, unsigned horizontal, unsigned vertical) override;
  • trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeFrameScrollingNodeRemoteIOS.mm

    r250491 r255037  
    9090    // Update the scroll position after child nodes have been updated, because they need to have updated their constraints before any scrolling happens.
    9191    if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition)) {
    92         auto scrollType = scrollingStateNode.requestedScrollPositionRepresentsProgrammaticScroll() ? ScrollType::Programmatic : ScrollType::User;
    93         scrollTo(scrollingStateNode.requestedScrollPosition(), scrollType);
     92        const auto& requestedScrollData = scrollingStateNode.requestedScrollData();
     93        scrollTo(requestedScrollData.scrollPosition, requestedScrollData.scrollType, requestedScrollData.clamping);
    9494    }
    9595}
  • trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm

    r250491 r255037  
    300300
    301301    if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition)) {
    302         auto scrollType = scrollingStateNode.requestedScrollPositionRepresentsProgrammaticScroll() ? ScrollType::Programmatic : ScrollType::User;
    303         scrollingNode().scrollTo(scrollingStateNode.requestedScrollPosition(), scrollType);
     302        const auto& requestedScrollData = scrollingStateNode.requestedScrollData();
     303        scrollingNode().scrollTo(requestedScrollData.scrollPosition, requestedScrollData.scrollType, requestedScrollData.clamping);
    304304    }
    305305}
Note: See TracChangeset for help on using the changeset viewer.