Changeset 246926 in webkit


Ignore:
Timestamp:
Jun 28, 2019 10:12:27 AM (5 years ago)
Author:
Antti Koivisto
Message:

[iOS Scrolling] Propagate scrolls to non-nested UIScrollViews
https://bugs.webkit.org/show_bug.cgi?id=199222

Reviewed by Simon Fraser.

We may generate scrolling hierarchies where the scrolling ancestor of a layer is not
an ancestor in the layer tree. We handle this in most situations but there is still
a problem where a scroller fails to propage scroll to the ancestor when it reaches
the edge.

This patch hooks up a new SPI that allows us to tell UIKit about non-ancestor scrolling
relations and solve this problem.

  • UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.h:
  • UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm:

(WebKit::findActingScrollParent):

  • UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h:
  • UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm:

(-[WKScrollingNodeScrollViewDelegate _actingParentScrollViewForScrollView:]):

Hook into UIKit SPI.

(WebKit::ScrollingTreeScrollingNodeDelegateIOS::findActingScrollParent):

Location:
trunk/Source/WebKit
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r246925 r246926  
     12019-06-28  Antti Koivisto  <antti@apple.com>
     2
     3        [iOS Scrolling] Propagate scrolls to non-nested UIScrollViews
     4        https://bugs.webkit.org/show_bug.cgi?id=199222
     5
     6        Reviewed by Simon Fraser.
     7
     8        We may generate scrolling hierarchies where the scrolling ancestor of a layer is not
     9        an ancestor in the layer tree. We  handle this in most situations but there is still
     10        a problem where a scroller fails to propage scroll to the ancestor when it reaches
     11        the edge.
     12
     13        This patch hooks up a new SPI that allows us to tell UIKit about non-ancestor scrolling
     14        relations and solve this problem.
     15
     16        * UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.h:
     17        * UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm:
     18        (WebKit::findActingScrollParent):
     19        * UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h:
     20        * UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm:
     21        (-[WKScrollingNodeScrollViewDelegate _actingParentScrollViewForScrollView:]):
     22
     23        Hook into UIKit SPI.
     24
     25        (WebKit::ScrollingTreeScrollingNodeDelegateIOS::findActingScrollParent):
     26
    1272019-06-28  Konstantin Tokarev  <annulen@yandex.ru>
    228
  • trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.h

    r244955 r246926  
    3232
    3333namespace WebKit {
     34class RemoteLayerTreeHost;
    3435class WebPageProxy;
    3536}
     
    7879OptionSet<WebCore::TouchAction> touchActionsForPoint(UIView *rootView, const WebCore::IntPoint&);
    7980#endif
     81UIScrollView *findActingScrollParent(UIScrollView *, const RemoteLayerTreeHost&);
    8082
    8183}
  • trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm

    r246892 r246926  
    125125#endif
    126126
     127UIScrollView *findActingScrollParent(UIScrollView *scrollView, const RemoteLayerTreeHost& host)
     128{
     129    HashSet<WebCore::GraphicsLayer::PlatformLayerID> scrollersToSkip;
     130
     131    for (UIView *view = [scrollView superview]; view; view = [view superview]) {
     132        if ([view isKindOfClass:[WKChildScrollView class]] && !scrollersToSkip.contains(RemoteLayerTreeNode::layerID(view.layer))) {
     133            // FIXME: Ideally we would return the scroller we want in all cases but the current UIKit SPI only allows returning a non-ancestor.
     134            return nil;
     135        }
     136
     137        if (auto* node = RemoteLayerTreeNode::forCALayer(view.layer)) {
     138            switch (node->relatedScrollContainerPositioningBehavior()) {
     139            case WebCore::ScrollPositioningBehavior::Moves:
     140                if (!node->relatedScrollContainerIDs().isEmpty()) {
     141                    if (auto* nonAncestorScrollingNode = host.nodeForID(node->relatedScrollContainerIDs()[0]))
     142                        return (WKChildScrollView *)nonAncestorScrollingNode->uiView();
     143                }
     144                break;
     145            case WebCore::ScrollPositioningBehavior::Stationary:
     146                scrollersToSkip.add(node->relatedScrollContainerIDs().begin(), node->relatedScrollContainerIDs().end());
     147                break;
     148            case WebCore::ScrollPositioningBehavior::None:
     149                break;
     150            }
     151        }
     152    }
     153    return nil;
     154}
     155
    127156}
    128157
  • trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h

    r245691 r246926  
    7474#endif
    7575
     76    UIScrollView *findActingScrollParent(UIScrollView *);
     77
    7678private:
    7779    UIScrollView *scrollView() const;
  • trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm

    r246723 r246926  
    2929#if PLATFORM(IOS_FAMILY) && ENABLE(ASYNC_SCROLLING)
    3030
     31#import "RemoteLayerTreeViews.h"
    3132#import "RemoteScrollingCoordinatorProxy.h"
    3233#import "RemoteScrollingTree.h"
     
    6061
    6162    return self;
     63}
     64
     65- (UIScrollView *)_actingParentScrollViewForScrollView:(UIScrollView *)scrollView
     66{
     67    // An "acting parent" is a non-ancestor scrolling parent. We tell this to UIKit so it can propagate scrolls correctly.
     68    return _scrollingTreeNodeDelegate->findActingScrollParent(scrollView);
    6269}
    6370
     
    339346}
    340347
     348UIScrollView *ScrollingTreeScrollingNodeDelegateIOS::findActingScrollParent(UIScrollView *scrollView)
     349{
     350    ASSERT(scrollView == this->scrollView());
     351
     352    auto& scrollingCoordinatorProxy = downcast<RemoteScrollingTree>(scrollingTree()).scrollingCoordinatorProxy();
     353    return WebKit::findActingScrollParent(scrollView, *scrollingCoordinatorProxy.layerTreeHost());
     354}
     355
    341356#if ENABLE(POINTER_EVENTS)
    342357void ScrollingTreeScrollingNodeDelegateIOS::computeActiveTouchActionsForGestureRecognizer(UIGestureRecognizer* gestureRecognizer)
Note: See TracChangeset for help on using the changeset viewer.