Changeset 221753 in webkit
- Timestamp:
- Sep 7, 2017 1:21:12 PM (7 years ago)
- Location:
- trunk/Source
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNodeDelegate.cpp
r221669 r221753 52 52 } 53 53 54 const FloatSize& ScrollingTreeScrollingNodeDelegate::totalContentsSize() 55 { 56 return m_scrollingNode.totalContentsSize(); 57 } 58 59 const FloatSize& ScrollingTreeScrollingNodeDelegate::reachableContentsSize() 60 { 61 return m_scrollingNode.reachableContentsSize(); 62 } 63 64 const IntPoint& ScrollingTreeScrollingNodeDelegate::scrollOrigin() const 65 { 66 return m_scrollingNode.scrollOrigin(); 67 } 68 54 69 } // namespace WebCore 55 70 -
trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNodeDelegate.h
r221669 r221753 31 31 32 32 class FloatPoint; 33 class FloatSize; 34 class IntPoint; 33 35 class ScrollingTreeScrollingNode; 34 36 class ScrollingTree; … … 44 46 WEBCORE_EXPORT ScrollingTree& scrollingTree() const; 45 47 WEBCORE_EXPORT FloatPoint lastCommittedScrollPosition() const; 48 WEBCORE_EXPORT const FloatSize& totalContentsSize(); 49 WEBCORE_EXPORT const FloatSize& reachableContentsSize(); 50 WEBCORE_EXPORT const IntPoint& scrollOrigin() const; 46 51 47 52 private: -
trunk/Source/WebKit/ChangeLog
r221749 r221753 1 2017-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 1 54 2017-09-07 Chris Dumez <cdumez@apple.com> 2 55 -
trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.h
r221669 r221753 28 28 #if ENABLE(ASYNC_SCROLLING) && PLATFORM(IOS) 29 29 30 #include <WebCore/ScrollingCoordinator.h>31 30 #include <WebCore/ScrollingTreeOverflowScrollingNode.h> 32 33 OBJC_CLASS CALayer;34 OBJC_CLASS WKOverflowScrollViewDelegate;35 31 36 32 namespace WebKit { … … 42 38 static Ref<ScrollingTreeOverflowScrollingNodeIOS> create(WebCore::ScrollingTree&, WebCore::ScrollingNodeID); 43 39 virtual ~ScrollingTreeOverflowScrollingNodeIOS(); 44 45 CALayer *scrollLayer() const { return m_scrollLayer.get(); }46 40 47 41 private: … … 62 56 void handleWheelEvent(const WebCore::PlatformWheelEvent&) override { } 63 57 64 RetainPtr<CALayer> m_scrollLayer;65 RetainPtr<CALayer> m_scrolledContentsLayer;66 67 RetainPtr<WKOverflowScrollViewDelegate> m_scrollViewDelegate;68 58 std::unique_ptr<ScrollingTreeScrollingNodeDelegateIOS> m_scrollingNodeDelegate; 69 59 }; -
trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.mm
r221669 r221753 30 30 #if ENABLE(ASYNC_SCROLLING) 31 31 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 #endif44 45 32 #import "ScrollingTreeScrollingNodeDelegateIOS.h" 46 33 34 #import <WebCore/ScrollingStateOverflowScrollingNode.h> 35 47 36 using 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 @end58 59 @implementation WKOverflowScrollViewDelegate60 61 - (instancetype)initWithScrollingTreeNodeDelegate:(WebKit::ScrollingTreeScrollingNodeDelegateIOS*)delegate62 {63 if ((self = [super init]))64 _scrollingTreeNodeDelegate = delegate;65 66 return self;67 }68 69 - (void)scrollViewDidScroll:(UIScrollView *)scrollView70 {71 _scrollingTreeNodeDelegate->scrollViewDidScroll(scrollView.contentOffset, _inUserInteraction);72 }73 74 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView75 {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 *)targetContentOffset85 {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 #endif114 115 - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)willDecelerate116 {117 if (_inUserInteraction && !willDecelerate) {118 _inUserInteraction = NO;119 _scrollingTreeNodeDelegate->scrollViewDidScroll(scrollView.contentOffset, _inUserInteraction);120 _scrollingTreeNodeDelegate->scrollDidEnd();121 }122 }123 124 - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView125 {126 if (_inUserInteraction) {127 _inUserInteraction = NO;128 _scrollingTreeNodeDelegate->scrollViewDidScroll(scrollView.contentOffset, _inUserInteraction);129 _scrollingTreeNodeDelegate->scrollDidEnd();130 }131 }132 133 @end134 37 135 38 namespace WebKit { … … 148 51 ScrollingTreeOverflowScrollingNodeIOS::~ScrollingTreeOverflowScrollingNodeIOS() 149 52 { 150 BEGIN_BLOCK_OBJC_EXCEPTIONS151 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_EXCEPTIONS158 159 // WKOverflowScrollViewDelegate holds a pointer to ScrollingTreeScrollingNodeDelegateIOS, so we ensure it is destroyed first.160 m_scrollViewDelegate.clear();161 m_scrollingNodeDelegate.reset();162 53 } 163 54 164 55 void ScrollingTreeOverflowScrollingNodeIOS::commitStateBeforeChildren(const WebCore::ScrollingStateNode& stateNode) 165 56 { 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(); 174 59 175 60 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)); 183 62 } 184 63 … … 186 65 { 187 66 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)); 242 68 } 243 69 244 70 void ScrollingTreeOverflowScrollingNodeIOS::updateLayersAfterAncestorChange(const ScrollingTreeNode& changedNode, const FloatRect& fixedPositionRect, const FloatSize& cumulativeDelta) 245 71 { 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); 253 73 } 254 74 255 75 FloatPoint ScrollingTreeOverflowScrollingNodeIOS::scrollPosition() const 256 76 { 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(); 262 78 } 263 79 264 80 void ScrollingTreeOverflowScrollingNodeIOS::setScrollLayerPosition(const FloatPoint& scrollPosition, const FloatRect&) 265 81 { 266 [m_scrollLayer setPosition:CGPointMake(-scrollPosition.x() + scrollOrigin().x(), -scrollPosition.y() + scrollOrigin().y())]; 267 268 m_scrollingNodeDelegate->updateChildNodesAfterScroll(scrollPosition); 82 m_scrollingNodeDelegate->setScrollLayerPosition(scrollPosition); 269 83 } 270 84 … … 274 88 } 275 89 276 } // namespace Web Core90 } // namespace WebKit 277 91 278 92 #endif // ENABLE(ASYNC_SCROLLING) -
trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.h
r221669 r221753 28 28 #if PLATFORM(IOS) && ENABLE(ASYNC_SCROLLING) 29 29 30 #include <UIKit/UIScrollView.h> 31 #include <WebCore/ScrollingCoordinator.h> 32 #include <WebCore/ScrollingTreeScrollingNode.h> 30 33 #include <WebCore/ScrollingTreeScrollingNodeDelegate.h> 34 35 OBJC_CLASS CALayer; 36 OBJC_CLASS WKScrollingNodeScrollViewDelegate; 31 37 32 38 namespace WebCore { 33 39 34 40 class FloatPoint; 41 class FloatRect; 42 class FloatSize; 35 43 class ScrollingTreeScrollingNode; 36 44 … … 39 47 namespace WebKit { 40 48 41 class ScrollingTreeOverflowScrollingNodeIOS;42 43 49 class ScrollingTreeScrollingNodeDelegateIOS : public WebCore::ScrollingTreeScrollingNodeDelegate { 44 friend class ScrollingTreeOverflowScrollingNodeIOS;45 46 50 public: 47 51 explicit ScrollingTreeScrollingNodeDelegateIOS(WebCore::ScrollingTreeScrollingNode&); … … 53 57 void scrollViewDidScroll(const WebCore::FloatPoint& scrollPosition, bool inUserInteraction) const; 54 58 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); 55 68 56 69 private: 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 }; 60 74 }; 61 75 62 76 } // namespace WebKit 63 77 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 64 88 #endif // PLATFORM(IOS) && ENABLE(ASYNC_SCROLLING) -
trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm
r221669 r221753 29 29 #if PLATFORM(IOS) && ENABLE(ASYNC_SCROLLING) 30 30 31 #import <QuartzCore/QuartzCore.h> 32 #import <UIKit/UIPanGestureRecognizer.h> 33 #import <UIKit/UIScrollView.h> 34 #import <WebCore/ScrollingStateOverflowScrollingNode.h> 31 35 #import <WebCore/ScrollingTree.h> 32 36 #import <WebCore/ScrollingTreeFrameScrollingNode.h> 33 37 #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 34 45 35 46 using 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 36 123 37 124 namespace WebKit { … … 45 132 ScrollingTreeScrollingNodeDelegateIOS::~ScrollingTreeScrollingNodeDelegateIOS() 46 133 { 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 144 void 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 154 void 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 163 void 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 217 void 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 228 FloatPoint 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 237 void ScrollingTreeScrollingNodeDelegateIOS::setScrollLayerPosition(const FloatPoint& scrollPosition) 238 { 239 [m_scrollLayer setPosition:CGPointMake(scrollPosition.x() + scrollOrigin().x(), scrollPosition.y() + scrollOrigin().y())]; 240 updateChildNodesAfterScroll(scrollPosition); 47 241 } 48 242
Note: See TracChangeset
for help on using the changeset viewer.