Changeset 269373 in webkit
- Timestamp:
- Nov 4, 2020 10:45:14 AM (21 months ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 20 edited
-
ChangeLog (modified) (1 diff)
-
page/scrolling/ScrollingTree.cpp (modified) (3 diffs)
-
page/scrolling/ScrollingTreeScrollingNode.cpp (modified) (1 diff)
-
page/scrolling/ScrollingTreeScrollingNode.h (modified) (1 diff)
-
page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h (modified) (1 diff)
-
page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm (modified) (1 diff)
-
page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.h (modified) (1 diff)
-
page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm (modified) (1 diff)
-
page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.h (modified) (2 diffs)
-
page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm (modified) (2 diffs)
-
page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp (modified) (1 diff)
-
page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.h (modified) (1 diff)
-
platform/ScrollAnimator.cpp (modified) (1 diff)
-
platform/ScrollableArea.cpp (modified) (1 diff)
-
platform/ScrollableArea.h (modified) (2 diffs)
-
platform/cocoa/ScrollController.h (modified) (6 diffs)
-
platform/cocoa/ScrollController.mm (modified) (6 diffs)
-
platform/mac/ScrollAnimatorMac.h (modified) (1 diff)
-
platform/mac/ScrollAnimatorMac.mm (modified) (1 diff)
-
platform/mock/ScrollAnimatorMock.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r269371 r269373 1 2020-11-04 Simon Fraser <simon.fraser@apple.com> 2 3 A programmatic scroll should stop any rubberbanding 4 https://bugs.webkit.org/show_bug.cgi?id=218545 5 6 Reviewed by Antti Koivisto. 7 8 Part of rdar://problem/69599531: Scrolling on netflix.com sometimes jumps to the top. 9 10 If the scrolling thread is in the middle of a rubberband (say, when a modal overlay is 11 up), and then the main thread triggers a programmatic scroll to some other location, 12 we should stop rubberbanding immediately. If we don't, then the rubberband timer 13 continues to generate scrolls on the scrolling thread which get to the main thread 14 after it has handled the programatic scroll, thus resetting the scroll position. 15 16 This change shares some edgePinnedState() around which is used to allow rubberbanding 17 to continue of the programmatic scroll is to the edge which is already pinned 18 (commonly the top). 19 20 Also address some review comments from a previous patch. 21 22 Very hard to make tests that do things while rubberbanding is happening. 23 24 * page/scrolling/ScrollingTree.cpp: 25 (WebCore::ScrollingTree::applyLayerPositionsInternal): 26 (WebCore::ScrollingTree::addPendingScrollUpdate): 27 (WebCore::ScrollingTree::takePendingScrollUpdates): 28 * page/scrolling/ScrollingTreeScrollingNode.cpp: 29 (WebCore::ScrollingTreeScrollingNode::scrollTo): 30 (WebCore::ScrollingTreeScrollingNode::currentScrollPositionChanged): 31 * page/scrolling/ScrollingTreeScrollingNode.h: 32 * page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h: 33 * page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm: 34 (WebCore::ScrollingTreeFrameScrollingNodeMac::currentScrollPositionChanged): 35 * page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.h: 36 * page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm: 37 (WebCore::ScrollingTreeOverflowScrollingNodeMac::currentScrollPositionChanged): 38 * page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.h: 39 * page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm: 40 (WebCore::ScrollingTreeScrollingNodeDelegateMac::currentScrollPositionChanged): 41 (WebCore::ScrollingTreeScrollingNodeDelegateMac::edgePinnedState const): 42 * platform/ScrollAnimator.cpp: 43 (WebCore::ScrollAnimator::notifyPositionChanged): 44 * platform/ScrollableArea.cpp: 45 (WebCore::ScrollableArea::edgePinnedState const): 46 * platform/ScrollableArea.h: 47 * platform/cocoa/ScrollController.h: 48 * platform/cocoa/ScrollController.mm: 49 (WebCore::ScrollController::snapRubberBandTimerFired): 50 (WebCore::ScrollController::scrollPositionChanged): 51 (WebCore::ScrollController::stopRubberbanding): 52 (WebCore::ScrollController::updateRubberBandingState): 53 (WebCore::ScrollController::updateRubberBandingEdges): 54 (WebCore::ScrollController::scrolledToRubberbandingEdge const): 55 * platform/mac/ScrollAnimatorMac.h: 56 * platform/mac/ScrollAnimatorMac.mm: 57 (WebCore::ScrollAnimatorMac::edgePinnedState const): 58 * platform/mock/ScrollAnimatorMock.h: 59 1 60 2020-11-04 Youenn Fablet <youenn@apple.com> 2 61 -
trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp
r269312 r269373 403 403 return; 404 404 405 // LOG(Scrolling, "\nScrollingTree %p applyLayerPositions (main thread %d)", this, isMainThread());406 405 applyLayerPositionsRecursive(*m_rootNode); 407 406 } … … 580 579 void ScrollingTree::addPendingScrollUpdate(ScrollUpdate&& update) 581 580 { 582 LockHolder locker(m_pendingScrollUpdatesLock);581 auto locker = holdLock(m_pendingScrollUpdatesLock); 583 582 for (auto& existingUpdate : m_pendingScrollUpdates) { 584 583 if (existingUpdate.canMerge(update)) { … … 593 592 Vector<ScrollingTree::ScrollUpdate> ScrollingTree::takePendingScrollUpdates() 594 593 { 595 LockHolder locker(m_pendingScrollUpdatesLock);594 auto locker = holdLock(m_pendingScrollUpdatesLock); 596 595 return std::exchange(m_pendingScrollUpdates, { }); 597 596 } -
trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp
r269184 r269373 259 259 260 260 scrollingTree().setIsHandlingProgrammaticScroll(scrollType == ScrollType::Programmatic); 261 261 262 262 m_currentScrollPosition = adjustedScrollPosition(position, clamp); 263 263 264 LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeScrollingNode " << scrollingNodeID() << " scrollTo " << position << " (" << scrollType << ") (delta from last committed position " << (m_lastCommittedScrollPosition - m_currentScrollPosition) << ")"); 264 LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeScrollingNode " << scrollingNodeID() << " scrollTo " << position << " adjusted to " 265 << m_currentScrollPosition << " (" << scrollType << ") (delta from last committed position " << (m_lastCommittedScrollPosition - m_currentScrollPosition) << ")" 266 << " rubberbanding " << scrollingTree().isRubberBandInProgressForNode(scrollingNodeID())); 265 267 266 268 updateViewportForCurrentScrollPosition(); 267 currentScrollPositionChanged( );269 currentScrollPositionChanged(scrollType); 268 270 269 271 scrollingTree().setIsHandlingProgrammaticScroll(false); 270 272 } 271 273 272 void ScrollingTreeScrollingNode::currentScrollPositionChanged(Scroll ingLayerPositionAction action)274 void ScrollingTreeScrollingNode::currentScrollPositionChanged(ScrollType, ScrollingLayerPositionAction action) 273 275 { 274 276 m_scrolledSinceLastCommit = true; -
trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h
r264203 r269373 128 128 virtual FloatPoint adjustedScrollPosition(const FloatPoint&, ScrollClamping = ScrollClamping::Clamped) const; 129 129 130 virtual void currentScrollPositionChanged(Scroll ingLayerPositionAction = ScrollingLayerPositionAction::Sync);130 virtual void currentScrollPositionChanged(ScrollType, ScrollingLayerPositionAction = ScrollingLayerPositionAction::Sync); 131 131 virtual void updateViewportForCurrentScrollPosition(Optional<FloatRect> = { }) { } 132 132 virtual bool scrollPositionAndLayoutViewportMatch(const FloatPoint& position, Optional<FloatRect> overrideLayoutViewport); -
trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h
r262294 r269373 68 68 FloatPoint adjustedScrollPosition(const FloatPoint&, ScrollClamping) const override; 69 69 70 void currentScrollPositionChanged(Scroll ingLayerPositionAction) final;70 void currentScrollPositionChanged(ScrollType, ScrollingLayerPositionAction) final; 71 71 void repositionScrollingLayers() final; 72 72 -
trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm
r269184 r269373 140 140 } 141 141 142 void ScrollingTreeFrameScrollingNodeMac::currentScrollPositionChanged(Scroll ingLayerPositionAction action)143 { 144 LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeFrameScrollingNodeMac ::currentScrollPositionChanged to " << currentScrollPosition() << " min: " << minimumScrollPosition() << " max: " << maximumScrollPosition() << " sync: " << hasSynchronousScrollingReasons());145 146 m_delegate.currentScrollPositionChanged( );142 void ScrollingTreeFrameScrollingNodeMac::currentScrollPositionChanged(ScrollType scrollType, ScrollingLayerPositionAction action) 143 { 144 LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeFrameScrollingNodeMac " << scrollingNodeID() << " currentScrollPositionChanged to " << currentScrollPosition() << " min: " << minimumScrollPosition() << " max: " << maximumScrollPosition() << " sync: " << hasSynchronousScrollingReasons()); 145 146 m_delegate.currentScrollPositionChanged(scrollType); 147 147 148 148 if (isRootNode()) 149 149 updateMainFramePinAndRubberbandState(); 150 150 151 ScrollingTreeFrameScrollingNode::currentScrollPositionChanged( hasSynchronousScrollingReasons() ? ScrollingLayerPositionAction::Set : action);151 ScrollingTreeFrameScrollingNode::currentScrollPositionChanged(scrollType, hasSynchronousScrollingReasons() ? ScrollingLayerPositionAction::Set : action); 152 152 153 153 if (scrollingTree().scrollingPerformanceLoggingEnabled()) { -
trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.h
r267002 r269373 48 48 FloatPoint adjustedScrollPosition(const FloatPoint&, ScrollClamping) const override; 49 49 50 void currentScrollPositionChanged(Scroll ingLayerPositionAction) final;50 void currentScrollPositionChanged(ScrollType, ScrollingLayerPositionAction) final; 51 51 52 52 void repositionScrollingLayers() override; -
trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm
r269184 r269373 87 87 } 88 88 89 void ScrollingTreeOverflowScrollingNodeMac::currentScrollPositionChanged(Scroll ingLayerPositionAction action)89 void ScrollingTreeOverflowScrollingNodeMac::currentScrollPositionChanged(ScrollType scrollType, ScrollingLayerPositionAction action) 90 90 { 91 ScrollingTreeOverflowScrollingNode::currentScrollPositionChanged( action);92 m_delegate.currentScrollPositionChanged( );91 ScrollingTreeOverflowScrollingNode::currentScrollPositionChanged(scrollType, action); 92 m_delegate.currentScrollPositionChanged(scrollType); 93 93 } 94 94 -
trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.h
r267002 r269373 52 52 bool handleWheelEvent(const PlatformWheelEvent&); 53 53 54 void currentScrollPositionChanged( );54 void currentScrollPositionChanged(ScrollType); 55 55 56 56 #if ENABLE(CSS_SCROLL_SNAP) … … 79 79 IntSize stretchAmount() const final; 80 80 bool pinnedInDirection(const FloatSize&) const final; 81 RectEdges<bool> edgePinnedState() const final; 81 82 bool canScrollHorizontally() const final; 82 83 bool canScrollVertically() const final; -
trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm
r269184 r269373 161 161 } 162 162 163 void ScrollingTreeScrollingNodeDelegateMac::currentScrollPositionChanged( )164 { 165 m_scrollController.scrollPositionChanged( );163 void ScrollingTreeScrollingNodeDelegateMac::currentScrollPositionChanged(ScrollType scrollType) 164 { 165 m_scrollController.scrollPositionChanged(scrollType); 166 166 } 167 167 … … 292 292 } 293 293 294 RectEdges<bool> ScrollingTreeScrollingNodeDelegateMac::edgePinnedState() const 295 { 296 return scrollingNode().edgePinnedState(); 297 } 298 294 299 bool ScrollingTreeScrollingNodeDelegateMac::canScrollHorizontally() const 295 300 { -
trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp
r269184 r269373 246 246 } 247 247 248 void ScrollingTreeFrameScrollingNodeNicosia::currentScrollPositionChanged(Scroll ingLayerPositionAction action)248 void ScrollingTreeFrameScrollingNodeNicosia::currentScrollPositionChanged(ScrollType scrollType, ScrollingLayerPositionAction action) 249 249 { 250 250 LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeFrameScrollingNodeNicosia::currentScrollPositionChanged to " << currentScrollPosition() << " min: " << minimumScrollPosition() << " max: " << maximumScrollPosition() << " sync: " << hasSynchronousScrollingReasons()); 251 251 252 ScrollingTreeFrameScrollingNode::currentScrollPositionChanged( hasSynchronousScrollingReasons() ? ScrollingLayerPositionAction::Set : action);252 ScrollingTreeFrameScrollingNode::currentScrollPositionChanged(scrollType, hasSynchronousScrollingReasons() ? ScrollingLayerPositionAction::Set : action); 253 253 } 254 254 -
trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.h
r268522 r269373 67 67 FloatPoint adjustedScrollPosition(const FloatPoint&, ScrollClamping) const override; 68 68 69 void currentScrollPositionChanged(Scroll ingLayerPositionAction) override;69 void currentScrollPositionChanged(ScrollType, ScrollingLayerPositionAction) override; 70 70 71 71 void repositionScrollingLayers() override; -
trunk/Source/WebCore/platform/ScrollAnimator.cpp
r269143 r269373 236 236 237 237 #if ENABLE(CSS_SCROLL_SNAP) || ENABLE(RUBBER_BANDING) 238 m_scrollController.scrollPositionChanged( );238 m_scrollController.scrollPositionChanged(ScrollType::Programmatic); 239 239 #endif 240 240 } -
trunk/Source/WebCore/platform/ScrollableArea.cpp
r268031 r269373 627 627 } 628 628 629 RectEdges<bool> ScrollableArea::edgePinnedState() const 630 { 631 auto scrollPosition = this->scrollPosition(); 632 auto minScrollPosition = minimumScrollPosition(); 633 auto maxScrollPosition = maximumScrollPosition(); 634 635 // Top, right, bottom, left. 636 return { 637 scrollPosition.y() <= minScrollPosition.y(), 638 scrollPosition.x() >= maxScrollPosition.x(), 639 scrollPosition.y() >= maxScrollPosition.y(), 640 scrollPosition.x() <= minScrollPosition.x() 641 }; 642 } 643 629 644 int ScrollableArea::horizontalScrollbarIntrusion() const 630 645 { -
trunk/Source/WebCore/platform/ScrollableArea.h
r268031 r269373 26 26 #pragma once 27 27 28 #include "RectEdges.h" 28 29 #include "ScrollSnapOffsetsInfo.h" 29 30 #include "ScrollTypes.h" … … 328 329 bool isPinnedVerticallyInDirection(int verticalScrollDelta) const; 329 330 331 RectEdges<bool> edgePinnedState() const; 332 330 333 // True if scrolling happens by moving compositing layers. 331 334 virtual bool usesCompositedScrolling() const { return false; } -
trunk/Source/WebCore/platform/cocoa/ScrollController.h
r267002 r269373 30 30 #include "FloatPoint.h" 31 31 #include "FloatSize.h" 32 #include "RectEdges.h" 32 33 #include "ScrollTypes.h" 33 34 #include "WheelEventTestMonitor.h" … … 76 77 virtual bool allowsVerticalStretching(const PlatformWheelEvent&) const = 0; 77 78 virtual IntSize stretchAmount() const = 0; 79 78 80 virtual bool pinnedInDirection(const FloatSize&) const = 0; 81 82 virtual RectEdges<bool> edgePinnedState() const = 0; 83 79 84 virtual bool canScrollHorizontally() const = 0; 80 85 virtual bool canScrollVertically() const = 0; … … 147 152 bool isScrollSnapInProgress() const; 148 153 149 void scrollPositionChanged( );154 void scrollPositionChanged(ScrollType); 150 155 151 156 #if ENABLE(CSS_SCROLL_SNAP) … … 174 179 private: 175 180 #if ENABLE(RUBBER_BANDING) 181 void stopRubberbanding(); 182 176 183 void startSnapRubberbandTimer(); 177 184 void stopSnapRubberbandTimer(); … … 184 191 bool isRubberBandInProgressInternal() const; 185 192 void updateRubberBandingState(); 193 void updateRubberBandingEdges(IntSize clientStretch); 194 195 bool scrolledToRubberbandingEdge() const; 186 196 #endif 187 197 … … 216 226 FloatSize m_startStretch; 217 227 FloatSize m_origVelocity; 228 RectEdges<bool> m_rubberBandingEdges; 218 229 std::unique_ptr<ScrollControllerTimer> m_snapRubberbandTimer; 219 230 #endif -
trunk/Source/WebCore/platform/cocoa/ScrollController.mm
r267002 r269373 408 408 return; 409 409 410 LOG_WITH_STREAM(Scrolling, stream << "ScrollController::snapRubberBandTimerFired() - main thread " << isMainThread()); 411 410 412 if (!m_momentumScrollInProgress || m_ignoreMomentumScrolls) { 411 413 auto timeDelta = MonotonicTime::now() - m_startTime; … … 414 416 m_startStretch = m_client.stretchAmount(); 415 417 if (m_startStretch == FloatSize()) { 416 stopSnapRubberbandTimer(); 417 418 m_stretchScrollForce = { }; 419 m_startTime = { }; 420 m_startStretch = { }; 421 m_origVelocity = { }; 422 423 updateRubberBandingState(); 418 stopRubberbanding(); 424 419 return; 425 420 } … … 452 447 } else { 453 448 m_client.adjustScrollPositionToBoundsIfNecessary(); 454 455 stopSnapRubberbandTimer(); 456 m_stretchScrollForce = { }; 457 m_startTime = { }; 458 m_startStretch = { }; 459 m_origVelocity = { }; 449 stopRubberbanding(); 460 450 } 461 451 } else { … … 470 460 #endif 471 461 472 void ScrollController::scrollPositionChanged( )462 void ScrollController::scrollPositionChanged(ScrollType scrollType) 473 463 { 474 464 #if ENABLE(RUBBER_BANDING) 465 if (scrollType == ScrollType::Programmatic && !scrolledToRubberbandingEdge()) 466 stopRubberbanding(); 467 475 468 updateRubberBandingState(); 469 #else 470 UNUSED_PARAM(scrollType); 476 471 #endif 477 472 } … … 517 512 518 513 #if ENABLE(RUBBER_BANDING) 514 void ScrollController::stopRubberbanding() 515 { 516 stopSnapRubberbandTimer(); 517 m_stretchScrollForce = { }; 518 m_startTime = { }; 519 m_startStretch = { }; 520 m_origVelocity = { }; 521 updateRubberBandingState(); 522 } 523 519 524 void ScrollController::startSnapRubberbandTimer() 520 525 { … … 585 590 if (isRubberBanding == m_isRubberBanding) 586 591 return; 592 593 m_isRubberBanding = isRubberBanding; 594 if (m_isRubberBanding) 595 updateRubberBandingEdges(m_client.stretchAmount()); 596 else 597 m_rubberBandingEdges = { }; 598 599 m_client.rubberBandingStateChanged(m_isRubberBanding); 600 } 601 602 void ScrollController::updateRubberBandingEdges(IntSize clientStretch) 603 { 604 m_rubberBandingEdges.setLeft(clientStretch.width() < 0); 605 m_rubberBandingEdges.setRight(clientStretch.width() > 0); 606 607 m_rubberBandingEdges.setTop(clientStretch.height() < 0); 608 m_rubberBandingEdges.setBottom(clientStretch.height() > 0); 609 } 610 611 bool ScrollController::scrolledToRubberbandingEdge() const 612 { 613 auto pinnedEdges = m_client.edgePinnedState(); 587 614 588 m_isRubberBanding = isRubberBanding; 589 m_client.rubberBandingStateChanged(m_isRubberBanding); 615 for (auto side : allBoxSides) { 616 if (m_rubberBandingEdges[side] && !pinnedEdges[side]) 617 return false; 618 } 619 620 return true; 590 621 } 591 622 -
trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.h
r264151 r269373 148 148 bool allowsVerticalStretching(const PlatformWheelEvent&) const final; 149 149 bool pinnedInDirection(const FloatSize&) const final; 150 RectEdges<bool> edgePinnedState() const final; 150 151 bool canScrollHorizontally() const final; 151 152 bool canScrollVertically() const final; -
trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm
r264280 r269373 1320 1320 } 1321 1321 1322 RectEdges<bool> ScrollAnimatorMac::edgePinnedState() const 1323 { 1324 return m_scrollableArea.edgePinnedState(); 1325 } 1326 1322 1327 // FIXME: We should find a way to share some of the code from newGestureIsStarting(), isAlreadyPinnedInDirectionOfGesture(), 1323 1328 // allowsVerticalStretching(), and allowsHorizontalStretching() with the implementation in ScrollingTreeFrameScrollingNodeMac. -
trunk/Source/WebCore/platform/mock/ScrollAnimatorMock.h
r251173 r269373 50 50 IntSize stretchAmount() const override { return IntSize(); } 51 51 bool pinnedInDirection(const FloatSize&) const override { return false; } 52 RectEdges<bool> edgePinnedState() const override { return { }; } 52 53 bool canScrollHorizontally() const override { return false; } 53 54 bool canScrollVertically() const override { return false; }
Note: See TracChangeset
for help on using the changeset viewer.