Changeset 248447 in webkit


Ignore:
Timestamp:
Aug 8, 2019 4:01:25 PM (5 years ago)
Author:
Simon Fraser
Message:

Add to InteractionInformationAtPosition information about whether the element is in a subscrollable region
https://bugs.webkit.org/show_bug.cgi?id=200374
rdar://problem/54095519

Reviewed by Tim Horton.
Source/WebCore:

Add to InteractionInformationAtPosition a ScrollingNodeID which represents the enclosing scrolling
node that affects the targeted element's position. We use this to find a UIScrollView in the UI process.

The entrypoint to finding the enclosing scrolling node is ScrollingCoordinator::scrollableContainerNodeID(),
which calls RenderLayerCompositor::asyncScrollableContainerNodeID() to look for a scrolling ancestor in
the current frame, and then looks for an enclosing scrollable frame, or a scrolling ancestor in
the enclosing frame.

There's a bit of subtlety in RenderLayerCompositor::asyncScrollableContainerNodeID() because if you're asking
for the node that scrolls the renderer, if the renderer itself has a layer and is scrollable, you want
its enclosing scroller.

  • page/scrolling/AsyncScrollingCoordinator.cpp:

(WebCore::AsyncScrollingCoordinator::scrollableContainerNodeID const):

  • page/scrolling/AsyncScrollingCoordinator.h:
  • page/scrolling/ScrollingCoordinator.cpp:

(WebCore::scrollableContainerNodeID const):

  • page/scrolling/ScrollingCoordinator.h:
  • rendering/RenderLayer.h:
  • rendering/RenderLayerCompositor.cpp:

(WebCore::RenderLayerCompositor::asyncScrollableContainerNodeID):

  • rendering/RenderLayerCompositor.h:

Source/WebKit:

Add InteractionInformationAtPosition.containerScrollingNodeID and initialize it in elementPositionInformation()
by asking the scrolling coordinator.

Also add a way to get from a ScrollingNodeID to a UIScrollView to RemoteScrollingCoordinatorProxy,
which gets the scrolling node and asks the delegate for the UIView.

  • Shared/ios/InteractionInformationAtPosition.h:
  • Shared/ios/InteractionInformationAtPosition.mm:

(WebKit::InteractionInformationAtPosition::encode const):
(WebKit::InteractionInformationAtPosition::decode):

  • UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h:
  • UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:

(WebKit::RemoteScrollingCoordinatorProxy::scrollViewForScrollingNodeID const):

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

(WebKit::ScrollingTreeOverflowScrollingNodeIOS::scrollView const):

  • UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h:
  • WebProcess/WebPage/ios/WebPageIOS.mm:

(WebKit::elementPositionInformation):

Location:
trunk/Source
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r248445 r248447  
    378378        (WebCore::WHLSL::EscapedVariableCollector::takeEscapedVariables): Deleted.
    379379        * Modules/webgpu/WHLSL/WHLSLRecursionChecker.cpp:
     380
     3812019-08-08  Simon Fraser  <simon.fraser@apple.com>
     382
     383        Add to InteractionInformationAtPosition information about whether the element is in a subscrollable region
     384        https://bugs.webkit.org/show_bug.cgi?id=200374
     385        rdar://problem/54095519
     386
     387        Reviewed by Tim Horton.
     388
     389        Add to InteractionInformationAtPosition a ScrollingNodeID which represents the enclosing scrolling
     390        node that affects the targeted element's position. We use this to find a UIScrollView in the UI process.
     391       
     392        The entrypoint to finding the enclosing scrolling node is ScrollingCoordinator::scrollableContainerNodeID(),
     393        which calls RenderLayerCompositor::asyncScrollableContainerNodeID() to look for a scrolling ancestor in
     394        the current frame, and then looks for an enclosing scrollable frame, or a scrolling ancestor in
     395        the enclosing frame.
     396       
     397        There's a bit of subtlety in RenderLayerCompositor::asyncScrollableContainerNodeID() because if you're asking
     398        for the node that scrolls the renderer, if the renderer itself has a layer and is scrollable, you want
     399        its enclosing scroller.
     400
     401        * page/scrolling/AsyncScrollingCoordinator.cpp:
     402        (WebCore::AsyncScrollingCoordinator::scrollableContainerNodeID const):
     403        * page/scrolling/AsyncScrollingCoordinator.h:
     404        * page/scrolling/ScrollingCoordinator.cpp:
     405        (WebCore::scrollableContainerNodeID const):
     406        * page/scrolling/ScrollingCoordinator.h:
     407        * rendering/RenderLayer.h:
     408        * rendering/RenderLayerCompositor.cpp:
     409        (WebCore::RenderLayerCompositor::asyncScrollableContainerNodeID):
     410        * rendering/RenderLayerCompositor.h:
    380411
    3814122019-08-07  Saam Barati  <sbarati@apple.com>
  • trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp

    r247839 r248447  
    3838#include "Page.h"
    3939#include "PerformanceLoggingClient.h"
     40#include "RenderLayerCompositor.h"
     41#include "RenderView.h"
    4042#include "ScrollAnimator.h"
    4143#include "ScrollingConstraints.h"
     
    790792}
    791793
     794ScrollingNodeID AsyncScrollingCoordinator::scrollableContainerNodeID(const RenderObject& renderer) const
     795{
     796    if (auto overflowScrollingNodeID = renderer.view().compositor().asyncScrollableContainerNodeID(renderer))
     797        return overflowScrollingNodeID;
     798
     799    // If we're in a scrollable frame, return that.
     800    auto* frameView = renderer.frame().view();
     801    if (!frameView)
     802        return 0;
     803
     804    if (auto scrollingNodeID = frameView->scrollingNodeID())
     805        return scrollingNodeID;
     806
     807    // Otherwise, look for a scrollable element in the containing frame.
     808    if (auto* ownerElement = renderer.document().ownerElement()) {
     809        if (auto* frameRenderer = ownerElement->renderer())
     810            return scrollableContainerNodeID(*frameRenderer);
     811    }
     812
     813    return 0;
     814}
     815
    792816String AsyncScrollingCoordinator::scrollingStateTreeAsText(ScrollingStateTreeAsTextBehavior behavior) const
    793817{
  • trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h

    r247344 r248447  
    9292    bool asyncFrameOrOverflowScrollingEnabled() const;
    9393
     94    WEBCORE_EXPORT ScrollingNodeID scrollableContainerNodeID(const RenderObject&) const override;
     95
    9496    WEBCORE_EXPORT void frameViewLayoutUpdated(FrameView&) override;
    9597    WEBCORE_EXPORT void frameViewRootLayerDidChange(FrameView&) override;
  • trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp

    r247306 r248447  
    9797}
    9898
     99ScrollingNodeID ScrollingCoordinator::scrollableContainerNodeID(const RenderObject&) const
     100{
     101    return 0;
     102}
     103
    99104EventTrackingRegions ScrollingCoordinator::absoluteEventTrackingRegionsForFrame(const Frame& frame) const
    100105{
  • trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h

    r247344 r248447  
    6060class Page;
    6161class Region;
     62class RenderObject;
    6263class RenderLayer;
    6364class ScrollableArea;
     
    8384    // Return whether this scrolling coordinator handles scrolling for the given overflow scroll layer.
    8485    WEBCORE_EXPORT virtual bool coordinatesScrollingForOverflowLayer(const RenderLayer&) const;
     86
     87    // Returns the ScrollingNodeID of the innermost scrolling node that scrolls the renderer.
     88    WEBCORE_EXPORT virtual ScrollingNodeID scrollableContainerNodeID(const RenderObject&) const;
    8589
    8690    // Should be called whenever the given frame view has been laid out.
  • trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp

    r247917 r248447  
    27082708}
    27092709
     2710// Note that this returns the ScrollingNodeID of the scroller this layer is embedded in, not the layer's own ScrollingNodeID if it has one.
     2711ScrollingNodeID RenderLayerCompositor::asyncScrollableContainerNodeID(const RenderObject& renderer)
     2712{
     2713    auto* enclosingLayer = renderer.enclosingLayer();
     2714    if (!enclosingLayer)
     2715        return 0;
     2716   
     2717    auto layerScrollingNodeID = [](const RenderLayer& layer) -> ScrollingNodeID {
     2718        if (layer.isComposited())
     2719            return layer.backing()->scrollingNodeIDForRole(ScrollCoordinationRole::Scrolling);
     2720        return 0;
     2721    };
     2722
     2723    // If the renderer is inside the layer, we care about the layer's scrollability. Otherwise, we let traverseAncestorLayers look at ancestors.
     2724    if (!renderer.hasLayer()) {
     2725        if (auto scrollingNodeID = layerScrollingNodeID(*enclosingLayer))
     2726            return scrollingNodeID;
     2727    }
     2728
     2729    ScrollingNodeID containerScrollingNodeID = 0;
     2730    traverseAncestorLayers(*enclosingLayer, [&](const RenderLayer& ancestorLayer, bool isContainingBlockChain, bool /*isPaintOrderAncestor*/) {
     2731        if (isContainingBlockChain && ancestorLayer.hasCompositedScrollableOverflow()) {
     2732            containerScrollingNodeID = layerScrollingNodeID(ancestorLayer);
     2733            return AncestorTraversal::Stop;
     2734        }
     2735        return AncestorTraversal::Continue;
     2736    });
     2737
     2738    return containerScrollingNodeID;
     2739}
     2740
    27102741// Return true if the given layer is a stacking context and has compositing child
    27112742// layers that it needs to clip. In this case we insert a clipping GraphicsLayer
  • trunk/Source/WebCore/rendering/RenderLayerCompositor.h

    r247246 r248447  
    215215    bool updateAncestorClippingStack(const RenderLayer&, const RenderLayer* compositingAncestor) const;
    216216
     217    // Returns the ScrollingNodeID for the containing async-scrollable layer that scrolls this renderer's border box.
     218    // May return 0 for position-fixed content.
     219    static ScrollingNodeID asyncScrollableContainerNodeID(const RenderObject&);
     220
    217221    // Whether layer's backing needs a graphics layer to clip z-order children of the given layer.
    218222    static bool clipsCompositingDescendants(const RenderLayer&);
  • trunk/Source/WebKit/ChangeLog

    r248444 r248447  
    310310        (-[WKContentView continueContextMenuInteractionWithDataDetectors:]): New method to
    311311        use DataDetectors if possible.
     312
     3132019-08-08  Simon Fraser  <simon.fraser@apple.com>
     314
     315        Add to InteractionInformationAtPosition information about whether the element is in a subscrollable region
     316        https://bugs.webkit.org/show_bug.cgi?id=200374
     317        rdar://problem/54095519
     318
     319        Reviewed by Tim Horton.
     320       
     321        Add InteractionInformationAtPosition.containerScrollingNodeID and initialize it in elementPositionInformation()
     322        by asking the scrolling coordinator.
     323       
     324        Also add a way to get from a ScrollingNodeID to a UIScrollView to RemoteScrollingCoordinatorProxy,
     325        which gets the scrolling node and asks the delegate for the UIView.
     326
     327        * Shared/ios/InteractionInformationAtPosition.h:
     328        * Shared/ios/InteractionInformationAtPosition.mm:
     329        (WebKit::InteractionInformationAtPosition::encode const):
     330        (WebKit::InteractionInformationAtPosition::decode):
     331        * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h:
     332        * UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:
     333        (WebKit::RemoteScrollingCoordinatorProxy::scrollViewForScrollingNodeID const):
     334        * UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.h:
     335        * UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.mm:
     336        (WebKit::ScrollingTreeOverflowScrollingNodeIOS::scrollView const):
     337        * UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h:
     338        * WebProcess/WebPage/ios/WebPageIOS.mm:
     339        (WebKit::elementPositionInformation):
    312340
    3133412019-08-07  Priyanka Agarwal  <pagarwal999@apple.com>
  • trunk/Source/WebKit/Shared/ios/InteractionInformationAtPosition.h

    r246892 r248447  
    3232#include "ShareableBitmap.h"
    3333#include <WebCore/IntPoint.h>
     34#include <WebCore/ScrollTypes.h>
    3435#include <WebCore/SelectionRect.h>
    3536#include <WebCore/TextIndicator.h>
     
    6263    bool isAnimatedImage { false };
    6364    bool isElement { false };
     65    WebCore::ScrollingNodeID containerScrollingNodeID { 0 };
    6466#if ENABLE(DATA_DETECTION)
    6567    bool isDataDetectorLink { false };
  • trunk/Source/WebKit/Shared/ios/InteractionInformationAtPosition.mm

    r246892 r248447  
    5757    encoder << isAnimatedImage;
    5858    encoder << isElement;
     59    encoder << containerScrollingNodeID;
    5960    encoder << adjustedPointForNodeRespondingToClickEvents;
    6061    encoder << url;
     
    126127        return false;
    127128
     129    if (!decoder.decode(result.containerScrollingNodeID))
     130        return false;
     131
    128132    if (!decoder.decode(result.adjustedPointForNodeRespondingToClickEvents))
    129133        return false;
  • trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h

    r246490 r248447  
    3434#include <wtf/Noncopyable.h>
    3535#include <wtf/RefPtr.h>
     36
     37OBJC_CLASS UIScrollView;
    3638
    3739namespace WebCore {
     
    8890
    8991#if PLATFORM(IOS_FAMILY)
     92    UIScrollView *scrollViewForScrollingNodeID(WebCore::ScrollingNodeID) const;
     93
    9094    WebCore::FloatRect currentLayoutViewport() const;
    9195    void scrollingTreeNodeWillStartPanGesture();
  • trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm

    r246962 r248447  
    3232#import "RemoteLayerTreeHost.h"
    3333#import "RemoteLayerTreeNode.h"
     34#import "ScrollingTreeOverflowScrollingNodeIOS.h"
    3435#import "WebPageProxy.h"
    3536#import <UIKit/UIView.h>
     
    5354using namespace WebCore;
    5455
     56UIScrollView *RemoteScrollingCoordinatorProxy::scrollViewForScrollingNodeID(WebCore::ScrollingNodeID nodeID) const
     57{
     58    auto* treeNode = m_scrollingTree->nodeForID(nodeID);
     59    if (!is<ScrollingTreeOverflowScrollingNode>(treeNode))
     60        return nil;
     61
     62    auto* scrollingNode = downcast<ScrollingTreeOverflowScrollingNode>(treeNode);
     63    // All ScrollingTreeOverflowScrollingNodes are ScrollingTreeOverflowScrollingNodeIOS on iOS.
     64    return static_cast<ScrollingTreeOverflowScrollingNodeIOS*>(scrollingNode)->scrollView();
     65}
     66
    5567void RemoteScrollingCoordinatorProxy::connectStateNodeLayers(ScrollingStateTree& stateTree, const RemoteLayerTreeHost& layerTreeHost)
    5668{
  • trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.h

    r243926 r248447  
    3030#include <WebCore/ScrollingTreeOverflowScrollingNode.h>
    3131
     32OBJC_CLASS UIScrollView;
     33
    3234namespace WebKit {
    3335
     
    3840    static Ref<ScrollingTreeOverflowScrollingNodeIOS> create(WebCore::ScrollingTree&, WebCore::ScrollingNodeID);
    3941    virtual ~ScrollingTreeOverflowScrollingNodeIOS();
     42
     43    UIScrollView* scrollView() const;
    4044
    4145private:
  • trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.mm

    r243926 r248447  
    5252}
    5353
     54UIScrollView* ScrollingTreeOverflowScrollingNodeIOS::scrollView() const
     55{
     56    return m_scrollingNodeDelegate->scrollView();
     57}
     58
    5459void ScrollingTreeOverflowScrollingNodeIOS::commitStateBeforeChildren(const WebCore::ScrollingStateNode& stateNode)
    5560{
  • trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h

    r246926 r248447  
    7575
    7676    UIScrollView *findActingScrollParent(UIScrollView *);
     77    UIScrollView *scrollView() const;
    7778
    7879private:
    79     UIScrollView *scrollView() const;
    80 
    8180    RetainPtr<CALayer> m_scrollLayer;
    8281    RetainPtr<CALayer> m_scrolledContentsLayer;
  • trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm

    r248438 r248447  
    26842684    }
    26852685
     2686    auto* elementForScrollTesting = linkElement ? linkElement : &element;
     2687    if (auto* renderer = elementForScrollTesting->renderer()) {
     2688#if ENABLE(ASYNC_SCROLLING)
     2689        if (auto* scrollingCoordinator = page.scrollingCoordinator())
     2690            info.containerScrollingNodeID = scrollingCoordinator->scrollableContainerNodeID(*renderer);
     2691#endif
     2692    }
     2693
    26862694    if (auto* renderer = element.renderer()) {
    26872695        if (renderer->isRenderImage())
Note: See TracChangeset for help on using the changeset viewer.