Changeset 283335 in webkit
- Timestamp:
- Sep 30, 2021, 1:58:03 PM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 15 edited
-
ChangeLog (modified) (1 diff)
-
page/EventHandler.cpp (modified) (2 diffs)
-
page/scrolling/ScrollingTree.cpp (modified) (1 diff)
-
page/scrolling/ScrollingTree.h (modified) (1 diff)
-
page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.h (modified) (3 diffs)
-
page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm (modified) (7 diffs)
-
platform/ScrollAnimator.cpp (modified) (1 diff)
-
platform/ScrollAnimator.h (modified) (1 diff)
-
platform/ScrollableArea.cpp (modified) (2 diffs)
-
platform/ScrollableArea.h (modified) (1 diff)
-
platform/ScrollingEffectsController.h (modified) (4 diffs)
-
platform/ios/ScrollAnimatorIOS.mm (modified) (2 diffs)
-
platform/mac/ScrollAnimatorMac.h (modified) (1 diff)
-
platform/mac/ScrollAnimatorMac.mm (modified) (3 diffs)
-
platform/mac/ScrollingEffectsController.mm (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r283331 r283335 1 2021-09-29 Simon Fraser <simon.fraser@apple.com> 2 3 Replace the confusing isPinnedForScrollDelta() logic with code that uses BoxSide 4 https://bugs.webkit.org/show_bug.cgi?id=231004 5 6 Reviewed by Tim Horton. 7 8 isPinnedForScrollDelta()/isPinnedForScrollDeltaOnAxis() are ambiguous because it's 9 easy to interpret them as looking at the magnitude of the delta to determine whether 10 the delta will cause stretching on an edge. However, they don't do this; they simply 11 use the delta to choose which edge to look at, and the "is pinned" refers to whether 12 the scroller is already scrolled to that edge or stretching at that edge. 13 14 To reduce ambiguity, rewrite the code in terms of BoxSides, separating the code 15 that determines which BoxSide to look at for a given event delta from the code that 16 computed pinned state. It's now clearer that it's the caller's responsibility to 17 do "dominant axis" delta transformations too. 18 19 * page/EventHandler.cpp: 20 (WebCore::EventHandler::scrollableAreaCanHandleEvent): 21 * page/scrolling/ScrollingTree.cpp: 22 (WebCore::ScrollingTree::mainFrameCanRubberBandOnSide): 23 (WebCore::ScrollingTree::mainFrameCanRubberBandInDirection): Deleted. 24 * page/scrolling/ScrollingTree.h: 25 * page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.h: 26 * page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm: 27 (WebCore::ScrollingTreeScrollingNodeDelegateMac::allowsHorizontalStretching const): 28 (WebCore::ScrollingTreeScrollingNodeDelegateMac::allowsVerticalStretching const): 29 (WebCore::ScrollingTreeScrollingNodeDelegateMac::isPinnedOnSide const): Remove the old "scrollOffsetLimit" threshold. Our scroll offsets 30 are currently all integral so I don't think this did anything. 31 (WebCore::ScrollingTreeScrollingNodeDelegateMac::shouldRubberBandOnSide const): 32 (WebCore::ScrollingTreeScrollingNodeDelegateMac::isPinnedForScrollDeltaOnAxis const): Deleted. 33 (WebCore::ScrollingTreeScrollingNodeDelegateMac::isPinnedForScrollDelta const): Deleted. 34 (WebCore::ScrollingTreeScrollingNodeDelegateMac::shouldRubberBandInDirection const): Deleted. 35 * platform/ScrollAnimator.cpp: 36 (WebCore::ScrollAnimator::isPinnedOnSide const): 37 (WebCore::ScrollAnimator::isPinnedForScrollDelta const): Deleted. 38 * platform/ScrollAnimator.h: 39 * platform/ScrollableArea.cpp: 40 (WebCore::ScrollableArea::isPinnedOnSide const): 41 (WebCore::ScrollableArea::targetSideForScrollDelta): 42 (WebCore::ScrollableArea::isPinnedForScrollDeltaOnAxis const): Deleted. 43 (WebCore::ScrollableArea::isPinnedForScrollDelta const): Deleted. 44 * platform/ScrollableArea.h: 45 * platform/ScrollingEffectsController.h: 46 * platform/ios/ScrollAnimatorIOS.mm: 47 (WebCore::ScrollAnimatorIOS::determineScrollableAreaForTouchSequence): 48 * platform/mac/ScrollAnimatorMac.h: 49 * platform/mac/ScrollAnimatorMac.mm: 50 (WebCore::ScrollAnimatorMac::allowsVerticalStretching const): 51 (WebCore::ScrollAnimatorMac::allowsHorizontalStretching const): 52 (WebCore::ScrollAnimatorMac::shouldRubberBandOnSide const): 53 (WebCore::ScrollAnimatorMac::shouldRubberBandInDirection const): Deleted. 54 * platform/mac/ScrollingEffectsController.mm: 55 (WebCore::dominantAxisFavoringVertical): 56 (WebCore::deltaAlignedToAxis): 57 (WebCore::deltaAlignedToDominantAxis): 58 (WebCore::affectedSideOnDominantAxis): 59 (WebCore::isHorizontalSide): 60 (WebCore::isVerticalSide): 61 (WebCore::ScrollingEffectsController::handleWheelEvent): 62 (WebCore::ScrollingEffectsController::wheelDeltaBiasingTowardsVertical): 63 (WebCore::ScrollingEffectsController::shouldRubberBandOnSide const): 64 (WebCore::convertToProminentAxisFavoringVertical): Deleted. 65 (WebCore::ScrollingEffectsController::directionFromEvent): Deleted. 66 (WebCore::ScrollingEffectsController::shouldRubberBandInHorizontalDirection const): Deleted. 67 (WebCore::ScrollingEffectsController::shouldRubberBandInDirection const): Deleted. 68 1 69 2021-09-30 Devin Rousso <drousso@apple.com> 2 70 -
trunk/Source/WebCore/page/EventHandler.cpp
r282860 r283335 99 99 #include "ScrollLatchingController.h" 100 100 #include "Scrollbar.h" 101 #include "ScrollingEffectsController.h" 101 102 #include "SelectionRestorationMode.h" 102 103 #include "Settings.h" … … 3104 3105 #endif 3105 3106 3106 if (biasedDelta.height() && !scrollableArea.isPinnedForScrollDeltaOnAxis(-biasedDelta.height(), ScrollEventAxis::Vertical)) 3107 auto verticalSide = ScrollableArea::targetSideForScrollDelta(-biasedDelta, ScrollEventAxis::Vertical); 3108 if (verticalSide && !scrollableArea.isPinnedOnSide(*verticalSide)) 3107 3109 return true; 3108 3110 3109 if (biasedDelta.width() && !scrollableArea.isPinnedForScrollDeltaOnAxis(-biasedDelta.width(), ScrollEventAxis::Horizontal)) 3111 auto horizontalSide = ScrollableArea::targetSideForScrollDelta(-biasedDelta, ScrollEventAxis::Horizontal); 3112 if (horizontalSide && !scrollableArea.isPinnedOnSide(*horizontalSide)) 3110 3113 return true; 3111 3114 -
trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp
r278253 r283335 596 596 } 597 597 598 bool ScrollingTree::mainFrameCanRubberBand InDirection(ScrollDirection direction)598 bool ScrollingTree::mainFrameCanRubberBandOnSide(BoxSide side) 599 599 { 600 600 Locker locker { m_swipeStateLock }; 601 602 switch (direction) { 603 case ScrollUp: return m_swipeState.canRubberBand.top(); 604 case ScrollDown: return m_swipeState.canRubberBand.bottom(); 605 case ScrollLeft: return m_swipeState.canRubberBand.left(); 606 case ScrollRight: return m_swipeState.canRubberBand.right(); 607 }; 608 609 return false; 601 return m_swipeState.canRubberBand.at(side); 610 602 } 611 603 -
trunk/Source/WebCore/page/scrolling/ScrollingTree.h
r278923 r283335 174 174 // Can be called from any thread. Will update what edges allow rubber-banding. 175 175 WEBCORE_EXPORT void setMainFrameCanRubberBand(RectEdges<bool>); 176 bool mainFrameCanRubberBand InDirection(ScrollDirection);176 bool mainFrameCanRubberBandOnSide(BoxSide); 177 177 178 178 bool isHandlingProgrammaticScroll() const { return m_isHandlingProgrammaticScroll; } -
trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.h
r283019 r283335 69 69 70 70 private: 71 bool isPinnedForScrollDeltaOnAxis(float scrollDelta, ScrollEventAxis, float scrollLimit = 0) const;72 73 71 // ScrollingEffectsControllerClient. 74 72 std::unique_ptr<ScrollingEffectsControllerTimer> createTimer(Function<void()>&&) final; … … 79 77 bool allowsVerticalStretching(const PlatformWheelEvent&) const final; 80 78 IntSize stretchAmount() const final; 81 bool isPinnedForScrollDelta(const FloatSize&) const final; 79 bool isPinnedOnSide(BoxSide) const final; 80 82 81 RectEdges<bool> edgePinnedState() const final; 83 82 bool allowsHorizontalScrolling() const final; … … 86 85 ScrollBehaviorStatus scrollBehaviorStatus() const final { return m_scrollBehaviorStatus; } 87 86 88 bool shouldRubberBand InDirection(ScrollDirection) const final;87 bool shouldRubberBandOnSide(BoxSide) const final; 89 88 void immediateScrollBy(const FloatSize&) final; 90 89 void immediateScrollByWithoutContentEdgeConstraints(const FloatSize&) final; -
trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm
r283019 r283335 173 173 } 174 174 175 bool ScrollingTreeScrollingNodeDelegateMac::isPinnedForScrollDeltaOnAxis(float scrollDelta, ScrollEventAxis axis, float scrollLimit) const176 {177 auto scrollPosition = currentScrollPosition();178 switch (axis) {179 case ScrollEventAxis::Vertical:180 if (!allowsVerticalScrolling())181 return true;182 183 if (scrollDelta < 0) {184 auto topOffset = scrollPosition.y() - minimumScrollPosition().y();185 return topOffset <= scrollLimit;186 }187 188 if (scrollDelta > 0) {189 auto bottomOffset = maximumScrollPosition().y() - scrollPosition.y();190 return bottomOffset <= scrollLimit;191 }192 break;193 case ScrollEventAxis::Horizontal:194 if (!allowsHorizontalScrolling())195 return true;196 197 if (scrollDelta < 0) {198 auto leftOffset = scrollPosition.x() - minimumScrollPosition().x();199 return leftOffset <= scrollLimit;200 }201 202 if (scrollDelta > 0) {203 auto rightOffset = maximumScrollPosition().x() - scrollPosition.x();204 return rightOffset <= scrollLimit;205 }206 break;207 }208 209 return false;210 }211 212 175 std::unique_ptr<ScrollingEffectsControllerTimer> ScrollingTreeScrollingNodeDelegateMac::createTimer(Function<void()>&& function) 213 176 { … … 245 208 case ScrollElasticityAutomatic: { 246 209 bool scrollbarsAllowStretching = allowsHorizontalScrolling() || !allowsVerticalScrolling(); 247 bool eventPreventsStretching = wheelEvent.isGestureStart() && isPinnedForScrollDeltaOnAxis(-wheelEvent.deltaX(), ScrollEventAxis::Horizontal); 210 auto relevantSide = ScrollableArea::targetSideForScrollDelta(-wheelEvent.delta(), ScrollEventAxis::Horizontal); 211 bool eventPreventsStretching = wheelEvent.isGestureStart() && relevantSide && isPinnedOnSide(*relevantSide); 248 212 return scrollbarsAllowStretching && !eventPreventsStretching; 249 213 } … … 251 215 return false; 252 216 case ScrollElasticityAllowed: { 253 auto scrollDirection = ScrollingEffectsController::directionFromEvent(wheelEvent, ScrollEventAxis::Horizontal);254 if ( scrollDirection)255 return shouldRubberBand InDirection(scrollDirection.value());217 auto relevantSide = ScrollableArea::targetSideForScrollDelta(-wheelEvent.delta(), ScrollEventAxis::Horizontal); 218 if (relevantSide) 219 return shouldRubberBandOnSide(*relevantSide); 256 220 return true; 257 221 } … … 267 231 case ScrollElasticityAutomatic: { 268 232 bool scrollbarsAllowStretching = allowsVerticalScrolling() || !allowsHorizontalScrolling(); 269 bool eventPreventsStretching = wheelEvent.isGestureStart() && isPinnedForScrollDeltaOnAxis(-wheelEvent.deltaY(), ScrollEventAxis::Vertical); 233 auto relevantSide = ScrollableArea::targetSideForScrollDelta(-wheelEvent.delta(), ScrollEventAxis::Vertical); 234 bool eventPreventsStretching = wheelEvent.isGestureStart() && relevantSide && isPinnedOnSide(*relevantSide); 270 235 return scrollbarsAllowStretching && !eventPreventsStretching; 271 236 } … … 273 238 return false; 274 239 case ScrollElasticityAllowed: { 275 auto scrollDirection = ScrollingEffectsController::directionFromEvent(wheelEvent, ScrollEventAxis::Vertical);276 if ( scrollDirection)277 return shouldRubberBand InDirection(scrollDirection.value());240 auto relevantSide = ScrollableArea::targetSideForScrollDelta(-wheelEvent.delta(), ScrollEventAxis::Vertical); 241 if (relevantSide) 242 return shouldRubberBandOnSide(*relevantSide); 278 243 return true; 279 244 } … … 302 267 } 303 268 304 bool ScrollingTreeScrollingNodeDelegateMac::isPinnedForScrollDelta(const FloatSize& delta) const 305 { 306 // This "offset < 1" logic was added in r107488. Unclear if it's needed. 307 constexpr float scrollOffsetLimit = 1.0f - std::numeric_limits<float>::epsilon(); 308 309 if (fabsf(delta.height()) >= fabsf(delta.width())) 310 return isPinnedForScrollDeltaOnAxis(delta.height(), ScrollEventAxis::Vertical, scrollOffsetLimit); 311 312 if (delta.width()) 313 return isPinnedForScrollDeltaOnAxis(delta.width(), ScrollEventAxis::Horizontal, scrollOffsetLimit); 314 269 bool ScrollingTreeScrollingNodeDelegateMac::isPinnedOnSide(BoxSide side) const 270 { 271 switch (side) { 272 case BoxSide::Top: 273 if (!allowsVerticalScrolling()) 274 return true; 275 return currentScrollPosition().y() <= minimumScrollPosition().y(); 276 case BoxSide::Bottom: 277 if (!allowsVerticalScrolling()) 278 return true; 279 return currentScrollPosition().y() >= maximumScrollPosition().y(); 280 case BoxSide::Left: 281 if (!allowsHorizontalScrolling()) 282 return true; 283 return currentScrollPosition().x() <= minimumScrollPosition().x(); 284 case BoxSide::Right: 285 if (!allowsHorizontalScrolling()) 286 return true; 287 return currentScrollPosition().x() >= maximumScrollPosition().x(); 288 } 315 289 return false; 316 290 } … … 331 305 } 332 306 333 bool ScrollingTreeScrollingNodeDelegateMac::shouldRubberBand InDirection(ScrollDirection direction) const307 bool ScrollingTreeScrollingNodeDelegateMac::shouldRubberBandOnSide(BoxSide side) const 334 308 { 335 309 if (scrollingNode().isRootNode()) 336 return scrollingTree().mainFrameCanRubberBand InDirection(direction);337 338 switch ( direction) {339 case ScrollDirection::ScrollUp:340 case ScrollDirection::ScrollDown:310 return scrollingTree().mainFrameCanRubberBandOnSide(side); 311 312 switch (side) { 313 case BoxSide::Top: 314 case BoxSide::Bottom: 341 315 return allowsVerticalScrolling(); 342 case ScrollDirection::ScrollLeft:343 case ScrollDirection::ScrollRight:316 case BoxSide::Left: 317 case BoxSide::Right: 344 318 return allowsHorizontalScrolling(); 345 319 } -
trunk/Source/WebCore/platform/ScrollAnimator.cpp
r283019 r283335 309 309 } 310 310 311 bool ScrollAnimator::isPinnedForScrollDelta(const FloatSize& delta) const 312 { 313 if (fabsf(delta.height()) >= fabsf(delta.width())) 314 return m_scrollableArea.isPinnedForScrollDeltaOnAxis(delta.height(), ScrollEventAxis::Vertical); 315 316 if (delta.width()) 317 return m_scrollableArea.isPinnedForScrollDeltaOnAxis(delta.width(), ScrollEventAxis::Horizontal); 318 319 return false; 320 } 311 bool ScrollAnimator::isPinnedOnSide(BoxSide side) const 312 { 313 return m_scrollableArea.isPinnedOnSide(side); 314 } 315 321 316 #endif 322 317 -
trunk/Source/WebCore/platform/ScrollAnimator.h
r283019 r283335 155 155 IntSize stretchAmount() const final; 156 156 RectEdges<bool> edgePinnedState() const final; 157 bool isPinned ForScrollDelta(const FloatSize&) const final;157 bool isPinnedOnSide(BoxSide) const final; 158 158 #endif 159 159 -
trunk/Source/WebCore/platform/ScrollableArea.cpp
r282903 r283335 579 579 } 580 580 581 bool ScrollableArea::isPinnedForScrollDeltaOnAxis(float scrollDelta, ScrollEventAxis axis) const 582 { 583 auto scrollPosition = this->scrollPosition(); 584 switch (axis) { 585 case ScrollEventAxis::Vertical: 581 bool ScrollableArea::isPinnedOnSide(BoxSide side) const 582 { 583 switch (side) { 584 case BoxSide::Top: 586 585 if (!allowsVerticalScrolling()) 587 586 return true; 588 589 if (scrollDelta < 0) // top 590 return scrollPosition.y() <= minimumScrollPosition().y(); 591 592 if (scrollDelta > 0) // bottom 593 return scrollPosition.y() >= maximumScrollPosition().y(); 594 595 break; 596 case ScrollEventAxis::Horizontal: 587 return scrollPosition().y() <= minimumScrollPosition().y(); 588 case BoxSide::Bottom: 589 if (!allowsVerticalScrolling()) 590 return true; 591 return scrollPosition().y() >= maximumScrollPosition().y(); 592 case BoxSide::Left: 597 593 if (!allowsHorizontalScrolling()) 598 594 return true; 599 600 if (scrollDelta < 0) // left 601 return scrollPosition.x() <= minimumScrollPosition().x(); 602 603 if (scrollDelta > 0) // right 604 return scrollPosition.x() >= maximumScrollPosition().x(); 605 606 break; 607 } 608 595 return scrollPosition().x() <= minimumScrollPosition().x(); 596 case BoxSide::Right: 597 if (!allowsHorizontalScrolling()) 598 return true; 599 return scrollPosition().x() >= maximumScrollPosition().x(); 600 } 609 601 return false; 610 }611 612 bool ScrollableArea::isPinnedForScrollDelta(const FloatSize& scrollDelta) const613 {614 return (!scrollDelta.width() || isPinnedForScrollDeltaOnAxis(scrollDelta.width(), ScrollEventAxis::Horizontal))615 && (!scrollDelta.height() || isPinnedForScrollDeltaOnAxis(scrollDelta.height(), ScrollEventAxis::Vertical));616 602 } 617 603 … … 798 784 } 799 785 786 std::optional<BoxSide> ScrollableArea::targetSideForScrollDelta(FloatSize delta, ScrollEventAxis axis) 787 { 788 switch (axis) { 789 case ScrollEventAxis::Horizontal: 790 if (delta.width() < 0) 791 return BoxSide::Left; 792 793 if (delta.width() > 0) 794 return BoxSide::Right; 795 break; 796 797 case ScrollEventAxis::Vertical: 798 if (delta.height() < 0) 799 return BoxSide::Top; 800 801 if (delta.height() > 0) 802 return BoxSide::Bottom; 803 break; 804 } 805 806 return { }; 807 } 808 800 809 TextStream& operator<<(TextStream& ts, const ScrollableArea& scrollableArea) 801 810 { -
trunk/Source/WebCore/platform/ScrollableArea.h
r282862 r283335 318 318 WEBCORE_EXPORT static void computeScrollbarValueAndOverhang(float currentPosition, float totalSize, float visibleSize, float& doubleValue, float& overhangAmount); 319 319 320 bool isPinnedForScrollDeltaOnAxis(float scrollDelta, ScrollEventAxis) const; 321 bool isPinnedForScrollDelta(const FloatSize&) const; 320 static std::optional<BoxSide> targetSideForScrollDelta(FloatSize, ScrollEventAxis); 321 322 // "Pinned" means scrolled at or beyond the edge. 323 bool isPinnedOnSide(BoxSide) const; 322 324 RectEdges<bool> edgePinnedState() const; 323 325 -
trunk/Source/WebCore/platform/ScrollingEffectsController.h
r283296 r283335 86 86 virtual ScrollBehaviorStatus scrollBehaviorStatus() const = 0; 87 87 88 // FIXME: use ScrollClamping to collapse these to one. 88 89 virtual void immediateScrollBy(const FloatSize&) = 0; 89 90 virtual void immediateScrollByWithoutContentEdgeConstraints(const FloatSize&) = 0; … … 98 99 virtual IntSize stretchAmount() const = 0; 99 100 100 virtual bool isPinnedForScrollDelta(const FloatSize&) const = 0;101 101 // "Pinned" means scrolled at or beyond the edge. 102 virtual bool isPinnedOnSide(BoxSide) const = 0; 102 103 virtual RectEdges<bool> edgePinnedState() const = 0; 103 104 104 virtual bool shouldRubberBandInDirection(ScrollDirection) const = 0; 105 106 // FIXME: use ScrollClamping to collapse these to one. 105 virtual bool shouldRubberBandOnSide(BoxSide) const = 0; 106 107 107 virtual void willStartRubberBandSnapAnimation() { } 108 108 virtual void didStopRubberbandSnapAnimation() { } … … 168 168 bool handleWheelEvent(const PlatformWheelEvent&); 169 169 170 enum class WheelAxisBias { None, Vertical };171 static std::optional<ScrollDirection> directionFromEvent(const PlatformWheelEvent&, std::optional<ScrollEventAxis>, WheelAxisBias = WheelAxisBias::None);172 170 static FloatSize wheelDeltaBiasingTowardsVertical(const PlatformWheelEvent&); 173 171 … … 205 203 206 204 void snapRubberBand(); 207 bool shouldRubberBandInHorizontalDirection(const PlatformWheelEvent&) const; 208 bool shouldRubberBandInDirection(ScrollDirection) const; 205 bool shouldRubberBandOnSide(BoxSide) const; 209 206 bool isRubberBandInProgressInternal() const; 210 207 void updateRubberBandingState(); -
trunk/Source/WebCore/platform/ios/ScrollAnimatorIOS.mm
r282720 r283335 32 32 #import "RenderLayer.h" 33 33 #import "ScrollableArea.h" 34 #import "ScrollingEffectsController.h" 34 35 35 36 #if ENABLE(TOUCH_EVENTS) … … 164 165 ASSERT(!m_scrollableAreaForTouchSequence); 165 166 166 ScrollableArea* scrollableArea = &m_scrollableArea; 167 auto horizontalEdge = ScrollableArea::targetSideForScrollDelta(scrollDelta, ScrollEventAxis::Horizontal); 168 auto verticalEdge = ScrollableArea::targetSideForScrollDelta(scrollDelta, ScrollEventAxis::Vertical); 169 170 auto* scrollableArea = &m_scrollableArea; 167 171 while (true) { 168 if ( !scrollableArea->isPinnedForScrollDelta(scrollDelta))172 if (verticalEdge && !scrollableArea->isPinnedOnSide(*verticalEdge)) 169 173 break; 170 174 171 ScrollableArea* enclosingArea = scrollableArea->enclosingScrollableArea(); 175 if (horizontalEdge && !scrollableArea->isPinnedOnSide(*horizontalEdge)) 176 break; 177 178 auto* enclosingArea = scrollableArea->enclosingScrollableArea(); 172 179 if (!enclosingArea) 173 180 break; -
trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.h
r283019 r283335 60 60 bool allowsHorizontalStretching(const PlatformWheelEvent&) const final; 61 61 bool allowsVerticalStretching(const PlatformWheelEvent&) const final; 62 bool shouldRubberBand InDirection(ScrollDirection) const final;62 bool shouldRubberBandOnSide(BoxSide) const final; 63 63 }; 64 64 -
trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm
r283019 r283335 159 159 Scrollbar* vScroller = m_scrollableArea.verticalScrollbar(); 160 160 bool scrollbarsAllowStretching = ((vScroller && vScroller->enabled()) || (!hScroller || !hScroller->enabled())); 161 bool eventPreventsStretching = m_scrollableArea.hasScrollableOrRubberbandableAncestor() && wheelEvent.isGestureStart() && m_scrollableArea.isPinnedForScrollDeltaOnAxis(-wheelEvent.deltaY(), ScrollEventAxis::Vertical); 161 auto relevantSide = ScrollableArea::targetSideForScrollDelta(-wheelEvent.delta(), ScrollEventAxis::Vertical); 162 bool eventPreventsStretching = m_scrollableArea.hasScrollableOrRubberbandableAncestor() && wheelEvent.isGestureStart() && relevantSide && m_scrollableArea.isPinnedOnSide(*relevantSide); 162 163 if (!eventPreventsStretching) 163 164 eventPreventsStretching = gestureShouldBeginSnap(wheelEvent, ScrollEventAxis::Vertical, m_scrollableArea.snapOffsetsInfo()); … … 181 182 Scrollbar* vScroller = m_scrollableArea.verticalScrollbar(); 182 183 bool scrollbarsAllowStretching = ((hScroller && hScroller->enabled()) || (!vScroller || !vScroller->enabled())); 183 bool eventPreventsStretching = m_scrollableArea.hasScrollableOrRubberbandableAncestor() && wheelEvent.isGestureStart() && m_scrollableArea.isPinnedForScrollDeltaOnAxis(-wheelEvent.deltaX(), ScrollEventAxis::Horizontal); 184 auto relevantSide = ScrollableArea::targetSideForScrollDelta(-wheelEvent.delta(), ScrollEventAxis::Horizontal); 185 bool eventPreventsStretching = m_scrollableArea.hasScrollableOrRubberbandableAncestor() && wheelEvent.isGestureStart() && relevantSide && m_scrollableArea.isPinnedOnSide(*relevantSide); 184 186 if (!eventPreventsStretching) 185 187 eventPreventsStretching = gestureShouldBeginSnap(wheelEvent, ScrollEventAxis::Horizontal, m_scrollableArea.snapOffsetsInfo()); … … 196 198 } 197 199 198 bool ScrollAnimatorMac::shouldRubberBand InDirection(ScrollDirection) const200 bool ScrollAnimatorMac::shouldRubberBandOnSide(BoxSide) const 199 201 { 200 202 return false; -
trunk/Source/WebCore/platform/mac/ScrollingEffectsController.mm
r283296 r283335 84 84 } 85 85 86 87 static FloatSize convertToProminentAxisFavoringVertical(FloatSize delta) 86 static ScrollEventAxis dominantAxisFavoringVertical(FloatSize delta) 88 87 { 89 88 if (fabsf(delta.height()) >= fabsf(delta.width())) 90 return { 0, delta.height() }; 91 92 return { delta.width(), 0 }; 89 return ScrollEventAxis::Vertical; 90 91 return ScrollEventAxis::Horizontal; 92 } 93 94 static FloatSize deltaAlignedToAxis(FloatSize delta, ScrollEventAxis axis) 95 { 96 switch (axis) { 97 case ScrollEventAxis::Horizontal: return FloatSize { delta.width(), 0 }; 98 case ScrollEventAxis::Vertical: return FloatSize { 0, delta.height() }; 99 } 100 101 return { }; 102 } 103 104 static FloatSize deltaAlignedToDominantAxis(FloatSize delta) 105 { 106 auto dominantAxis = dominantAxisFavoringVertical(delta); 107 return deltaAlignedToAxis(delta, dominantAxis); 108 } 109 110 static std::optional<BoxSide> affectedSideOnDominantAxis(FloatSize delta) 111 { 112 auto dominantAxis = dominantAxisFavoringVertical(delta); 113 return ScrollableArea::targetSideForScrollDelta(delta, dominantAxis); 114 } 115 116 static bool isHorizontalSide(std::optional<BoxSide> side) 117 { 118 return side && (*side == BoxSide::Left || *side == BoxSide::Right); 119 } 120 121 static bool isVerticalSide(std::optional<BoxSide> side) 122 { 123 return side && (*side == BoxSide::Top || *side == BoxSide::Bottom); 93 124 } 94 125 … … 103 134 if (wheelEvent.phase() == PlatformWheelEventPhase::Began) { 104 135 // FIXME: Trying to decide if a gesture is horizontal or vertical at the "began" phase is very error-prone. 105 auto direction = directionFromEvent(wheelEvent, ScrollEventAxis::Horizontal);106 if ( direction && m_client.isPinnedForScrollDelta(FloatSize(-wheelEvent.deltaX(), 0)) && !shouldRubberBandInDirection(direction.value()))136 auto horizontalSide = ScrollableArea::targetSideForScrollDelta(-wheelEvent.delta(), ScrollEventAxis::Horizontal); 137 if (horizontalSide && m_client.isPinnedOnSide(*horizontalSide) && !shouldRubberBandOnSide(*horizontalSide)) 107 138 return false; 108 139 109 direction = directionFromEvent(wheelEvent, ScrollEventAxis::Vertical);110 if ( direction && m_client.isPinnedForScrollDelta(FloatSize(0, -wheelEvent.deltaY())) && !shouldRubberBandInDirection(direction.value()))140 auto verticalSide = ScrollableArea::targetSideForScrollDelta(-wheelEvent.delta(), ScrollEventAxis::Vertical); 141 if (verticalSide && m_client.isPinnedOnSide(*verticalSide) && !shouldRubberBandOnSide(*verticalSide)) 111 142 return false; 112 143 … … 156 187 delta += eventCoalescedDelta; 157 188 158 delta = convertToProminentAxisFavoringVertical(delta); 189 // FIXME: All of the code below could be simplified since predominantAxis is known, and we zero out the delta on the other axis. 190 auto affectedSide = affectedSideOnDominantAxis(delta); 191 159 192 float deltaX = delta.width(); 160 193 float deltaY = delta.height(); … … 178 211 179 212 if (isVerticallyStretched) { 180 if (!isHorizontallyStretched && m_client.isPinnedForScrollDelta(FloatSize(deltaX, 0))) {213 if (!isHorizontallyStretched && isHorizontalSide(affectedSide) && m_client.isPinnedOnSide(*affectedSide)) { 181 214 // Stretching only in the vertical. 182 215 if (deltaY && (fabsf(deltaX / deltaY) < rubberbandDirectionLockStretchRatio)) … … 190 223 } else if (isHorizontallyStretched) { 191 224 // Stretching only in the horizontal. 192 if ( m_client.isPinnedForScrollDelta(FloatSize(0, deltaY))) {225 if (isVerticalSide(affectedSide) && m_client.isPinnedOnSide(*affectedSide)) { 193 226 if (deltaX && (fabsf(deltaY / deltaX) < rubberbandDirectionLockStretchRatio)) 194 227 deltaY = 0; … … 201 234 } else { 202 235 // Not stretching at all yet. 203 if ( m_client.isPinnedForScrollDelta(FloatSize(deltaX, deltaY))) {236 if (affectedSide && m_client.isPinnedOnSide(*affectedSide)) { 204 237 if (fabsf(deltaY) >= fabsf(deltaX)) { 205 238 if (fabsf(deltaX) < rubberbandMinimumRequiredDeltaBeforeStretch) { … … 234 267 } 235 268 } else { 269 affectedSide = affectedSideOnDominantAxis({ deltaX, deltaY }); 236 270 if (deltaX) { 237 271 if (!m_client.allowsHorizontalStretching(wheelEvent)) { … … 239 273 eventCoalescedDelta.setWidth(0); 240 274 handled = false; 241 } else if (!isHorizontallyStretched && !m_client.isPinned ForScrollDelta(FloatSize(deltaX, 0))) {275 } else if (!isHorizontallyStretched && !m_client.isPinnedOnSide(*affectedSide)) { 242 276 deltaX *= scrollWheelMultiplier(); 243 277 … … 252 286 eventCoalescedDelta.setHeight(0); 253 287 handled = false; 254 } else if (!isVerticallyStretched && !m_client.isPinned ForScrollDelta(FloatSize(0, deltaY))) {288 } else if (!isVerticallyStretched && !m_client.isPinnedOnSide(*affectedSide)) { 255 289 deltaY *= scrollWheelMultiplier(); 256 290 … … 263 297 264 298 if (m_momentumScrollInProgress) { 265 if ((m_client.isPinnedForScrollDelta(eventCoalescedDelta) || eventCoalescedDelta.isZero()) && m_lastMomentumScrollTimestamp) { 299 auto sideAffectedByEventDelta = affectedSideOnDominantAxis(eventCoalescedDelta); 300 if ((!sideAffectedByEventDelta || m_client.isPinnedOnSide(*sideAffectedByEventDelta)) && m_lastMomentumScrollTimestamp) { 266 301 m_ignoreMomentumScrolls = true; 267 302 m_momentumScrollInProgress = false; … … 294 329 FloatSize ScrollingEffectsController::wheelDeltaBiasingTowardsVertical(const PlatformWheelEvent& wheelEvent) 295 330 { 296 return convertToProminentAxisFavoringVertical(wheelEvent.delta()); 297 } 298 299 std::optional<ScrollDirection> ScrollingEffectsController::directionFromEvent(const PlatformWheelEvent& wheelEvent, std::optional<ScrollEventAxis> axis, WheelAxisBias bias) 300 { 301 // FIXME: It's impossible to infer direction from a single event, since the start of a gesture is either zero or 302 // has small deltas on both axes. 303 304 auto wheelDelta = FloatSize { wheelEvent.deltaX(), wheelEvent.deltaY() }; 305 if (bias == WheelAxisBias::Vertical) 306 wheelDelta = wheelDeltaBiasingTowardsVertical(wheelEvent); 307 308 if (axis) { 309 switch (axis.value()) { 310 case ScrollEventAxis::Vertical: 311 if (wheelDelta.height() < 0) 312 return ScrollDown; 313 314 if (wheelDelta.height() > 0) 315 return ScrollUp; 316 break; 317 318 case ScrollEventAxis::Horizontal: 319 if (wheelDelta.width() > 0) 320 return ScrollLeft; 321 322 if (wheelDelta.width() < 0) 323 return ScrollRight; 324 } 325 326 return std::nullopt; 327 } 328 329 // Check Y first because vertical scrolling dominates. 330 if (wheelDelta.height() < 0) 331 return ScrollDown; 332 333 if (wheelDelta.height() > 0) 334 return ScrollUp; 335 336 if (wheelDelta.width() > 0) 337 return ScrollLeft; 338 339 if (wheelDelta.width() < 0) 340 return ScrollRight; 341 342 return std::nullopt; 331 return deltaAlignedToDominantAxis(wheelEvent.delta()); 343 332 } 344 333 … … 494 483 } 495 484 496 bool ScrollingEffectsController::shouldRubberBandInHorizontalDirection(const PlatformWheelEvent& wheelEvent) const 497 { 498 auto direction = directionFromEvent(wheelEvent, ScrollEventAxis::Horizontal); 499 if (direction) 500 return shouldRubberBandInDirection(direction.value()); 501 502 return true; 503 } 504 505 bool ScrollingEffectsController::shouldRubberBandInDirection(ScrollDirection direction) const 506 { 507 return m_client.shouldRubberBandInDirection(direction); 485 bool ScrollingEffectsController::shouldRubberBandOnSide(BoxSide side) const 486 { 487 return m_client.shouldRubberBandOnSide(side); 508 488 } 509 489
Note:
See TracChangeset
for help on using the changeset viewer.