Changeset 221753 in webkit


Ignore:
Timestamp:
Sep 7, 2017 1:21:12 PM (7 years ago)
Author:
commit-queue@webkit.org
Message:

Move more code from ScrollingTreeScrollingNodeDelegateIOS to ScrollingTreeScrollingNodeDelegate
https://bugs.webkit.org/show_bug.cgi?id=174130

Reviewed by Simon Fraser.

  • UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.h: Remove some members, headers and pre-declaration that are moved into the delegate. (WebKit::ScrollingTreeOverflowScrollingNodeIOS::scrollLayer): Deleted.
  • UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.mm: Remove some headers and WKOverflowScrollViewDelegate since they are moved into the delegate file. Also fix the comment to closing the WebKit namespace. (WebKit::ScrollingTreeOverflowScrollingNodeIOS::~ScrollingTreeOverflowScrollingNodeIOS): Remove some code moved into the delegate and call the corresponding helper function to preserve the current behavior. (WebKit::ScrollingTreeOverflowScrollingNodeIOS::commitStateBeforeChildren): Ditto. Note that it is only necessary to cast the parameter to a ScrollingStateTreeNode. (WebKit::ScrollingTreeOverflowScrollingNodeIOS::commitStateAfterChildren): Ditto. (WebKit::ScrollingTreeOverflowScrollingNodeIOS::updateLayersAfterAncestorChange): Ditto. (WebKit::ScrollingTreeOverflowScrollingNodeIOS::scrollPosition): Ditto. (WebKit::ScrollingTreeOverflowScrollingNodeIOS::setScrollLayerPosition): Ditto. (-[WKOverflowScrollViewDelegate initWithScrollingTreeNodeDelegate:]): Deleted. (-[WKOverflowScrollViewDelegate scrollViewDidScroll:]): Deleted. (-[WKOverflowScrollViewDelegate scrollViewWillBeginDragging:]): Deleted. (-[WKOverflowScrollViewDelegate scrollViewWillEndDragging:withVelocity:targetContentOffset:]): Deleted. (-[WKOverflowScrollViewDelegate scrollViewDidEndDragging:willDecelerate:]): Deleted. (-[WKOverflowScrollViewDelegate scrollViewDidEndDecelerating:]): Deleted.
  • UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h: Import headers and members from ScrollingTreeOverflowScrollingNodeIOS. Define new helper functions for the code imported from ScrollingTreeOverflowScrollingNodeIOS. Remove the friendship with ScrollingTreeOverflowScrollingNodeIOS and only makes public the function used by that class. (WebKit::ScrollingTreeScrollingNodeDelegateIOS::scrollLayer): This function is moved from ScrollingTreeOverflowScrollingNodeIOS.
  • UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm: Add headers, WKOverflowScrollViewDelegate (renamed WKScrollingNodeScrollViewDelegate) and some helper code imported from ScrollingTreeOverflowScrollingNodeIOS. (-[WKScrollingNodeScrollViewDelegate scrollViewDidScroll:]): Moved from ScrollingTreeOverflowScrollingNodeIOS. (-[WKScrollingNodeScrollViewDelegate scrollViewWillBeginDragging:]): Ditto. (-[WKScrollingNodeScrollViewDelegate scrollViewWillEndDragging:withVelocity:targetContentOffset:]): Ditto. (-[WKScrollingNodeScrollViewDelegate scrollViewDidEndDragging:willDecelerate:]): Ditto. (-[WKScrollingNodeScrollViewDelegate scrollViewDidEndDecelerating:]): Ditto. (WebKit::ScrollingTreeScrollingNodeDelegateIOS::~ScrollingTreeScrollingNodeDelegateIOS): Import code from ScrollingTreeOverflowScrollingNodeIOS. (WebKit::ScrollingTreeScrollingNodeDelegateIOS::resetScrollViewDelegate): New helper function importing code from ScrollingTreeOverflowScrollingNodeIOS. (WebKit::ScrollingTreeScrollingNodeDelegateIOS::commitStateBeforeChildren): Ditto. (WebKit::ScrollingTreeScrollingNodeDelegateIOS::commitStateAfterChildren): Ditto. (WebKit::ScrollingTreeScrollingNodeDelegateIOS::updateLayersAfterAncestorChange): Ditto. (WebKit::ScrollingTreeScrollingNodeDelegateIOS::scrollPosition): Ditto. (WebKit::ScrollingTreeScrollingNodeDelegateIOS::setScrollLayerPosition): Ditto.

Patch by Frederic Wang <fwang@igalia.com> on 2017-09-07

Location:
trunk/Source
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNodeDelegate.cpp

    r221669 r221753  
    5252}
    5353
     54const FloatSize& ScrollingTreeScrollingNodeDelegate::totalContentsSize()
     55{
     56    return m_scrollingNode.totalContentsSize();
     57}
     58
     59const FloatSize& ScrollingTreeScrollingNodeDelegate::reachableContentsSize()
     60{
     61    return m_scrollingNode.reachableContentsSize();
     62}
     63
     64const IntPoint& ScrollingTreeScrollingNodeDelegate::scrollOrigin() const
     65{
     66    return m_scrollingNode.scrollOrigin();
     67}
     68
    5469} // namespace WebCore
    5570
  • trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNodeDelegate.h

    r221669 r221753  
    3131
    3232class FloatPoint;
     33class FloatSize;
     34class IntPoint;
    3335class ScrollingTreeScrollingNode;
    3436class ScrollingTree;
     
    4446    WEBCORE_EXPORT ScrollingTree& scrollingTree() const;
    4547    WEBCORE_EXPORT FloatPoint lastCommittedScrollPosition() const;
     48    WEBCORE_EXPORT const FloatSize& totalContentsSize();
     49    WEBCORE_EXPORT const FloatSize& reachableContentsSize();
     50    WEBCORE_EXPORT const IntPoint& scrollOrigin() const;
    4651
    4752private:
  • trunk/Source/WebKit/ChangeLog

    r221749 r221753  
     12017-09-07  Frederic Wang  <fwang@igalia.com>
     2
     3         Move more code from ScrollingTreeScrollingNodeDelegateIOS to ScrollingTreeScrollingNodeDelegate
     4         https://bugs.webkit.org/show_bug.cgi?id=174130
     5
     6         Reviewed by Simon Fraser.
     7
     8         * UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.h: Remove some members,
     9         headers and pre-declaration that are moved into the delegate.
     10         (WebKit::ScrollingTreeOverflowScrollingNodeIOS::scrollLayer): Deleted.
     11         * UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.mm: Remove some headers and
     12         WKOverflowScrollViewDelegate since they are moved into the delegate file. Also fix the
     13         comment to closing the WebKit namespace.
     14         (WebKit::ScrollingTreeOverflowScrollingNodeIOS::~ScrollingTreeOverflowScrollingNodeIOS):
     15         Remove some code moved into the delegate and call the corresponding helper function to
     16         preserve the current behavior.
     17         (WebKit::ScrollingTreeOverflowScrollingNodeIOS::commitStateBeforeChildren): Ditto.
     18         Note that it is only necessary to cast the parameter to a ScrollingStateTreeNode.
     19         (WebKit::ScrollingTreeOverflowScrollingNodeIOS::commitStateAfterChildren): Ditto.
     20         (WebKit::ScrollingTreeOverflowScrollingNodeIOS::updateLayersAfterAncestorChange): Ditto.
     21         (WebKit::ScrollingTreeOverflowScrollingNodeIOS::scrollPosition): Ditto.
     22         (WebKit::ScrollingTreeOverflowScrollingNodeIOS::setScrollLayerPosition): Ditto.
     23         (-[WKOverflowScrollViewDelegate initWithScrollingTreeNodeDelegate:]): Deleted.
     24         (-[WKOverflowScrollViewDelegate scrollViewDidScroll:]): Deleted.
     25         (-[WKOverflowScrollViewDelegate scrollViewWillBeginDragging:]): Deleted.
     26         (-[WKOverflowScrollViewDelegate scrollViewWillEndDragging:withVelocity:targetContentOffset:]): Deleted.
     27         (-[WKOverflowScrollViewDelegate scrollViewDidEndDragging:willDecelerate:]): Deleted.
     28         (-[WKOverflowScrollViewDelegate scrollViewDidEndDecelerating:]): Deleted.
     29         * UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h: Import headers and members
     30         from ScrollingTreeOverflowScrollingNodeIOS. Define new helper functions for the code imported
     31         from ScrollingTreeOverflowScrollingNodeIOS. Remove the friendship with
     32         ScrollingTreeOverflowScrollingNodeIOS and only makes public the function used by that class.
     33         (WebKit::ScrollingTreeScrollingNodeDelegateIOS::scrollLayer): This function is moved from
     34         ScrollingTreeOverflowScrollingNodeIOS.
     35         * UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm: Add headers,
     36         WKOverflowScrollViewDelegate (renamed WKScrollingNodeScrollViewDelegate) and some helper code
     37         imported from ScrollingTreeOverflowScrollingNodeIOS.
     38         (-[WKScrollingNodeScrollViewDelegate scrollViewDidScroll:]): Moved from
     39         ScrollingTreeOverflowScrollingNodeIOS.
     40         (-[WKScrollingNodeScrollViewDelegate scrollViewWillBeginDragging:]): Ditto.
     41         (-[WKScrollingNodeScrollViewDelegate scrollViewWillEndDragging:withVelocity:targetContentOffset:]): Ditto.
     42         (-[WKScrollingNodeScrollViewDelegate scrollViewDidEndDragging:willDecelerate:]): Ditto.
     43         (-[WKScrollingNodeScrollViewDelegate scrollViewDidEndDecelerating:]): Ditto.
     44         (WebKit::ScrollingTreeScrollingNodeDelegateIOS::~ScrollingTreeScrollingNodeDelegateIOS):
     45         Import code from ScrollingTreeOverflowScrollingNodeIOS.
     46         (WebKit::ScrollingTreeScrollingNodeDelegateIOS::resetScrollViewDelegate): New helper function
     47         importing code from ScrollingTreeOverflowScrollingNodeIOS.
     48         (WebKit::ScrollingTreeScrollingNodeDelegateIOS::commitStateBeforeChildren): Ditto.
     49         (WebKit::ScrollingTreeScrollingNodeDelegateIOS::commitStateAfterChildren): Ditto.
     50         (WebKit::ScrollingTreeScrollingNodeDelegateIOS::updateLayersAfterAncestorChange): Ditto.
     51         (WebKit::ScrollingTreeScrollingNodeDelegateIOS::scrollPosition): Ditto.
     52         (WebKit::ScrollingTreeScrollingNodeDelegateIOS::setScrollLayerPosition): Ditto.
     53
    1542017-09-07  Chris Dumez  <cdumez@apple.com>
    255
  • trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.h

    r221669 r221753  
    2828#if ENABLE(ASYNC_SCROLLING) && PLATFORM(IOS)
    2929
    30 #include <WebCore/ScrollingCoordinator.h>
    3130#include <WebCore/ScrollingTreeOverflowScrollingNode.h>
    32 
    33 OBJC_CLASS CALayer;
    34 OBJC_CLASS WKOverflowScrollViewDelegate;
    3531
    3632namespace WebKit {
     
    4238    static Ref<ScrollingTreeOverflowScrollingNodeIOS> create(WebCore::ScrollingTree&, WebCore::ScrollingNodeID);
    4339    virtual ~ScrollingTreeOverflowScrollingNodeIOS();
    44 
    45     CALayer *scrollLayer() const { return m_scrollLayer.get(); }
    4640
    4741private:
     
    6256    void handleWheelEvent(const WebCore::PlatformWheelEvent&) override { }
    6357
    64     RetainPtr<CALayer> m_scrollLayer;
    65     RetainPtr<CALayer> m_scrolledContentsLayer;
    66 
    67     RetainPtr<WKOverflowScrollViewDelegate> m_scrollViewDelegate;
    6858    std::unique_ptr<ScrollingTreeScrollingNodeDelegateIOS> m_scrollingNodeDelegate;
    6959};
  • trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.mm

    r221669 r221753  
    3030#if ENABLE(ASYNC_SCROLLING)
    3131
    32 #import <QuartzCore/QuartzCore.h>
    33 #import <UIKit/UIPanGestureRecognizer.h>
    34 #import <UIKit/UIScrollView.h>
    35 #import <WebCore/ScrollingStateOverflowScrollingNode.h>
    36 #import <WebCore/ScrollingTree.h>
    37 #import <wtf/BlockObjCExceptions.h>
    38 #import <wtf/SetForScope.h>
    39 
    40 #if ENABLE(CSS_SCROLL_SNAP)
    41 #import <WebCore/AxisScrollSnapOffsets.h>
    42 #import <WebCore/ScrollSnapOffsetsInfo.h>
    43 #endif
    44 
    4532#import "ScrollingTreeScrollingNodeDelegateIOS.h"
    4633
     34#import <WebCore/ScrollingStateOverflowScrollingNode.h>
     35
    4736using namespace WebCore;
    48 
    49 @interface WKOverflowScrollViewDelegate : NSObject <UIScrollViewDelegate> {
    50     WebKit::ScrollingTreeScrollingNodeDelegateIOS* _scrollingTreeNodeDelegate;
    51 }
    52 
    53 @property (nonatomic, getter=_isInUserInteraction) BOOL inUserInteraction;
    54 
    55 - (instancetype)initWithScrollingTreeNodeDelegate:(WebKit::ScrollingTreeScrollingNodeDelegateIOS*)delegate;
    56 
    57 @end
    58 
    59 @implementation WKOverflowScrollViewDelegate
    60 
    61 - (instancetype)initWithScrollingTreeNodeDelegate:(WebKit::ScrollingTreeScrollingNodeDelegateIOS*)delegate
    62 {
    63     if ((self = [super init]))
    64         _scrollingTreeNodeDelegate = delegate;
    65 
    66     return self;
    67 }
    68 
    69 - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    70 {
    71     _scrollingTreeNodeDelegate->scrollViewDidScroll(scrollView.contentOffset, _inUserInteraction);
    72 }
    73 
    74 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
    75 {
    76     _inUserInteraction = YES;
    77 
    78     if (scrollView.panGestureRecognizer.state == UIGestureRecognizerStateBegan)
    79         _scrollingTreeNodeDelegate->scrollViewWillStartPanGesture();
    80     _scrollingTreeNodeDelegate->scrollWillStart();
    81 }
    82 
    83 #if ENABLE(CSS_SCROLL_SNAP)
    84 - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
    85 {
    86     CGFloat horizontalTarget = targetContentOffset->x;
    87     CGFloat verticalTarget = targetContentOffset->y;
    88 
    89     unsigned originalHorizontalSnapPosition = _scrollingTreeNodeDelegate->scrollingNode().currentHorizontalSnapPointIndex();
    90     unsigned originalVerticalSnapPosition = _scrollingTreeNodeDelegate->scrollingNode().currentVerticalSnapPointIndex();
    91 
    92     if (!_scrollingTreeNodeDelegate->scrollingNode().horizontalSnapOffsets().isEmpty()) {
    93         unsigned index;
    94         float potentialSnapPosition = closestSnapOffset(_scrollingTreeNodeDelegate->scrollingNode().horizontalSnapOffsets(), _scrollingTreeNodeDelegate->scrollingNode().horizontalSnapOffsetRanges(), horizontalTarget, velocity.x, index);
    95         _scrollingTreeNodeDelegate->scrollingNode().setCurrentHorizontalSnapPointIndex(index);
    96         if (horizontalTarget >= 0 && horizontalTarget <= scrollView.contentSize.width)
    97             targetContentOffset->x = potentialSnapPosition;
    98     }
    99 
    100     if (!_scrollingTreeNodeDelegate->scrollingNode().verticalSnapOffsets().isEmpty()) {
    101         unsigned index;
    102         float potentialSnapPosition = closestSnapOffset(_scrollingTreeNodeDelegate->scrollingNode().verticalSnapOffsets(), _scrollingTreeNodeDelegate->scrollingNode().verticalSnapOffsetRanges(), verticalTarget, velocity.y, index);
    103         _scrollingTreeNodeDelegate->scrollingNode().setCurrentVerticalSnapPointIndex(index);
    104         if (verticalTarget >= 0 && verticalTarget <= scrollView.contentSize.height)
    105             targetContentOffset->y = potentialSnapPosition;
    106     }
    107 
    108     if (originalHorizontalSnapPosition != _scrollingTreeNodeDelegate->scrollingNode().currentHorizontalSnapPointIndex()
    109         || originalVerticalSnapPosition != _scrollingTreeNodeDelegate->scrollingNode().currentVerticalSnapPointIndex()) {
    110         _scrollingTreeNodeDelegate->currentSnapPointIndicesDidChange(_scrollingTreeNodeDelegate->scrollingNode().currentHorizontalSnapPointIndex(), _scrollingTreeNodeDelegate->scrollingNode().currentVerticalSnapPointIndex());
    111     }
    112 }
    113 #endif
    114 
    115 - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)willDecelerate
    116 {
    117     if (_inUserInteraction && !willDecelerate) {
    118         _inUserInteraction = NO;
    119         _scrollingTreeNodeDelegate->scrollViewDidScroll(scrollView.contentOffset, _inUserInteraction);
    120         _scrollingTreeNodeDelegate->scrollDidEnd();
    121     }
    122 }
    123 
    124 - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
    125 {
    126     if (_inUserInteraction) {
    127         _inUserInteraction = NO;
    128         _scrollingTreeNodeDelegate->scrollViewDidScroll(scrollView.contentOffset, _inUserInteraction);
    129         _scrollingTreeNodeDelegate->scrollDidEnd();
    130     }
    131 }
    132 
    133 @end
    13437
    13538namespace WebKit {
     
    14851ScrollingTreeOverflowScrollingNodeIOS::~ScrollingTreeOverflowScrollingNodeIOS()
    14952{
    150     BEGIN_BLOCK_OBJC_EXCEPTIONS
    151     if (UIScrollView *scrollView = (UIScrollView *)[scrollLayer() delegate]) {
    152         ASSERT([scrollView isKindOfClass:[UIScrollView self]]);
    153         // The scrollView may have been adopted by another node, so only clear the delegate if it's ours.
    154         if (scrollView.delegate == m_scrollViewDelegate.get())
    155             scrollView.delegate = nil;
    156     }
    157     END_BLOCK_OBJC_EXCEPTIONS
    158 
    159     // WKOverflowScrollViewDelegate holds a pointer to ScrollingTreeScrollingNodeDelegateIOS, so we ensure it is destroyed first.
    160     m_scrollViewDelegate.clear();
    161     m_scrollingNodeDelegate.reset();
    16253}
    16354
    16455void ScrollingTreeOverflowScrollingNodeIOS::commitStateBeforeChildren(const WebCore::ScrollingStateNode& stateNode)
    16556{
    166     if (stateNode.hasChangedProperty(ScrollingStateScrollingNode::ScrollLayer)) {
    167         BEGIN_BLOCK_OBJC_EXCEPTIONS
    168         if (UIScrollView *scrollView = (UIScrollView *)[scrollLayer() delegate]) {
    169             ASSERT([scrollView isKindOfClass:[UIScrollView self]]);
    170             scrollView.delegate = nil;
    171         }
    172         END_BLOCK_OBJC_EXCEPTIONS
    173     }
     57    if (stateNode.hasChangedProperty(ScrollingStateScrollingNode::ScrollLayer))
     58        m_scrollingNodeDelegate->resetScrollViewDelegate();
    17459
    17560    ScrollingTreeOverflowScrollingNode::commitStateBeforeChildren(stateNode);
    176 
    177     const auto& scrollingStateNode = downcast<ScrollingStateOverflowScrollingNode>(stateNode);
    178     if (scrollingStateNode.hasChangedProperty(ScrollingStateNode::ScrollLayer))
    179         m_scrollLayer = scrollingStateNode.layer();
    180 
    181     if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ScrolledContentsLayer))
    182         m_scrolledContentsLayer = scrollingStateNode.scrolledContentsLayer();
     61    m_scrollingNodeDelegate->commitStateBeforeChildren(downcast<ScrollingStateScrollingNode>(stateNode));
    18362}
    18463
     
    18665{
    18766    ScrollingTreeOverflowScrollingNode::commitStateAfterChildren(stateNode);
    188 
    189     SetForScope<bool> updatingChange(m_scrollingNodeDelegate->m_updatingFromStateNode, true);
    190 
    191     const auto& scrollingStateNode = downcast<ScrollingStateOverflowScrollingNode>(stateNode);
    192 
    193     if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ScrollLayer)
    194         || scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::TotalContentsSize)
    195         || scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ReachableContentsSize)
    196         || scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ScrollPosition)
    197         || scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ScrollOrigin)) {
    198         BEGIN_BLOCK_OBJC_EXCEPTIONS
    199         UIScrollView *scrollView = (UIScrollView *)[scrollLayer() delegate];
    200         ASSERT([scrollView isKindOfClass:[UIScrollView self]]);
    201 
    202         if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ScrollLayer)) {
    203             if (!m_scrollViewDelegate)
    204                 m_scrollViewDelegate = adoptNS([[WKOverflowScrollViewDelegate alloc] initWithScrollingTreeNodeDelegate:m_scrollingNodeDelegate.get()]);
    205 
    206             scrollView.scrollsToTop = NO;
    207             scrollView.delegate = m_scrollViewDelegate.get();
    208         }
    209 
    210         bool recomputeInsets = scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::TotalContentsSize);
    211         if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ReachableContentsSize)) {
    212             scrollView.contentSize = scrollingStateNode.reachableContentsSize();
    213             recomputeInsets = true;
    214         }
    215 
    216         if ((scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ScrollPosition)
    217             || scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ScrollOrigin))
    218             && ![m_scrollViewDelegate _isInUserInteraction]) {
    219             scrollView.contentOffset = scrollingStateNode.scrollPosition() + scrollOrigin();
    220             recomputeInsets = true;
    221         }
    222 
    223         if (recomputeInsets) {
    224             UIEdgeInsets insets = UIEdgeInsetsMake(0, 0, 0, 0);
    225             // With RTL or bottom-to-top scrolling (non-zero origin), we need extra space on the left or top.
    226             if (scrollOrigin().x())
    227                 insets.left = reachableContentsSize().width() - totalContentsSize().width();
    228 
    229             if (scrollOrigin().y())
    230                 insets.top = reachableContentsSize().height() - totalContentsSize().height();
    231 
    232             scrollView.contentInset = insets;
    233         }
    234 
    235 #if ENABLE(CSS_SCROLL_SNAP)
    236         // FIXME: If only one axis snaps in 2D scrolling, the other axis will decelerate fast as well. Is this what we want?
    237         if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::HorizontalSnapOffsets) || scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::VerticalSnapOffsets))
    238             scrollView.decelerationRate = horizontalSnapOffsets().size() || verticalSnapOffsets().size() ? UIScrollViewDecelerationRateFast : UIScrollViewDecelerationRateNormal;
    239 #endif
    240         END_BLOCK_OBJC_EXCEPTIONS
    241     }
     67    m_scrollingNodeDelegate->commitStateAfterChildren(downcast<ScrollingStateScrollingNode>(stateNode));
    24268}
    24369
    24470void ScrollingTreeOverflowScrollingNodeIOS::updateLayersAfterAncestorChange(const ScrollingTreeNode& changedNode, const FloatRect& fixedPositionRect, const FloatSize& cumulativeDelta)
    24571{
    246     if (!m_children)
    247         return;
    248 
    249     FloatSize scrollDelta = lastCommittedScrollPosition() - scrollPosition();
    250 
    251     for (auto& child : *m_children)
    252         child->updateLayersAfterAncestorChange(changedNode, fixedPositionRect, cumulativeDelta + scrollDelta);
     72    m_scrollingNodeDelegate->updateLayersAfterAncestorChange(changedNode, fixedPositionRect, cumulativeDelta);
    25373}
    25474
    25575FloatPoint ScrollingTreeOverflowScrollingNodeIOS::scrollPosition() const
    25676{
    257     BEGIN_BLOCK_OBJC_EXCEPTIONS
    258     UIScrollView *scrollView = (UIScrollView *)[scrollLayer() delegate];
    259     ASSERT([scrollView isKindOfClass:[UIScrollView self]]);
    260     return [scrollView contentOffset];
    261     END_BLOCK_OBJC_EXCEPTIONS
     77    return m_scrollingNodeDelegate->scrollPosition();
    26278}
    26379
    26480void ScrollingTreeOverflowScrollingNodeIOS::setScrollLayerPosition(const FloatPoint& scrollPosition, const FloatRect&)
    26581{
    266     [m_scrollLayer setPosition:CGPointMake(-scrollPosition.x() + scrollOrigin().x(), -scrollPosition.y() + scrollOrigin().y())];
    267 
    268     m_scrollingNodeDelegate->updateChildNodesAfterScroll(scrollPosition);
     82    m_scrollingNodeDelegate->setScrollLayerPosition(scrollPosition);
    26983}
    27084
     
    27488}
    27589
    276 } // namespace WebCore
     90} // namespace WebKit
    27791
    27892#endif // ENABLE(ASYNC_SCROLLING)
  • trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h

    r221669 r221753  
    2828#if PLATFORM(IOS) && ENABLE(ASYNC_SCROLLING)
    2929
     30#include <UIKit/UIScrollView.h>
     31#include <WebCore/ScrollingCoordinator.h>
     32#include <WebCore/ScrollingTreeScrollingNode.h>
    3033#include <WebCore/ScrollingTreeScrollingNodeDelegate.h>
     34
     35OBJC_CLASS CALayer;
     36OBJC_CLASS WKScrollingNodeScrollViewDelegate;
    3137
    3238namespace WebCore {
    3339
    3440class FloatPoint;
     41class FloatRect;
     42class FloatSize;
    3543class ScrollingTreeScrollingNode;
    3644
     
    3947namespace WebKit {
    4048
    41 class ScrollingTreeOverflowScrollingNodeIOS;
    42 
    4349class ScrollingTreeScrollingNodeDelegateIOS : public WebCore::ScrollingTreeScrollingNodeDelegate {
    44     friend class ScrollingTreeOverflowScrollingNodeIOS;
    45 
    4650public:
    4751    explicit ScrollingTreeScrollingNodeDelegateIOS(WebCore::ScrollingTreeScrollingNode&);
     
    5357    void scrollViewDidScroll(const WebCore::FloatPoint& scrollPosition, bool inUserInteraction) const;
    5458    void currentSnapPointIndicesDidChange(unsigned horizontal, unsigned vertical) const;
     59    CALayer *scrollLayer() const { return m_scrollLayer.get(); }
     60
     61    void resetScrollViewDelegate();
     62    void commitStateBeforeChildren(const WebCore::ScrollingStateScrollingNode&);
     63    void commitStateAfterChildren(const WebCore::ScrollingStateScrollingNode&);
     64    void updateLayersAfterAncestorChange(const WebCore::ScrollingTreeNode& changedNode, const WebCore::FloatRect& fixedPositionRect, const WebCore::FloatSize& cumulativeDelta);
     65    WebCore::FloatPoint scrollPosition() const;
     66    void setScrollLayerPosition(const WebCore::FloatPoint&);
     67    void updateChildNodesAfterScroll(const WebCore::FloatPoint& scrollPosition);
    5568
    5669private:
    57     void updateChildNodesAfterScroll(const WebCore::FloatPoint& scrollPosition);
    58 
    59     bool m_updatingFromStateNode;
     70    RetainPtr<CALayer> m_scrollLayer;
     71    RetainPtr<CALayer> m_scrolledContentsLayer;
     72    RetainPtr<WKScrollingNodeScrollViewDelegate> m_scrollViewDelegate;
     73    bool m_updatingFromStateNode { false };
    6074};
    6175
    6276} // namespace WebKit
    6377
     78@interface WKScrollingNodeScrollViewDelegate : NSObject <UIScrollViewDelegate> {
     79    WebKit::ScrollingTreeScrollingNodeDelegateIOS* _scrollingTreeNodeDelegate;
     80}
     81
     82@property (nonatomic, getter=_isInUserInteraction) BOOL inUserInteraction;
     83
     84- (instancetype)initWithScrollingTreeNodeDelegate:(WebKit::ScrollingTreeScrollingNodeDelegateIOS*)delegate;
     85
     86@end
     87
    6488#endif // PLATFORM(IOS) && ENABLE(ASYNC_SCROLLING)
  • trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm

    r221669 r221753  
    2929#if PLATFORM(IOS) && ENABLE(ASYNC_SCROLLING)
    3030
     31#import <QuartzCore/QuartzCore.h>
     32#import <UIKit/UIPanGestureRecognizer.h>
     33#import <UIKit/UIScrollView.h>
     34#import <WebCore/ScrollingStateOverflowScrollingNode.h>
    3135#import <WebCore/ScrollingTree.h>
    3236#import <WebCore/ScrollingTreeFrameScrollingNode.h>
    3337#import <WebCore/ScrollingTreeScrollingNode.h>
     38#import <wtf/BlockObjCExceptions.h>
     39#import <wtf/SetForScope.h>
     40
     41#if ENABLE(CSS_SCROLL_SNAP)
     42#import <WebCore/AxisScrollSnapOffsets.h>
     43#import <WebCore/ScrollSnapOffsetsInfo.h>
     44#endif
    3445
    3546using namespace WebCore;
     47
     48@implementation WKScrollingNodeScrollViewDelegate
     49
     50- (instancetype)initWithScrollingTreeNodeDelegate:(WebKit::ScrollingTreeScrollingNodeDelegateIOS*)delegate
     51{
     52    if ((self = [super init]))
     53        _scrollingTreeNodeDelegate = delegate;
     54
     55    return self;
     56}
     57
     58- (void)scrollViewDidScroll:(UIScrollView *)scrollView
     59{
     60    _scrollingTreeNodeDelegate->scrollViewDidScroll(scrollView.contentOffset, _inUserInteraction);
     61}
     62
     63- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
     64{
     65    _inUserInteraction = YES;
     66
     67    if (scrollView.panGestureRecognizer.state == UIGestureRecognizerStateBegan)
     68        _scrollingTreeNodeDelegate->scrollViewWillStartPanGesture();
     69    _scrollingTreeNodeDelegate->scrollWillStart();
     70}
     71
     72#if ENABLE(CSS_SCROLL_SNAP)
     73- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
     74{
     75    CGFloat horizontalTarget = targetContentOffset->x;
     76    CGFloat verticalTarget = targetContentOffset->y;
     77
     78    unsigned originalHorizontalSnapPosition = _scrollingTreeNodeDelegate->scrollingNode().currentHorizontalSnapPointIndex();
     79    unsigned originalVerticalSnapPosition = _scrollingTreeNodeDelegate->scrollingNode().currentVerticalSnapPointIndex();
     80
     81    if (!_scrollingTreeNodeDelegate->scrollingNode().horizontalSnapOffsets().isEmpty()) {
     82        unsigned index;
     83        float potentialSnapPosition = closestSnapOffset(_scrollingTreeNodeDelegate->scrollingNode().horizontalSnapOffsets(), _scrollingTreeNodeDelegate->scrollingNode().horizontalSnapOffsetRanges(), horizontalTarget, velocity.x, index);
     84        _scrollingTreeNodeDelegate->scrollingNode().setCurrentHorizontalSnapPointIndex(index);
     85        if (horizontalTarget >= 0 && horizontalTarget <= scrollView.contentSize.width)
     86            targetContentOffset->x = potentialSnapPosition;
     87    }
     88
     89    if (!_scrollingTreeNodeDelegate->scrollingNode().verticalSnapOffsets().isEmpty()) {
     90        unsigned index;
     91        float potentialSnapPosition = closestSnapOffset(_scrollingTreeNodeDelegate->scrollingNode().verticalSnapOffsets(), _scrollingTreeNodeDelegate->scrollingNode().verticalSnapOffsetRanges(), verticalTarget, velocity.y, index);
     92        _scrollingTreeNodeDelegate->scrollingNode().setCurrentVerticalSnapPointIndex(index);
     93        if (verticalTarget >= 0 && verticalTarget <= scrollView.contentSize.height)
     94            targetContentOffset->y = potentialSnapPosition;
     95    }
     96
     97    if (originalHorizontalSnapPosition != _scrollingTreeNodeDelegate->scrollingNode().currentHorizontalSnapPointIndex()
     98        || originalVerticalSnapPosition != _scrollingTreeNodeDelegate->scrollingNode().currentVerticalSnapPointIndex()) {
     99        _scrollingTreeNodeDelegate->currentSnapPointIndicesDidChange(_scrollingTreeNodeDelegate->scrollingNode().currentHorizontalSnapPointIndex(), _scrollingTreeNodeDelegate->scrollingNode().currentVerticalSnapPointIndex());
     100    }
     101}
     102#endif
     103
     104- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)willDecelerate
     105{
     106    if (_inUserInteraction && !willDecelerate) {
     107        _inUserInteraction = NO;
     108        _scrollingTreeNodeDelegate->scrollViewDidScroll(scrollView.contentOffset, _inUserInteraction);
     109        _scrollingTreeNodeDelegate->scrollDidEnd();
     110    }
     111}
     112
     113- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
     114{
     115    if (_inUserInteraction) {
     116        _inUserInteraction = NO;
     117        _scrollingTreeNodeDelegate->scrollViewDidScroll(scrollView.contentOffset, _inUserInteraction);
     118        _scrollingTreeNodeDelegate->scrollDidEnd();
     119    }
     120}
     121
     122@end
    36123
    37124namespace WebKit {
     
    45132ScrollingTreeScrollingNodeDelegateIOS::~ScrollingTreeScrollingNodeDelegateIOS()
    46133{
     134    BEGIN_BLOCK_OBJC_EXCEPTIONS
     135    if (UIScrollView *scrollView = (UIScrollView *)[scrollLayer() delegate]) {
     136        ASSERT([scrollView isKindOfClass:[UIScrollView self]]);
     137        // The scrollView may have been adopted by another node, so only clear the delegate if it's ours.
     138        if (scrollView.delegate == m_scrollViewDelegate.get())
     139            scrollView.delegate = nil;
     140    }
     141    END_BLOCK_OBJC_EXCEPTIONS
     142}
     143
     144void ScrollingTreeScrollingNodeDelegateIOS::resetScrollViewDelegate()
     145{
     146    BEGIN_BLOCK_OBJC_EXCEPTIONS
     147    if (UIScrollView *scrollView = (UIScrollView *)[scrollLayer() delegate]) {
     148        ASSERT([scrollView isKindOfClass:[UIScrollView self]]);
     149        scrollView.delegate = nil;
     150    }
     151    END_BLOCK_OBJC_EXCEPTIONS
     152}
     153
     154void ScrollingTreeScrollingNodeDelegateIOS::commitStateBeforeChildren(const ScrollingStateScrollingNode& scrollingStateNode)
     155{
     156    if (scrollingStateNode.hasChangedProperty(ScrollingStateNode::ScrollLayer))
     157        m_scrollLayer = scrollingStateNode.layer();
     158
     159    if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ScrolledContentsLayer))
     160        m_scrolledContentsLayer = scrollingStateNode.scrolledContentsLayer();
     161}
     162
     163void ScrollingTreeScrollingNodeDelegateIOS::commitStateAfterChildren(const ScrollingStateScrollingNode& scrollingStateNode)
     164{
     165    SetForScope<bool> updatingChange(m_updatingFromStateNode, true);
     166    if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ScrollLayer)
     167        || scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::TotalContentsSize)
     168        || scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ReachableContentsSize)
     169        || scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ScrollPosition)
     170        || scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ScrollOrigin)) {
     171        BEGIN_BLOCK_OBJC_EXCEPTIONS
     172        UIScrollView *scrollView = (UIScrollView *)[scrollLayer() delegate];
     173        ASSERT([scrollView isKindOfClass:[UIScrollView self]]);
     174
     175        if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ScrollLayer)) {
     176            if (!m_scrollViewDelegate)
     177                m_scrollViewDelegate = adoptNS([[WKScrollingNodeScrollViewDelegate alloc] initWithScrollingTreeNodeDelegate:this]);
     178
     179            scrollView.scrollsToTop = NO;
     180            scrollView.delegate = m_scrollViewDelegate.get();
     181        }
     182
     183        bool recomputeInsets = scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::TotalContentsSize);
     184        if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ReachableContentsSize)) {
     185            scrollView.contentSize = scrollingStateNode.reachableContentsSize();
     186            recomputeInsets = true;
     187        }
     188
     189        if ((scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ScrollPosition)
     190            || scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ScrollOrigin))
     191            && ![m_scrollViewDelegate _isInUserInteraction]) {
     192            scrollView.contentOffset = scrollingStateNode.scrollPosition() + scrollOrigin();
     193            recomputeInsets = true;
     194        }
     195
     196        if (recomputeInsets) {
     197            UIEdgeInsets insets = UIEdgeInsetsMake(0, 0, 0, 0);
     198            // With RTL or bottom-to-top scrolling (non-zero origin), we need extra space on the left or top.
     199            if (scrollOrigin().x())
     200                insets.left = reachableContentsSize().width() - totalContentsSize().width();
     201
     202            if (scrollOrigin().y())
     203                insets.top = reachableContentsSize().height() - totalContentsSize().height();
     204
     205            scrollView.contentInset = insets;
     206        }
     207
     208#if ENABLE(CSS_SCROLL_SNAP)
     209        // FIXME: If only one axis snaps in 2D scrolling, the other axis will decelerate fast as well. Is this what we want?
     210        if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::HorizontalSnapOffsets) || scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::VerticalSnapOffsets))
     211            scrollView.decelerationRate = scrollingNode().horizontalSnapOffsets().size() || scrollingNode().verticalSnapOffsets().size() ? UIScrollViewDecelerationRateFast : UIScrollViewDecelerationRateNormal;
     212#endif
     213        END_BLOCK_OBJC_EXCEPTIONS
     214    }
     215}
     216
     217void ScrollingTreeScrollingNodeDelegateIOS::updateLayersAfterAncestorChange(const ScrollingTreeNode& changedNode, const FloatRect& fixedPositionRect, const FloatSize& cumulativeDelta)
     218{
     219    if (!scrollingNode().children())
     220        return;
     221
     222    FloatSize scrollDelta = lastCommittedScrollPosition() - scrollingNode().scrollPosition();
     223
     224    for (auto& child : *scrollingNode().children())
     225        child->updateLayersAfterAncestorChange(changedNode, fixedPositionRect, cumulativeDelta + scrollDelta);
     226}
     227
     228FloatPoint ScrollingTreeScrollingNodeDelegateIOS::scrollPosition() const
     229{
     230    BEGIN_BLOCK_OBJC_EXCEPTIONS
     231    UIScrollView *scrollView = (UIScrollView *)[scrollLayer() delegate];
     232    ASSERT([scrollView isKindOfClass:[UIScrollView self]]);
     233    return [scrollView contentOffset];
     234    END_BLOCK_OBJC_EXCEPTIONS
     235}
     236
     237void ScrollingTreeScrollingNodeDelegateIOS::setScrollLayerPosition(const FloatPoint& scrollPosition)
     238{
     239    [m_scrollLayer setPosition:CGPointMake(scrollPosition.x() + scrollOrigin().x(), scrollPosition.y() + scrollOrigin().y())];
     240    updateChildNodesAfterScroll(scrollPosition);
    47241}
    48242
Note: See TracChangeset for help on using the changeset viewer.