Changeset 288777 in webkit


Ignore:
Timestamp:
Jan 28, 2022 6:56:40 PM (6 months ago)
Author:
Nikos Mouchtaris
Message:

Implement CSS overscroll-behavior for asynchronous scroll on Mac
https://bugs.webkit.org/show_bug.cgi?id=220139

Reviewed by Simon Fraser.

Source/WebCore:

Split up patch by Cathie Chen and Frederic Wang. Add function for blocking scroll chaining
and filtering scroll delta depending on the values of overscroll behavior for a scrolling
node. This patch is for asynchronous scrolling only.

Tests: fast/scrolling/mac/async-overscroll-behavior-element.html

fast/scrolling/mac/async-overscroll-behavior-iframe.html
fast/scrolling/mac/async-overscroll-behavior-unscrollable-element.html
fast/scrolling/mac/async-overscroll-behavior-unscrollable-iframe.html

  • page/scrolling/ScrollingTree.cpp:

(WebCore::ScrollingTree::shouldBlockScrollChainingWithNode):
(WebCore::ScrollingTree::handleWheelEventWithNode):

  • page/scrolling/ScrollingTree.h:
  • page/scrolling/ScrollingTreeScrollingNode.h:
  • page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm:

(WebCore::ScrollingTreeScrollingNodeDelegateMac::allowsHorizontalStretching const):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::allowsVerticalStretching const):

  • rendering/RenderLayerCompositor.cpp:

(WebCore::recompositeChangeRequiresGeometryUpdate):
(WebCore::RenderLayerCompositor::rootOrBodyStyleChanged):

  • rendering/style/RenderStyle.cpp:

(WebCore::RenderStyle::changeRequiresRecompositeLayer const):

LayoutTests:

  • fast/scrolling/mac/async-overscroll-behavior-element-expected.txt: Added.
  • fast/scrolling/mac/async-overscroll-behavior-element.html: Added.
  • fast/scrolling/mac/async-overscroll-behavior-iframe-expected.txt: Added.
  • fast/scrolling/mac/async-overscroll-behavior-iframe.html: Added.
  • fast/scrolling/mac/async-overscroll-behavior-unscrollable-element-expected.txt: Added.
  • fast/scrolling/mac/async-overscroll-behavior-unscrollable-element.html: Added.
  • fast/scrolling/mac/async-overscroll-behavior-unscrollable-iframe-expected.txt: Added.
  • fast/scrolling/mac/async-overscroll-behavior-unscrollable-iframe.html: Added.
  • fast/scrolling/resources/overscroll-behavior-support.js: Added.

(getDeltas):
(async mouseWheelScrollAndWait):

Location:
trunk
Files:
9 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r288775 r288777  
     12022-01-28  Nikolaos Mouchtaris  <nmouchtaris@apple.com>
     2
     3        Implement CSS overscroll-behavior for asynchronous scroll on Mac
     4        https://bugs.webkit.org/show_bug.cgi?id=220139
     5
     6        Reviewed by Simon Fraser.
     7
     8        * fast/scrolling/mac/async-overscroll-behavior-element-expected.txt: Added.
     9        * fast/scrolling/mac/async-overscroll-behavior-element.html: Added.
     10        * fast/scrolling/mac/async-overscroll-behavior-iframe-expected.txt: Added.
     11        * fast/scrolling/mac/async-overscroll-behavior-iframe.html: Added.
     12        * fast/scrolling/mac/async-overscroll-behavior-unscrollable-element-expected.txt: Added.
     13        * fast/scrolling/mac/async-overscroll-behavior-unscrollable-element.html: Added.
     14        * fast/scrolling/mac/async-overscroll-behavior-unscrollable-iframe-expected.txt: Added.
     15        * fast/scrolling/mac/async-overscroll-behavior-unscrollable-iframe.html: Added.
     16        * fast/scrolling/resources/overscroll-behavior-support.js: Added.
     17        (getDeltas):
     18        (async mouseWheelScrollAndWait):
     19
    1202022-01-28  Robert Jenner  <Jenner@apple.com>
    221
  • trunk/Source/WebCore/ChangeLog

    r288774 r288777  
     12022-01-28  Nikolaos Mouchtaris  <nmouchtaris@apple.com>
     2
     3        Implement CSS overscroll-behavior for asynchronous scroll on Mac
     4        https://bugs.webkit.org/show_bug.cgi?id=220139
     5
     6        Reviewed by Simon Fraser.
     7
     8        Split up patch by Cathie Chen and Frederic Wang. Add function for blocking scroll chaining
     9        and filtering scroll delta depending on the values of overscroll behavior for a scrolling
     10        node. This patch is for asynchronous scrolling only.
     11
     12        Tests: fast/scrolling/mac/async-overscroll-behavior-element.html
     13               fast/scrolling/mac/async-overscroll-behavior-iframe.html
     14               fast/scrolling/mac/async-overscroll-behavior-unscrollable-element.html
     15               fast/scrolling/mac/async-overscroll-behavior-unscrollable-iframe.html
     16
     17        * page/scrolling/ScrollingTree.cpp:
     18        (WebCore::ScrollingTree::shouldBlockScrollChainingWithNode):
     19        (WebCore::ScrollingTree::handleWheelEventWithNode):
     20        * page/scrolling/ScrollingTree.h:
     21        * page/scrolling/ScrollingTreeScrollingNode.h:
     22        * page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm:
     23        (WebCore::ScrollingTreeScrollingNodeDelegateMac::allowsHorizontalStretching const):
     24        (WebCore::ScrollingTreeScrollingNodeDelegateMac::allowsVerticalStretching const):
     25        * rendering/RenderLayerCompositor.cpp:
     26        (WebCore::recompositeChangeRequiresGeometryUpdate):
     27        (WebCore::RenderLayerCompositor::rootOrBodyStyleChanged):
     28        * rendering/style/RenderStyle.cpp:
     29        (WebCore::RenderStyle::changeRequiresRecompositeLayer const):
     30
    1312022-01-28  Tyler Wilcock  <tyler_w@apple.com>
    232
  • trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp

    r286351 r288777  
    788788
    789789    ScrollableAreaParameters scrollParameters;
    790     scrollParameters.horizontalScrollElasticity = scrollableArea.horizontalScrollElasticity();
    791     scrollParameters.verticalScrollElasticity = scrollableArea.verticalScrollElasticity();
     790    scrollParameters.horizontalScrollElasticity = scrollableArea.horizontalOverscrollBehavior() == OverscrollBehavior::None ? ScrollElasticity::None : scrollableArea.horizontalScrollElasticity();
     791    scrollParameters.verticalScrollElasticity = scrollableArea.verticalOverscrollBehavior() == OverscrollBehavior::None ? ScrollElasticity::None : scrollableArea.verticalScrollElasticity();
    792792    scrollParameters.allowsHorizontalScrolling = scrollableArea.allowsHorizontalScrolling();
    793793    scrollParameters.allowsVerticalScrolling = scrollableArea.allowsVerticalScrolling();
  • trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp

    r286411 r288777  
    3232#include "Logging.h"
    3333#include "PlatformWheelEvent.h"
     34#include "ScrollingEffectsController.h"
    3435#include "ScrollingStateFrameScrollingNode.h"
    3536#include "ScrollingStateTree.h"
     
    202203WheelEventHandlingResult ScrollingTree::handleWheelEventWithNode(const PlatformWheelEvent& wheelEvent, OptionSet<WheelEventProcessingSteps> processingSteps, ScrollingTreeNode* node, EventTargeting eventTargeting)
    203204{
     205    auto adjustedWheelEvent = wheelEvent;
    204206    while (node) {
    205207        if (is<ScrollingTreeScrollingNode>(*node)) {
    206208            auto& scrollingNode = downcast<ScrollingTreeScrollingNode>(*node);
    207             auto result = scrollingNode.handleWheelEvent(wheelEvent, eventTargeting);
     209            auto result = scrollingNode.handleWheelEvent(adjustedWheelEvent, eventTargeting);
    208210
    209211            if (result.wasHandled) {
    210                 m_latchingController.nodeDidHandleEvent(scrollingNode.scrollingNodeID(), processingSteps, wheelEvent, m_allowLatching);
    211                 m_gestureState.nodeDidHandleEvent(scrollingNode.scrollingNodeID(), wheelEvent);
     212                m_latchingController.nodeDidHandleEvent(scrollingNode.scrollingNodeID(), processingSteps, adjustedWheelEvent, m_allowLatching);
     213                m_gestureState.nodeDidHandleEvent(scrollingNode.scrollingNodeID(), adjustedWheelEvent);
    212214                return result;
    213215            }
     
    215217            if (result.needsMainThreadProcessing() || eventTargeting != EventTargeting::Propagate)
    216218                return result;
     219           
     220            if (scrollingNode.shouldBlockScrollPropagation(adjustedWheelEvent.delta())) {
     221                m_latchingController.nodeDidHandleEvent(scrollingNode.scrollingNodeID(), processingSteps, adjustedWheelEvent, m_allowLatching);
     222                m_gestureState.nodeDidHandleEvent(scrollingNode.scrollingNodeID(), adjustedWheelEvent);
     223                return WheelEventHandlingResult::handled();
     224            }
     225            adjustedWheelEvent = scrollingNode.eventForPropagation(adjustedWheelEvent);
    217226        }
    218227
  • trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp

    r287739 r288777  
    3333#include "ScrollingStateFrameScrollingNode.h"
    3434#endif
     35#include "ScrollingEffectsController.h"
    3536#include "ScrollingStateScrollingNode.h"
    3637#include "ScrollingStateTree.h"
     
    122123}
    123124
     125bool ScrollingTreeScrollingNode::shouldRubberBand(const PlatformWheelEvent& wheelEvent, EventTargeting eventTargeting) const
     126{
     127    // We always rubber-band the latched node, or the root node.
     128    // The stateless wheel event doesn't trigger rubber-band.
     129    // Also rubberband when we should block scroll propagation
     130    // at this node, which has overscroll behavior that is not none.
     131    return (isLatchedNode() || eventTargeting == EventTargeting::NodeOnly || (isRootNode() && !wheelEvent.isNonGestureEvent()) || (shouldBlockScrollPropagation(wheelEvent.delta()) && overscrollBehaviorAllowRubberBand()));
     132}
     133
    124134bool ScrollingTreeScrollingNode::canHandleWheelEvent(const PlatformWheelEvent& wheelEvent, EventTargeting eventTargeting) const
    125135{
     
    131141        return true;
    132142
    133     // We always rubber-band the latched node, or the root node.
    134     // The stateless wheel event doesn't trigger rubber-band.
    135     if (isLatchedNode() || eventTargeting == EventTargeting::NodeOnly || (isRootNode() && !wheelEvent.isNonGestureEvent()))
     143    if (shouldRubberBand(wheelEvent, eventTargeting))
    136144        return true;
    137145
     
    393401}
    394402
     403PlatformWheelEvent ScrollingTreeScrollingNode::eventForPropagation(const PlatformWheelEvent& wheelEvent) const
     404{
     405    auto filteredDelta = wheelEvent.delta();
     406#if PLATFORM(MAC)
     407    auto biasedDelta = ScrollingEffectsController::wheelDeltaBiasingTowardsVertical(wheelEvent);
     408#else
     409    auto biasedDelta = wheelEvent.delta();
     410#endif
     411    if (horizontalOverscrollBehaviorPreventsPropagation() || verticalOverscrollBehaviorPreventsPropagation()) {
     412        if(horizontalOverscrollBehaviorPreventsPropagation() || (verticalOverscrollBehaviorPreventsPropagation() && !biasedDelta.width()))
     413           filteredDelta.setWidth(0);
     414        if(verticalOverscrollBehaviorPreventsPropagation() || (horizontalOverscrollBehaviorPreventsPropagation() && !biasedDelta.height()))
     415           filteredDelta.setHeight(0);
     416        return wheelEvent.copyWithDeltaAndVelocity(filteredDelta, wheelEvent.scrollingVelocity());
     417    }
     418    return wheelEvent;
     419}
     420
     421bool ScrollingTreeScrollingNode::shouldBlockScrollPropagation(const FloatSize& delta) const
     422{
     423    return ((horizontalOverscrollBehaviorPreventsPropagation() || verticalOverscrollBehaviorPreventsPropagation()) && ((horizontalOverscrollBehaviorPreventsPropagation() && verticalOverscrollBehaviorPreventsPropagation()) || (horizontalOverscrollBehaviorPreventsPropagation() && !delta.height()) || (verticalOverscrollBehaviorPreventsPropagation() && !delta.width())));
     424}
     425
    395426} // namespace WebCore
    396427
  • trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h

    r287739 r288777  
    160160    bool allowsHorizontalScrolling() const { return m_scrollableAreaParameters.allowsHorizontalScrolling; }
    161161    bool allowsVerticalScrolling() const { return m_scrollableAreaParameters.allowsVerticalScrolling; }
    162 
     162    OverscrollBehavior horizontalOverscrollBehavior() const { return m_scrollableAreaParameters.horizontalOverscrollBehavior; }
     163    OverscrollBehavior verticalOverscrollBehavior() const { return m_scrollableAreaParameters.verticalOverscrollBehavior; }
     164    bool horizontalOverscrollBehaviorPreventsPropagation() const { return m_scrollableAreaParameters.horizontalOverscrollBehavior != OverscrollBehavior::Auto; }
     165    bool verticalOverscrollBehaviorPreventsPropagation() const { return m_scrollableAreaParameters.verticalOverscrollBehavior != OverscrollBehavior::Auto; }
     166    PlatformWheelEvent eventForPropagation(const PlatformWheelEvent&) const;
     167    bool shouldBlockScrollPropagation(const FloatSize&) const;
     168    bool overscrollBehaviorAllowRubberBand() const { return m_scrollableAreaParameters.horizontalOverscrollBehavior != OverscrollBehavior::None ||  m_scrollableAreaParameters.verticalOverscrollBehavior != OverscrollBehavior::None; }
     169    bool shouldRubberBand(const PlatformWheelEvent&, EventTargeting) const;
    163170    void dumpProperties(WTF::TextStream&, OptionSet<ScrollingStateTreeAsTextBehavior>) const override;
    164171
  • trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp

    r288067 r288777  
    16521652        || oldStyle.offsetDistance() != newStyle.offsetDistance()
    16531653        || oldStyle.offsetRotate() != newStyle.offsetRotate()
    1654         || !arePointingToEqualData(oldStyle.clipPath(), newStyle.clipPath());
     1654        || !arePointingToEqualData(oldStyle.clipPath(), newStyle.clipPath())
     1655        || oldStyle.overscrollBehaviorX() != newStyle.overscrollBehaviorX()
     1656        || oldStyle.overscrollBehaviorY() != newStyle.overscrollBehaviorY();
    16551657}
    16561658
     
    39453947    if (hadFixedBackground != renderer.style().hasEntirelyFixedBackground())
    39463948        rootLayerConfigurationChanged();
     3949   
     3950    if (oldStyle && (oldStyle->overscrollBehaviorX() != renderer.style().overscrollBehaviorX() || oldStyle->overscrollBehaviorY() != renderer.style().overscrollBehaviorY())) {
     3951        if (auto* layer = m_renderView.layer())
     3952            layer->setNeedsCompositingGeometryUpdate();
     3953    }
    39473954}
    39483955
  • trunk/Source/WebCore/rendering/style/RenderStyle.cpp

    r288627 r288777  
    11901190            || m_rareNonInheritedData->perspective != other.m_rareNonInheritedData->perspective
    11911191            || m_rareNonInheritedData->perspectiveOriginX != other.m_rareNonInheritedData->perspectiveOriginX
    1192             || m_rareNonInheritedData->perspectiveOriginY != other.m_rareNonInheritedData->perspectiveOriginY)
     1192            || m_rareNonInheritedData->perspectiveOriginY != other.m_rareNonInheritedData->perspectiveOriginY
     1193            || m_rareNonInheritedData->overscrollBehaviorX != other.m_rareNonInheritedData->overscrollBehaviorX
     1194            || m_rareNonInheritedData->overscrollBehaviorY != other.m_rareNonInheritedData->overscrollBehaviorY)
    11931195            return true;
    11941196    }
Note: See TracChangeset for help on using the changeset viewer.