Changeset 271090 in webkit


Ignore:
Timestamp:
Dec 26, 2020 10:28:39 AM (19 months ago)
Author:
Simon Fraser
Message:

Fix scrolling issues when scrolling on only one axis is enabled
https://bugs.webkit.org/show_bug.cgi?id=220134

Reviewed by Sam Weinig.

Source/WebCore:

If an overflow:scroll has overflow on an axis, but overflow:hidden on that
axis, then there are various issues with finding the correct scroller and
latching.

This affects nested scrollers where inner and outer and scrollable on different
axes, and the inner scroller has overflow, but overflow:hidden on the cross axis.

The fix involves adding checks for scrolling being allowed in code that fetches
pinned state, and code that looks for scrollable areas for a given event delta.

Tests: fast/scrolling/mac/overflow-hidden-on-one-axis-async-overflow.html

fast/scrolling/mac/overflow-hidden-on-one-axis.html

  • page/mac/EventHandlerMac.mm:

(WebCore::findEnclosingScrollableContainer):

  • page/scrolling/ScrollingTreeScrollingNode.cpp:

(WebCore::ScrollingTreeScrollingNode::edgePinnedState const):

  • page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm:

(WebCore::ScrollingTreeScrollingNodeDelegateMac::isPinnedForScrollDeltaOnAxis const):

  • platform/ScrollableArea.cpp:

(WebCore::ScrollableArea::isPinnedForScrollDeltaOnAxis const):
(WebCore::ScrollableArea::isPinnedForScrollDelta const): Check for non-zero deltas.
isPinnedForScrollDeltaOnAxis() returns false if a delta is zero, so we don't want to say
we're not pinned if a delta is zero. The logic of this code really needs to be inverted
to talk about scrollability, not pinning.
(WebCore::ScrollableArea::edgePinnedState const):

LayoutTests:

  • fast/scrolling/mac/overflow-hidden-on-one-axis-async-overflow-expected.txt: Added.
  • fast/scrolling/mac/overflow-hidden-on-one-axis-async-overflow.html: Added.
  • fast/scrolling/mac/overflow-hidden-on-one-axis-expected.txt: Added.
  • fast/scrolling/mac/overflow-hidden-on-one-axis.html: Added.
Location:
trunk
Files:
4 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r271077 r271090  
     12020-12-26  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Fix scrolling issues when scrolling on only one axis is enabled
     4        https://bugs.webkit.org/show_bug.cgi?id=220134
     5
     6        Reviewed by Sam Weinig.
     7
     8        * fast/scrolling/mac/overflow-hidden-on-one-axis-async-overflow-expected.txt: Added.
     9        * fast/scrolling/mac/overflow-hidden-on-one-axis-async-overflow.html: Added.
     10        * fast/scrolling/mac/overflow-hidden-on-one-axis-expected.txt: Added.
     11        * fast/scrolling/mac/overflow-hidden-on-one-axis.html: Added.
     12
    1132020-12-23  Ryan Haddad  <ryanhaddad@apple.com>
    214
  • trunk/Source/WebCore/ChangeLog

    r271089 r271090  
     12020-12-26  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Fix scrolling issues when scrolling on only one axis is enabled
     4        https://bugs.webkit.org/show_bug.cgi?id=220134
     5
     6        Reviewed by Sam Weinig.
     7
     8        If an overflow:scroll has overflow on an axis, but overflow:hidden on that
     9        axis, then there are various issues with finding the correct scroller and
     10        latching.
     11
     12        This affects nested scrollers where inner and outer and scrollable on different
     13        axes, and the inner scroller has overflow, but overflow:hidden on the cross axis.
     14
     15        The fix involves adding checks for scrolling being allowed in code that fetches
     16        pinned state, and code that looks for scrollable areas for a given event delta.
     17
     18        Tests: fast/scrolling/mac/overflow-hidden-on-one-axis-async-overflow.html
     19               fast/scrolling/mac/overflow-hidden-on-one-axis.html
     20
     21        * page/mac/EventHandlerMac.mm:
     22        (WebCore::findEnclosingScrollableContainer):
     23        * page/scrolling/ScrollingTreeScrollingNode.cpp:
     24        (WebCore::ScrollingTreeScrollingNode::edgePinnedState const):
     25        * page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm:
     26        (WebCore::ScrollingTreeScrollingNodeDelegateMac::isPinnedForScrollDeltaOnAxis const):
     27        * platform/ScrollableArea.cpp:
     28        (WebCore::ScrollableArea::isPinnedForScrollDeltaOnAxis const):
     29        (WebCore::ScrollableArea::isPinnedForScrollDelta const): Check for non-zero deltas.
     30        isPinnedForScrollDeltaOnAxis() returns false if a delta is zero, so we don't want to say
     31        we're not pinned if a delta is zero. The logic of this code really needs to be inverted
     32        to talk about scrollability, not pinning.
     33        (WebCore::ScrollableArea::edgePinnedState const):
     34
    1352020-12-26  Sam Weinig  <weinig@apple.com>
    236
  • trunk/Source/WebCore/page/mac/EventHandlerMac.mm

    r270425 r271090  
    820820            return candidate;
    821821
    822         if ((biasedDelta.height() > 0 && !scrollableArea->scrolledToTop()) || (biasedDelta.height() < 0 && !scrollableArea->scrolledToBottom())
    823             || (biasedDelta.width() > 0 && !scrollableArea->scrolledToLeft()) || (biasedDelta.width() < 0 && !scrollableArea->scrolledToRight()))
     822        if (biasedDelta.height() && !scrollableArea->isPinnedForScrollDeltaOnAxis(-biasedDelta.height(), ScrollEventAxis::Vertical))
     823            return candidate;
     824
     825        if (biasedDelta.width() && !scrollableArea->isPinnedForScrollDeltaOnAxis(-biasedDelta.width(), ScrollEventAxis::Horizontal))
    824826            return candidate;
    825827    }
  • trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp

    r271070 r271090  
    199199    auto maxScrollPosition = maximumScrollPosition();
    200200
     201    bool horizontallyUnscrollable = !allowsHorizontalScrolling();
     202    bool verticallyUnscrollable = !allowsVerticalScrolling();
     203
    201204    // Top, right, bottom, left.
    202205    return {
    203         scrollPosition.y() <= minScrollPosition.y(),
    204         scrollPosition.x() >= maxScrollPosition.x(),
    205         scrollPosition.y() >= maxScrollPosition.y(),
    206         scrollPosition.x() <= minScrollPosition.x()
     206        verticallyUnscrollable || scrollPosition.y() <= minScrollPosition.y(),
     207        horizontallyUnscrollable || scrollPosition.x() >= maxScrollPosition.x(),
     208        verticallyUnscrollable || scrollPosition.y() >= maxScrollPosition.y(),
     209        horizontallyUnscrollable || scrollPosition.x() <= minScrollPosition.x()
    207210    };
    208211}
  • trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm

    r271081 r271090  
    221221    switch (axis) {
    222222    case ScrollEventAxis::Vertical:
     223        if (!allowsVerticalScrolling())
     224            return true;
     225
    223226        if (scrollDelta < 0) {
    224227            auto topOffset = scrollPosition.y() - minimumScrollPosition().y();
     
    232235        break;
    233236    case ScrollEventAxis::Horizontal:
     237        if (!allowsHorizontalScrolling())
     238            return true;
     239
    234240        if (scrollDelta < 0) {
    235241            auto leftOffset = scrollPosition.x() - minimumScrollPosition().x();
  • trunk/Source/WebCore/platform/ScrollableArea.cpp

    r271081 r271090  
    635635    switch (axis) {
    636636    case ScrollEventAxis::Vertical:
     637        if (!allowsVerticalScrolling())
     638            return true;
     639
    637640        if (scrollDelta < 0) // top
    638641            return scrollPosition.y() <= minimumScrollPosition().y();
     
    643646        break;
    644647    case ScrollEventAxis::Horizontal:
     648        if (!allowsHorizontalScrolling())
     649            return true;
     650
    645651        if (scrollDelta < 0) // left
    646652            return scrollPosition.x() <= minimumScrollPosition().x();
     
    657663bool ScrollableArea::isPinnedForScrollDelta(const FloatSize& scrollDelta) const
    658664{
    659     return isPinnedForScrollDeltaOnAxis(scrollDelta.width(), ScrollEventAxis::Horizontal) && isPinnedForScrollDeltaOnAxis(scrollDelta.height(), ScrollEventAxis::Vertical);
     665    return (!scrollDelta.width() || isPinnedForScrollDeltaOnAxis(scrollDelta.width(), ScrollEventAxis::Horizontal))
     666        && (!scrollDelta.height() || isPinnedForScrollDeltaOnAxis(scrollDelta.height(), ScrollEventAxis::Vertical));
    660667}
    661668
     
    666673    auto maxScrollPosition = maximumScrollPosition();
    667674
     675    bool horizontallyUnscrollable = !allowsHorizontalScrolling();
     676    bool verticallyUnscrollable = !allowsVerticalScrolling();
     677
    668678    // Top, right, bottom, left.
    669679    return {
    670         scrollPosition.y() <= minScrollPosition.y(),
    671         scrollPosition.x() >= maxScrollPosition.x(),
    672         scrollPosition.y() >= maxScrollPosition.y(),
    673         scrollPosition.x() <= minScrollPosition.x()
     680        verticallyUnscrollable || scrollPosition.y() <= minScrollPosition.y(),
     681        horizontallyUnscrollable || scrollPosition.x() >= maxScrollPosition.x(),
     682        verticallyUnscrollable || scrollPosition.y() >= maxScrollPosition.y(),
     683        horizontallyUnscrollable || scrollPosition.x() <= minScrollPosition.x()
    674684    };
    675685}
Note: See TracChangeset for help on using the changeset viewer.