Title: [246926] trunk/Source/WebKit
Revision
246926
Author
an...@apple.com
Date
2019-06-28 10:12:27 -0700 (Fri, 28 Jun 2019)

Log 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):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (246925 => 246926)


--- trunk/Source/WebKit/ChangeLog	2019-06-28 16:00:17 UTC (rev 246925)
+++ trunk/Source/WebKit/ChangeLog	2019-06-28 17:12:27 UTC (rev 246926)
@@ -1,3 +1,29 @@
+2019-06-28  Antti Koivisto  <an...@apple.com>
+
+        [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):
+
 2019-06-28  Konstantin Tokarev  <annu...@yandex.ru>
 
         Remove traces of ENABLE_ICONDATABASE remaining after its removal in 219733

Modified: trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.h (246925 => 246926)


--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.h	2019-06-28 16:00:17 UTC (rev 246925)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.h	2019-06-28 17:12:27 UTC (rev 246926)
@@ -31,6 +31,7 @@
 #import <WebCore/GraphicsLayer.h>
 
 namespace WebKit {
+class RemoteLayerTreeHost;
 class WebPageProxy;
 }
 
@@ -77,6 +78,7 @@
 #if ENABLE(POINTER_EVENTS)
 OptionSet<WebCore::TouchAction> touchActionsForPoint(UIView *rootView, const WebCore::IntPoint&);
 #endif
+UIScrollView *findActingScrollParent(UIScrollView *, const RemoteLayerTreeHost&);
 
 }
 

Modified: trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm (246925 => 246926)


--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm	2019-06-28 16:00:17 UTC (rev 246925)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm	2019-06-28 17:12:27 UTC (rev 246926)
@@ -124,8 +124,37 @@
 }
 #endif
 
+UIScrollView *findActingScrollParent(UIScrollView *scrollView, const RemoteLayerTreeHost& host)
+{
+    HashSet<WebCore::GraphicsLayer::PlatformLayerID> scrollersToSkip;
+
+    for (UIView *view = [scrollView superview]; view; view = [view superview]) {
+        if ([view isKindOfClass:[WKChildScrollView class]] && !scrollersToSkip.contains(RemoteLayerTreeNode::layerID(view.layer))) {
+            // FIXME: Ideally we would return the scroller we want in all cases but the current UIKit SPI only allows returning a non-ancestor.
+            return nil;
+        }
+
+        if (auto* node = RemoteLayerTreeNode::forCALayer(view.layer)) {
+            switch (node->relatedScrollContainerPositioningBehavior()) {
+            case WebCore::ScrollPositioningBehavior::Moves:
+                if (!node->relatedScrollContainerIDs().isEmpty()) {
+                    if (auto* nonAncestorScrollingNode = host.nodeForID(node->relatedScrollContainerIDs()[0]))
+                        return (WKChildScrollView *)nonAncestorScrollingNode->uiView();
+                }
+                break;
+            case WebCore::ScrollPositioningBehavior::Stationary:
+                scrollersToSkip.add(node->relatedScrollContainerIDs().begin(), node->relatedScrollContainerIDs().end());
+                break;
+            case WebCore::ScrollPositioningBehavior::None:
+                break;
+            }
+        }
+    }
+    return nil;
 }
 
+}
+
 @interface UIView (WKHitTesting)
 - (UIView *)_web_findDescendantViewAtPoint:(CGPoint)point withEvent:(UIEvent *)event;
 @end

Modified: trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h (246925 => 246926)


--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h	2019-06-28 16:00:17 UTC (rev 246925)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h	2019-06-28 17:12:27 UTC (rev 246926)
@@ -73,6 +73,8 @@
     void cancelPointersForGestureRecognizer(UIGestureRecognizer*);
 #endif
 
+    UIScrollView *findActingScrollParent(UIScrollView *);
+
 private:
     UIScrollView *scrollView() const;
 

Modified: trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm (246925 => 246926)


--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm	2019-06-28 16:00:17 UTC (rev 246925)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm	2019-06-28 17:12:27 UTC (rev 246926)
@@ -28,6 +28,7 @@
 
 #if PLATFORM(IOS_FAMILY) && ENABLE(ASYNC_SCROLLING)
 
+#import "RemoteLayerTreeViews.h"
 #import "RemoteScrollingCoordinatorProxy.h"
 #import "RemoteScrollingTree.h"
 #import "UIKitSPI.h"
@@ -61,6 +62,12 @@
     return self;
 }
 
+- (UIScrollView *)_actingParentScrollViewForScrollView:(UIScrollView *)scrollView
+{
+    // An "acting parent" is a non-ancestor scrolling parent. We tell this to UIKit so it can propagate scrolls correctly.
+    return _scrollingTreeNodeDelegate->findActingScrollParent(scrollView);
+}
+
 - (void)scrollViewDidScroll:(UIScrollView *)scrollView
 {
     _scrollingTreeNodeDelegate->scrollViewDidScroll(scrollView.contentOffset, _inUserInteraction);
@@ -338,6 +345,14 @@
     return scrollView;
 }
 
+UIScrollView *ScrollingTreeScrollingNodeDelegateIOS::findActingScrollParent(UIScrollView *scrollView)
+{
+    ASSERT(scrollView == this->scrollView());
+
+    auto& scrollingCoordinatorProxy = downcast<RemoteScrollingTree>(scrollingTree()).scrollingCoordinatorProxy();
+    return WebKit::findActingScrollParent(scrollView, *scrollingCoordinatorProxy.layerTreeHost());
+}
+
 #if ENABLE(POINTER_EVENTS)
 void ScrollingTreeScrollingNodeDelegateIOS::computeActiveTouchActionsForGestureRecognizer(UIGestureRecognizer* gestureRecognizer)
 {
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to