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