RESOLVED FIXED 222968
Implement CSS overscroll-behavior for synchronous scroll
https://bugs.webkit.org/show_bug.cgi?id=222968
Summary Implement CSS overscroll-behavior for synchronous scroll
cathiechen
Reported 2021-03-09 03:47:30 PST
Support CSS property overscroll-behavior for synchronous scroll.
Attachments
Patch (59.57 KB, patch)
2021-03-09 03:51 PST, cathiechen
no flags
Patch (59.42 KB, patch)
2021-03-15 06:04 PDT, cathiechen
no flags
Patch (59.56 KB, patch)
2021-03-15 06:19 PDT, cathiechen
no flags
Patch (60.84 KB, patch)
2021-03-15 22:43 PDT, cathiechen
no flags
Patch (61.87 KB, patch)
2021-03-18 03:34 PDT, cathiechen
no flags
Patch (60.39 KB, patch)
2021-03-22 08:38 PDT, cathiechen
no flags
Patch (60.29 KB, patch)
2021-03-24 10:59 PDT, cathiechen
no flags
Patch (34.72 KB, patch)
2021-12-02 16:57 PST, Nikos Mouchtaris
no flags
Patch (37.86 KB, patch)
2021-12-03 14:02 PST, Nikos Mouchtaris
ews-feeder: commit-queue-
Patch (37.86 KB, patch)
2021-12-03 14:15 PST, Nikos Mouchtaris
no flags
Patch (38.07 KB, patch)
2021-12-08 17:25 PST, Nikos Mouchtaris
no flags
Patch (39.78 KB, patch)
2021-12-09 14:39 PST, Nikos Mouchtaris
no flags
Patch (39.65 KB, patch)
2021-12-10 13:53 PST, Nikos Mouchtaris
no flags
Patch (38.69 KB, patch)
2021-12-10 15:35 PST, Nikos Mouchtaris
no flags
Patch (17.07 KB, patch)
2022-01-28 17:51 PST, Nikos Mouchtaris
no flags
Patch (36.83 KB, patch)
2022-01-28 21:09 PST, Nikos Mouchtaris
ews-feeder: commit-queue-
Patch (36.87 KB, patch)
2022-01-28 21:55 PST, Nikos Mouchtaris
ews-feeder: commit-queue-
Patch (37.69 KB, patch)
2022-01-28 23:04 PST, Nikos Mouchtaris
simon.fraser: review+
ews-feeder: commit-queue-
Patch (35.52 KB, patch)
2022-02-02 12:46 PST, Nikos Mouchtaris
ews-feeder: commit-queue-
Patch (35.75 KB, patch)
2022-02-02 12:57 PST, Nikos Mouchtaris
ews-feeder: commit-queue-
Patch (39.01 KB, patch)
2022-02-02 23:35 PST, Nikos Mouchtaris
no flags
cathiechen
Comment 1 2021-03-09 03:51:11 PST
cathiechen
Comment 2 2021-03-15 06:04:20 PDT
cathiechen
Comment 3 2021-03-15 06:19:20 PDT
cathiechen
Comment 4 2021-03-15 22:43:27 PDT
Radar WebKit Bug Importer
Comment 5 2021-03-16 04:48:17 PDT
cathiechen
Comment 6 2021-03-18 03:34:11 PDT
cathiechen
Comment 7 2021-03-22 08:38:30 PDT
cathiechen
Comment 8 2021-03-22 20:36:36 PDT
Comment on attachment 423886 [details] Patch I think overscroll-behahvior of sync scroll is ready to review:)
cathiechen
Comment 9 2021-03-24 10:59:54 PDT
Nikos Mouchtaris
Comment 10 2021-12-02 16:57:24 PST
Nikos Mouchtaris
Comment 11 2021-12-03 14:02:04 PST
Nikos Mouchtaris
Comment 12 2021-12-03 14:15:43 PST
Nikos Mouchtaris
Comment 13 2021-12-08 17:25:25 PST
Simon Fraser (smfr)
Comment 14 2021-12-09 11:20:33 PST
Comment on attachment 446466 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=446466&action=review > Source/WebCore/page/EventHandler.cpp:2922 > +static bool shouldBlockScrollChainingWithScrollableArea(const ScrollableArea* scrollableArea, FloatSize& biasedDelta) I don't like "scroll chaining". > Source/WebCore/page/EventHandler.cpp:2930 > + biasedDelta.setWidth(scrollableArea->horizontalOverscrollBehavior()!= OverscrollBehavior::Auto ? 0 : biasedDelta.width()); > + biasedDelta.setHeight(scrollableArea->verticalOverscrollBehavior()!= OverscrollBehavior::Auto ? 0 : biasedDelta.height()); Spacing here. > Source/WebCore/page/EventHandler.cpp:2943 > + if (frameView && (frameView->horizontalOverscrollBehavior() != OverscrollBehavior::Auto || frameView->verticalOverscrollBehavior() != OverscrollBehavior::Auto)) { > + if (frameView->horizontalOverscrollBehavior() != OverscrollBehavior::Auto && !biasedDelta.height() && biasedDelta.width()) > + return true; > + if ((frameView->horizontalOverscrollBehavior() != OverscrollBehavior::Auto && frameView->verticalOverscrollBehavior() != OverscrollBehavior::Auto) || (frameView->horizontalOverscrollBehavior()!= OverscrollBehavior::Auto && !biasedDelta.height()) || (frameView->verticalOverscrollBehavior()!= OverscrollBehavior::Auto && !biasedDelta.width())) > + return true; > + biasedDelta.setWidth(frameView->horizontalOverscrollBehavior()!= OverscrollBehavior::Auto ? 0 : biasedDelta.width()); > + biasedDelta.setHeight(frameView->verticalOverscrollBehavior()!= OverscrollBehavior::Auto ? 0 : biasedDelta.height()); There are so many "horizontalOverscrollBehavior() != OverscrollBehavior::Auto" checks in this code. Maybe add a helper function that makes this more readable. > Source/WebCore/page/EventHandler.cpp:3064 > + adjustedWheelEvent = adjustedWheelEvent.copyWithDeltaAndVelocity(filteredDelta, adjustedWheelEvent.scrollingVelocity()); > + handledEvent = processWheelEventForScrolling(adjustedWheelEvent, scrollableArea, handling); > + processWheelEventForScrollSnap(adjustedWheelEvent, scrollableArea); I find it odd that this main thread code implements overscroll behavior by zeroing out the deltas on the events, but the scrolling thread code does it by cutting of the ancestor node traversal. Let's be consistent.
Nikos Mouchtaris
Comment 15 2021-12-09 14:39:45 PST
Jon Lee
Comment 16 2021-12-10 12:29:36 PST
Comment on attachment 446608 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=446608&action=review > Source/WebCore/page/EventHandler.cpp:3127 > + if (boxScrollableArea->horizontalOverscrollBehavior() != OverscrollBehavior::Auto && !filteredPlatformDelta.height()) can this use hasHorizontalOverscrollBehavior? > Source/WebCore/page/mac/EventHandlerMac.mm:818 > + if ((scrollableArea->horizontalOverscrollBehavior() != OverscrollBehavior::Auto && scrollableArea->verticalOverscrollBehavior() != OverscrollBehavior::Auto) || (scrollableArea->horizontalOverscrollBehavior() != OverscrollBehavior::Auto && !wheelEvent.delta().height()) || (scrollableArea->verticalOverscrollBehavior() != OverscrollBehavior::Auto && !wheelEvent.delta().width())) can this use has{Horizontal,Vertical}OverscrollBehavior?
Jon Lee
Comment 17 2021-12-10 12:29:37 PST
Comment on attachment 446608 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=446608&action=review > Source/WebCore/page/EventHandler.cpp:3127 > + if (boxScrollableArea->horizontalOverscrollBehavior() != OverscrollBehavior::Auto && !filteredPlatformDelta.height()) can this use hasHorizontalOverscrollBehavior? > Source/WebCore/page/mac/EventHandlerMac.mm:818 > + if ((scrollableArea->horizontalOverscrollBehavior() != OverscrollBehavior::Auto && scrollableArea->verticalOverscrollBehavior() != OverscrollBehavior::Auto) || (scrollableArea->horizontalOverscrollBehavior() != OverscrollBehavior::Auto && !wheelEvent.delta().height()) || (scrollableArea->verticalOverscrollBehavior() != OverscrollBehavior::Auto && !wheelEvent.delta().width())) can this use has{Horizontal,Vertical}OverscrollBehavior?
Nikos Mouchtaris
Comment 18 2021-12-10 13:53:42 PST
Nikos Mouchtaris
Comment 19 2021-12-10 13:57:03 PST
(In reply to Simon Fraser (smfr) from comment #14) > Comment on attachment 446466 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=446466&action=review > > > Source/WebCore/page/EventHandler.cpp:3064 > > + adjustedWheelEvent = adjustedWheelEvent.copyWithDeltaAndVelocity(filteredDelta, adjustedWheelEvent.scrollingVelocity()); > > + handledEvent = processWheelEventForScrolling(adjustedWheelEvent, scrollableArea, handling); > > + processWheelEventForScrollSnap(adjustedWheelEvent, scrollableArea); > > I find it odd that this main thread code implements overscroll behavior by > zeroing out the deltas on the events, but the scrolling thread code does it > by cutting of the ancestor node traversal. Let's be consistent. The traversal is getting cut off in EventHandler::handleWheelEventInAppropriateEnclosingBox based on the result of shouldBlockScrollPropogationWithScrollableArea.
Simon Fraser (smfr)
Comment 20 2021-12-10 14:16:12 PST
Comment on attachment 446805 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=446805&action=review > Source/WebCore/page/EventHandler.cpp:2922 > +static bool shouldBlockScrollPropogationWithScrollableArea(const ScrollableArea* scrollableArea, FloatSize& biasedDelta) "Propogation" Maybe this should be a function on ScrollableArea? And can we find out how to do this without having to modify event deltas?
Nikos Mouchtaris
Comment 21 2021-12-10 15:35:05 PST
Nikos Mouchtaris
Comment 22 2021-12-10 15:37:30 PST
(In reply to Simon Fraser (smfr) from comment #20) > Comment on attachment 446805 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=446805&action=review > > > Source/WebCore/page/EventHandler.cpp:2922 > > +static bool shouldBlockScrollPropogationWithScrollableArea(const ScrollableArea* scrollableArea, FloatSize& biasedDelta) > > "Propogation" > > Maybe this should be a function on ScrollableArea? And can we find out how > to do this without having to modify event deltas? I think we have to modify the deltas for the case where we are only blocking in one direction, we have to zero out the delta for that direction.
Simon Fraser (smfr)
Comment 23 2022-01-28 16:38:22 PST
Comment on attachment 446830 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=446830&action=review > Source/WebCore/page/EventHandler.cpp:3029 > + PlatformWheelEvent adjustedWheelEvent = PlatformWheelEvent(event); auto > Source/WebCore/page/EventHandler.cpp:3057 > + FloatSize filteredDelta(wheelEvent.deltaX(), wheelEvent.deltaY()); auto filteredDelta = wheelEvent.delta() > Source/WebCore/page/EventHandler.cpp:3058 > + scrollableArea.shouldBlockScrollPropagation(filteredDelta); That looks like a no-op until you notice that shouldBlockScrollPropagation() modifies the delta. Can we apply the same cleanup we did in bug 220139? > Source/WebCore/page/EventHandler.cpp:3096 > + FloatSize biasedDelta(wheelEvent.deltaX(), wheelEvent.deltaY()); auto biasedDelta = .... > Source/WebCore/platform/ScrollableArea.cpp:811 > +bool ScrollableArea::shouldBlockScrollPropagation(FloatSize& biasedDelta) const This code should be changed to be more similar to the async structure (separate out the question from the modification). > LayoutTests/fast/scrolling/sync-scroll-overscroll-behavior-element.html:1 > +<!doctype html> Same comments about these tests as in bug 220139.
Nikos Mouchtaris
Comment 24 2022-01-28 17:51:10 PST
Simon Fraser (smfr)
Comment 25 2022-01-28 20:33:47 PST
Comment on attachment 450298 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=450298&action=review I'd like to see one more round. Also, we need to test this code path. You need some tests that either don't have async overflow scroll enabled. > Source/WebCore/page/EventHandler.cpp:3103 > + if (boxScrollableArea->hasHorizontalOverscrollBehavior() && !filteredPlatformDelta.height()) Need ScrollableArea::horizontalOverscrollBehaviorPreventsPropagation() etc just like the async code path. Again here, the lack of symmetry between vertical and horizontal is confusing. > Source/WebCore/page/FrameView.h:706 > + bool hasHorizontalOverscrollBehavior() const final { return horizontalOverscrollBehavior() != OverscrollBehavior::Auto; } > + bool hasVerticalOverscrollBehavior() const final { return verticalOverscrollBehavior() != OverscrollBehavior::Auto; } Can't these live on ScrollableArea? > Source/WebCore/page/mac/EventHandlerMac.mm:819 > + if ((scrollableArea->hasHorizontalOverscrollBehavior() && scrollableArea->hasVerticalOverscrollBehavior()) || (scrollableArea->hasHorizontalOverscrollBehavior() && !wheelEvent.delta().height()) || (scrollableArea->hasVerticalOverscrollBehavior() && !wheelEvent.delta().width())) > + return nullptr; I feel like this could be wrapped up a helper called something like overscrollBehaviorPreventsScrollPropagation(FloatSize delta). Also it should use horizontalOverscrollBehaviorPreventsPropagation() terminology. > Source/WebCore/platform/ScrollableArea.cpp:821 > +bool ScrollableArea::shouldBlockScrollPropagation(const FloatSize& biasedDelta) const Oh it's here. Why didn't EventHandlerMac call this? > Source/WebCore/platform/ScrollableArea.h:375 > + virtual bool hasHorizontalOverscrollBehavior() const { return false; } > + virtual bool hasVerticalOverscrollBehavior() const { return false; } horizontalOverscrollBehaviorPreventsPropagation etc > Source/WebCore/rendering/RenderLayer.cpp:2312 > +// ASSERT_UNUSED(foundAncestor, foundAncestor); Why? Also you can't land this.
Nikos Mouchtaris
Comment 26 2022-01-28 21:09:47 PST
Nikos Mouchtaris
Comment 27 2022-01-28 21:55:55 PST
Nikos Mouchtaris
Comment 28 2022-01-28 23:04:25 PST
Simon Fraser (smfr)
Comment 29 2022-02-01 13:58:51 PST
Comment on attachment 450319 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=450319&action=review I'd still like the tests to be rewritten. > Source/WebCore/page/FrameView.h:706 > + bool horizontalOverscrollBehaviorPreventsPropagation() const final { return horizontalOverscrollBehavior() != OverscrollBehavior::Auto; } > + bool verticalOverscrollBehaviorPreventsPropagation() const final { return verticalOverscrollBehavior() != OverscrollBehavior::Auto; } Why aren't these just on the base class? horizontalOverscrollBehavior() is virtual, so this doesn't need to be. > Source/WebCore/page/mac/EventHandlerMac.mm:819 > + if (scrollableArea->shouldBlockScrollPropagation(wheelEvent.delta())) > + return nullptr; Is this the right place to call this, allowing a "over scroll-behavior: contain" scroller to rubberband? > Source/WebCore/platform/ScrollableArea.cpp:822 > + return ((horizontalOverscrollBehaviorPreventsPropagation() || verticalOverscrollBehaviorPreventsPropagation()) && ((horizontalOverscrollBehaviorPreventsPropagation() && verticalOverscrollBehaviorPreventsPropagation()) || (horizontalOverscrollBehaviorPreventsPropagation() && !biasedDelta.height()) || (verticalOverscrollBehaviorPreventsPropagation() && !biasedDelta.width()))); I'd wrap this line more. > Source/WebCore/platform/ScrollableArea.h:378 > + virtual bool horizontalOverscrollBehaviorPreventsPropagation() const { return false; } > + virtual bool verticalOverscrollBehaviorPreventsPropagation() const { return false; } Can't these just be: bool horizontalOverscrollBehaviorPreventsPropagation() const { return horizontalOverscrollBehavior() != OverscrollBehavior::Auto; } bool verticalOverscrollBehaviorPreventsPropagation() const { return verticalOverscrollBehavior() != OverscrollBehavior::Auto; } > Source/WebCore/rendering/RenderLayerScrollableArea.h:241 > + bool horizontalOverscrollBehaviorPreventsPropagation() const final { return horizontalOverscrollBehavior() != OverscrollBehavior::Auto; } > + bool verticalOverscrollBehaviorPreventsPropagation() const final { return verticalOverscrollBehavior() != OverscrollBehavior::Auto; } And you can remove these. > LayoutTests/platform/ios/TestExpectations:821 > +# Overscroll-behavior is not supported on iOS yet: https://bugs.webkit.org/show_bug.cgi?id=233788 > +fast/scrolling/sync-scroll-overscroll-behavior-element.html [ Skip ] > +fast/scrolling/sync-scroll-overscroll-behavior-iframe.html [ Skip ] > +fast/scrolling/sync-scroll-overscroll-behavior-unscrollable-element.html [ Skip ] > +fast/scrolling/sync-scroll-overscroll-behavior-unscrollable-iframe.html [ Skip ] Not true any more.
Nikos Mouchtaris
Comment 30 2022-02-02 12:46:52 PST
Nikos Mouchtaris
Comment 31 2022-02-02 12:57:30 PST
Nikos Mouchtaris
Comment 32 2022-02-02 13:01:37 PST
(In reply to Simon Fraser (smfr) from comment #29) > Comment on attachment 450319 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=450319&action=review > > I'd still like the tests to be rewritten. Tracked in https://bugs.webkit.org/show_bug.cgi?id=235847. > > > Source/WebCore/page/FrameView.h:706 > > + bool horizontalOverscrollBehaviorPreventsPropagation() const final { return horizontalOverscrollBehavior() != OverscrollBehavior::Auto; } > > + bool verticalOverscrollBehaviorPreventsPropagation() const final { return verticalOverscrollBehavior() != OverscrollBehavior::Auto; } > > Why aren't these just on the base class? horizontalOverscrollBehavior() is > virtual, so this doesn't need to be. > Fixed. > > Source/WebCore/page/mac/EventHandlerMac.mm:819 > > + if (scrollableArea->shouldBlockScrollPropagation(wheelEvent.delta())) > > + return nullptr; > > Is this the right place to call this, allowing a "over scroll-behavior: > contain" scroller to rubberband? Added similar code to async in handleWheelEventInAppropriateEnclosingBox to allow node to handle rubber banding. > > > Source/WebCore/platform/ScrollableArea.cpp:822 > > + return ((horizontalOverscrollBehaviorPreventsPropagation() || verticalOverscrollBehaviorPreventsPropagation()) && ((horizontalOverscrollBehaviorPreventsPropagation() && verticalOverscrollBehaviorPreventsPropagation()) || (horizontalOverscrollBehaviorPreventsPropagation() && !biasedDelta.height()) || (verticalOverscrollBehaviorPreventsPropagation() && !biasedDelta.width()))); > > I'd wrap this line more. > Fixed. > > Source/WebCore/platform/ScrollableArea.h:378 > > + virtual bool horizontalOverscrollBehaviorPreventsPropagation() const { return false; } > > + virtual bool verticalOverscrollBehaviorPreventsPropagation() const { return false; } > > Can't these just be: > > bool horizontalOverscrollBehaviorPreventsPropagation() const { return > horizontalOverscrollBehavior() != OverscrollBehavior::Auto; } > bool verticalOverscrollBehaviorPreventsPropagation() const { return > verticalOverscrollBehavior() != OverscrollBehavior::Auto; } Fixed. > > > Source/WebCore/rendering/RenderLayerScrollableArea.h:241 > > + bool horizontalOverscrollBehaviorPreventsPropagation() const final { return horizontalOverscrollBehavior() != OverscrollBehavior::Auto; } > > + bool verticalOverscrollBehaviorPreventsPropagation() const final { return verticalOverscrollBehavior() != OverscrollBehavior::Auto; } > > And you can remove these. Fixed. > > > LayoutTests/platform/ios/TestExpectations:821 > > +# Overscroll-behavior is not supported on iOS yet: https://bugs.webkit.org/show_bug.cgi?id=233788 > > +fast/scrolling/sync-scroll-overscroll-behavior-element.html [ Skip ] > > +fast/scrolling/sync-scroll-overscroll-behavior-iframe.html [ Skip ] > > +fast/scrolling/sync-scroll-overscroll-behavior-unscrollable-element.html [ Skip ] > > +fast/scrolling/sync-scroll-overscroll-behavior-unscrollable-iframe.html [ Skip ] > > Not true any more. Fixed.
Simon Fraser (smfr)
Comment 33 2022-02-02 13:11:55 PST
Comment on attachment 450692 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=450692&action=review > Source/WebCore/platform/ScrollableArea.h:379 > + bool overscrollBehaviorAllowRubberBand() const { return horizontalOverscrollBehavior() != OverscrollBehavior::None || verticalOverscrollBehavior() != OverscrollBehavior::None; } overscrollBehaviorAllowRubberBand -> overscrollBehaviorAllowsRubberBand
Nikos Mouchtaris
Comment 34 2022-02-02 23:35:19 PST
EWS
Comment 35 2022-02-03 13:33:56 PST
Committed r289074 (246780@main): <https://commits.webkit.org/246780@main> All reviewed patches have been landed. Closing bug and clearing flags on attachment 450737 [details].
Note You need to log in before you can comment on or make changes to this bug.