Diff
Modified: trunk/Source/WebCore/ChangeLog (283334 => 283335)
--- trunk/Source/WebCore/ChangeLog 2021-09-30 20:51:45 UTC (rev 283334)
+++ trunk/Source/WebCore/ChangeLog 2021-09-30 20:58:03 UTC (rev 283335)
@@ -1,3 +1,71 @@
+2021-09-29 Simon Fraser <simon.fra...@apple.com>
+
+ Replace the confusing isPinnedForScrollDelta() logic with code that uses BoxSide
+ https://bugs.webkit.org/show_bug.cgi?id=231004
+
+ Reviewed by Tim Horton.
+
+ isPinnedForScrollDelta()/isPinnedForScrollDeltaOnAxis() are ambiguous because it's
+ easy to interpret them as looking at the magnitude of the delta to determine whether
+ the delta will cause stretching on an edge. However, they don't do this; they simply
+ use the delta to choose which edge to look at, and the "is pinned" refers to whether
+ the scroller is already scrolled to that edge or stretching at that edge.
+
+ To reduce ambiguity, rewrite the code in terms of BoxSides, separating the code
+ that determines which BoxSide to look at for a given event delta from the code that
+ computed pinned state. It's now clearer that it's the caller's responsibility to
+ do "dominant axis" delta transformations too.
+
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::scrollableAreaCanHandleEvent):
+ * page/scrolling/ScrollingTree.cpp:
+ (WebCore::ScrollingTree::mainFrameCanRubberBandOnSide):
+ (WebCore::ScrollingTree::mainFrameCanRubberBandInDirection): Deleted.
+ * page/scrolling/ScrollingTree.h:
+ * page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.h:
+ * page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm:
+ (WebCore::ScrollingTreeScrollingNodeDelegateMac::allowsHorizontalStretching const):
+ (WebCore::ScrollingTreeScrollingNodeDelegateMac::allowsVerticalStretching const):
+ (WebCore::ScrollingTreeScrollingNodeDelegateMac::isPinnedOnSide const): Remove the old "scrollOffsetLimit" threshold. Our scroll offsets
+ are currently all integral so I don't think this did anything.
+ (WebCore::ScrollingTreeScrollingNodeDelegateMac::shouldRubberBandOnSide const):
+ (WebCore::ScrollingTreeScrollingNodeDelegateMac::isPinnedForScrollDeltaOnAxis const): Deleted.
+ (WebCore::ScrollingTreeScrollingNodeDelegateMac::isPinnedForScrollDelta const): Deleted.
+ (WebCore::ScrollingTreeScrollingNodeDelegateMac::shouldRubberBandInDirection const): Deleted.
+ * platform/ScrollAnimator.cpp:
+ (WebCore::ScrollAnimator::isPinnedOnSide const):
+ (WebCore::ScrollAnimator::isPinnedForScrollDelta const): Deleted.
+ * platform/ScrollAnimator.h:
+ * platform/ScrollableArea.cpp:
+ (WebCore::ScrollableArea::isPinnedOnSide const):
+ (WebCore::ScrollableArea::targetSideForScrollDelta):
+ (WebCore::ScrollableArea::isPinnedForScrollDeltaOnAxis const): Deleted.
+ (WebCore::ScrollableArea::isPinnedForScrollDelta const): Deleted.
+ * platform/ScrollableArea.h:
+ * platform/ScrollingEffectsController.h:
+ * platform/ios/ScrollAnimatorIOS.mm:
+ (WebCore::ScrollAnimatorIOS::determineScrollableAreaForTouchSequence):
+ * platform/mac/ScrollAnimatorMac.h:
+ * platform/mac/ScrollAnimatorMac.mm:
+ (WebCore::ScrollAnimatorMac::allowsVerticalStretching const):
+ (WebCore::ScrollAnimatorMac::allowsHorizontalStretching const):
+ (WebCore::ScrollAnimatorMac::shouldRubberBandOnSide const):
+ (WebCore::ScrollAnimatorMac::shouldRubberBandInDirection const): Deleted.
+ * platform/mac/ScrollingEffectsController.mm:
+ (WebCore::dominantAxisFavoringVertical):
+ (WebCore::deltaAlignedToAxis):
+ (WebCore::deltaAlignedToDominantAxis):
+ (WebCore::affectedSideOnDominantAxis):
+ (WebCore::isHorizontalSide):
+ (WebCore::isVerticalSide):
+ (WebCore::ScrollingEffectsController::handleWheelEvent):
+ (WebCore::ScrollingEffectsController::wheelDeltaBiasingTowardsVertical):
+ (WebCore::ScrollingEffectsController::shouldRubberBandOnSide const):
+ (WebCore::convertToProminentAxisFavoringVertical): Deleted.
+ (WebCore::ScrollingEffectsController::directionFromEvent): Deleted.
+ (WebCore::ScrollingEffectsController::shouldRubberBandInHorizontalDirection const): Deleted.
+ (WebCore::ScrollingEffectsController::shouldRubberBandInDirection const): Deleted.
+
2021-09-30 Devin Rousso <drou...@apple.com>
[GPU Process] support rendering Apple Pay buttons
Modified: trunk/Source/WebCore/page/EventHandler.cpp (283334 => 283335)
--- trunk/Source/WebCore/page/EventHandler.cpp 2021-09-30 20:51:45 UTC (rev 283334)
+++ trunk/Source/WebCore/page/EventHandler.cpp 2021-09-30 20:58:03 UTC (rev 283335)
@@ -98,6 +98,7 @@
#include "ScrollAnimator.h"
#include "ScrollLatchingController.h"
#include "Scrollbar.h"
+#include "ScrollingEffectsController.h"
#include "SelectionRestorationMode.h"
#include "Settings.h"
#include "ShadowRoot.h"
@@ -3103,10 +3104,12 @@
auto biasedDelta = wheelEvent.delta();
#endif
- if (biasedDelta.height() && !scrollableArea.isPinnedForScrollDeltaOnAxis(-biasedDelta.height(), ScrollEventAxis::Vertical))
+ auto verticalSide = ScrollableArea::targetSideForScrollDelta(-biasedDelta, ScrollEventAxis::Vertical);
+ if (verticalSide && !scrollableArea.isPinnedOnSide(*verticalSide))
return true;
- if (biasedDelta.width() && !scrollableArea.isPinnedForScrollDeltaOnAxis(-biasedDelta.width(), ScrollEventAxis::Horizontal))
+ auto horizontalSide = ScrollableArea::targetSideForScrollDelta(-biasedDelta, ScrollEventAxis::Horizontal);
+ if (horizontalSide && !scrollableArea.isPinnedOnSide(*horizontalSide))
return true;
return false;
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp (283334 => 283335)
--- trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp 2021-09-30 20:51:45 UTC (rev 283334)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp 2021-09-30 20:58:03 UTC (rev 283335)
@@ -595,18 +595,10 @@
m_swipeState.canRubberBand = canRubberBand;
}
-bool ScrollingTree::mainFrameCanRubberBandInDirection(ScrollDirection direction)
+bool ScrollingTree::mainFrameCanRubberBandOnSide(BoxSide side)
{
Locker locker { m_swipeStateLock };
-
- switch (direction) {
- case ScrollUp: return m_swipeState.canRubberBand.top();
- case ScrollDown: return m_swipeState.canRubberBand.bottom();
- case ScrollLeft: return m_swipeState.canRubberBand.left();
- case ScrollRight: return m_swipeState.canRubberBand.right();
- };
-
- return false;
+ return m_swipeState.canRubberBand.at(side);
}
void ScrollingTree::addPendingScrollUpdate(ScrollUpdate&& update)
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.h (283334 => 283335)
--- trunk/Source/WebCore/page/scrolling/ScrollingTree.h 2021-09-30 20:51:45 UTC (rev 283334)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.h 2021-09-30 20:58:03 UTC (rev 283335)
@@ -173,7 +173,7 @@
// Can be called from any thread. Will update what edges allow rubber-banding.
WEBCORE_EXPORT void setMainFrameCanRubberBand(RectEdges<bool>);
- bool mainFrameCanRubberBandInDirection(ScrollDirection);
+ bool mainFrameCanRubberBandOnSide(BoxSide);
bool isHandlingProgrammaticScroll() const { return m_isHandlingProgrammaticScroll; }
void setIsHandlingProgrammaticScroll(bool isHandlingProgrammaticScroll) { m_isHandlingProgrammaticScroll = isHandlingProgrammaticScroll; }
Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.h (283334 => 283335)
--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.h 2021-09-30 20:51:45 UTC (rev 283334)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.h 2021-09-30 20:58:03 UTC (rev 283335)
@@ -68,8 +68,6 @@
void removeWheelEventTestCompletionDeferralForReason(WheelEventTestMonitor::ScrollableAreaIdentifier, WheelEventTestMonitor::DeferReason) const override;
private:
- bool isPinnedForScrollDeltaOnAxis(float scrollDelta, ScrollEventAxis, float scrollLimit = 0) const;
-
// ScrollingEffectsControllerClient.
std::unique_ptr<ScrollingEffectsControllerTimer> createTimer(Function<void()>&&) final;
void startAnimationCallback(ScrollingEffectsController&) final;
@@ -78,7 +76,8 @@
bool allowsHorizontalStretching(const PlatformWheelEvent&) const final;
bool allowsVerticalStretching(const PlatformWheelEvent&) const final;
IntSize stretchAmount() const final;
- bool isPinnedForScrollDelta(const FloatSize&) const final;
+ bool isPinnedOnSide(BoxSide) const final;
+
RectEdges<bool> edgePinnedState() const final;
bool allowsHorizontalScrolling() const final;
bool allowsVerticalScrolling() const final;
@@ -85,7 +84,7 @@
void setScrollBehaviorStatus(ScrollBehaviorStatus status) final { m_scrollBehaviorStatus = status; }
ScrollBehaviorStatus scrollBehaviorStatus() const final { return m_scrollBehaviorStatus; }
- bool shouldRubberBandInDirection(ScrollDirection) const final;
+ bool shouldRubberBandOnSide(BoxSide) const final;
void immediateScrollBy(const FloatSize&) final;
void immediateScrollByWithoutContentEdgeConstraints(const FloatSize&) final;
void didStopRubberbandSnapAnimation() final;
Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm (283334 => 283335)
--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm 2021-09-30 20:51:45 UTC (rev 283334)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm 2021-09-30 20:58:03 UTC (rev 283335)
@@ -172,43 +172,6 @@
return m_scrollController.isScrollSnapInProgress();
}
-bool ScrollingTreeScrollingNodeDelegateMac::isPinnedForScrollDeltaOnAxis(float scrollDelta, ScrollEventAxis axis, float scrollLimit) const
-{
- auto scrollPosition = currentScrollPosition();
- switch (axis) {
- case ScrollEventAxis::Vertical:
- if (!allowsVerticalScrolling())
- return true;
-
- if (scrollDelta < 0) {
- auto topOffset = scrollPosition.y() - minimumScrollPosition().y();
- return topOffset <= scrollLimit;
- }
-
- if (scrollDelta > 0) {
- auto bottomOffset = maximumScrollPosition().y() - scrollPosition.y();
- return bottomOffset <= scrollLimit;
- }
- break;
- case ScrollEventAxis::Horizontal:
- if (!allowsHorizontalScrolling())
- return true;
-
- if (scrollDelta < 0) {
- auto leftOffset = scrollPosition.x() - minimumScrollPosition().x();
- return leftOffset <= scrollLimit;
- }
-
- if (scrollDelta > 0) {
- auto rightOffset = maximumScrollPosition().x() - scrollPosition.x();
- return rightOffset <= scrollLimit;
- }
- break;
- }
-
- return false;
-}
-
std::unique_ptr<ScrollingEffectsControllerTimer> ScrollingTreeScrollingNodeDelegateMac::createTimer(Function<void()>&& function)
{
return WTF::makeUnique<ScrollingEffectsControllerTimer>(RunLoop::current(), [function = WTFMove(function), protectedNode = Ref { scrollingNode() }] {
@@ -244,15 +207,16 @@
switch (horizontalScrollElasticity()) {
case ScrollElasticityAutomatic: {
bool scrollbarsAllowStretching = allowsHorizontalScrolling() || !allowsVerticalScrolling();
- bool eventPreventsStretching = wheelEvent.isGestureStart() && isPinnedForScrollDeltaOnAxis(-wheelEvent.deltaX(), ScrollEventAxis::Horizontal);
+ auto relevantSide = ScrollableArea::targetSideForScrollDelta(-wheelEvent.delta(), ScrollEventAxis::Horizontal);
+ bool eventPreventsStretching = wheelEvent.isGestureStart() && relevantSide && isPinnedOnSide(*relevantSide);
return scrollbarsAllowStretching && !eventPreventsStretching;
}
case ScrollElasticityNone:
return false;
case ScrollElasticityAllowed: {
- auto scrollDirection = ScrollingEffectsController::directionFromEvent(wheelEvent, ScrollEventAxis::Horizontal);
- if (scrollDirection)
- return shouldRubberBandInDirection(scrollDirection.value());
+ auto relevantSide = ScrollableArea::targetSideForScrollDelta(-wheelEvent.delta(), ScrollEventAxis::Horizontal);
+ if (relevantSide)
+ return shouldRubberBandOnSide(*relevantSide);
return true;
}
}
@@ -266,15 +230,16 @@
switch (verticalScrollElasticity()) {
case ScrollElasticityAutomatic: {
bool scrollbarsAllowStretching = allowsVerticalScrolling() || !allowsHorizontalScrolling();
- bool eventPreventsStretching = wheelEvent.isGestureStart() && isPinnedForScrollDeltaOnAxis(-wheelEvent.deltaY(), ScrollEventAxis::Vertical);
+ auto relevantSide = ScrollableArea::targetSideForScrollDelta(-wheelEvent.delta(), ScrollEventAxis::Vertical);
+ bool eventPreventsStretching = wheelEvent.isGestureStart() && relevantSide && isPinnedOnSide(*relevantSide);
return scrollbarsAllowStretching && !eventPreventsStretching;
}
case ScrollElasticityNone:
return false;
case ScrollElasticityAllowed: {
- auto scrollDirection = ScrollingEffectsController::directionFromEvent(wheelEvent, ScrollEventAxis::Vertical);
- if (scrollDirection)
- return shouldRubberBandInDirection(scrollDirection.value());
+ auto relevantSide = ScrollableArea::targetSideForScrollDelta(-wheelEvent.delta(), ScrollEventAxis::Vertical);
+ if (relevantSide)
+ return shouldRubberBandOnSide(*relevantSide);
return true;
}
}
@@ -301,17 +266,26 @@
return stretch;
}
-bool ScrollingTreeScrollingNodeDelegateMac::isPinnedForScrollDelta(const FloatSize& delta) const
+bool ScrollingTreeScrollingNodeDelegateMac::isPinnedOnSide(BoxSide side) const
{
- // This "offset < 1" logic was added in r107488. Unclear if it's needed.
- constexpr float scrollOffsetLimit = 1.0f - std::numeric_limits<float>::epsilon();
-
- if (fabsf(delta.height()) >= fabsf(delta.width()))
- return isPinnedForScrollDeltaOnAxis(delta.height(), ScrollEventAxis::Vertical, scrollOffsetLimit);
-
- if (delta.width())
- return isPinnedForScrollDeltaOnAxis(delta.width(), ScrollEventAxis::Horizontal, scrollOffsetLimit);
-
+ switch (side) {
+ case BoxSide::Top:
+ if (!allowsVerticalScrolling())
+ return true;
+ return currentScrollPosition().y() <= minimumScrollPosition().y();
+ case BoxSide::Bottom:
+ if (!allowsVerticalScrolling())
+ return true;
+ return currentScrollPosition().y() >= maximumScrollPosition().y();
+ case BoxSide::Left:
+ if (!allowsHorizontalScrolling())
+ return true;
+ return currentScrollPosition().x() <= minimumScrollPosition().x();
+ case BoxSide::Right:
+ if (!allowsHorizontalScrolling())
+ return true;
+ return currentScrollPosition().x() >= maximumScrollPosition().x();
+ }
return false;
}
@@ -330,17 +304,17 @@
return ScrollingTreeScrollingNodeDelegate::allowsVerticalScrolling();
}
-bool ScrollingTreeScrollingNodeDelegateMac::shouldRubberBandInDirection(ScrollDirection direction) const
+bool ScrollingTreeScrollingNodeDelegateMac::shouldRubberBandOnSide(BoxSide side) const
{
if (scrollingNode().isRootNode())
- return scrollingTree().mainFrameCanRubberBandInDirection(direction);
+ return scrollingTree().mainFrameCanRubberBandOnSide(side);
- switch (direction) {
- case ScrollDirection::ScrollUp:
- case ScrollDirection::ScrollDown:
+ switch (side) {
+ case BoxSide::Top:
+ case BoxSide::Bottom:
return allowsVerticalScrolling();
- case ScrollDirection::ScrollLeft:
- case ScrollDirection::ScrollRight:
+ case BoxSide::Left:
+ case BoxSide::Right:
return allowsHorizontalScrolling();
}
return true;
Modified: trunk/Source/WebCore/platform/ScrollAnimator.cpp (283334 => 283335)
--- trunk/Source/WebCore/platform/ScrollAnimator.cpp 2021-09-30 20:51:45 UTC (rev 283334)
+++ trunk/Source/WebCore/platform/ScrollAnimator.cpp 2021-09-30 20:58:03 UTC (rev 283335)
@@ -308,16 +308,11 @@
return m_scrollableArea.edgePinnedState();
}
-bool ScrollAnimator::isPinnedForScrollDelta(const FloatSize& delta) const
+bool ScrollAnimator::isPinnedOnSide(BoxSide side) const
{
- if (fabsf(delta.height()) >= fabsf(delta.width()))
- return m_scrollableArea.isPinnedForScrollDeltaOnAxis(delta.height(), ScrollEventAxis::Vertical);
+ return m_scrollableArea.isPinnedOnSide(side);
+}
- if (delta.width())
- return m_scrollableArea.isPinnedForScrollDeltaOnAxis(delta.width(), ScrollEventAxis::Horizontal);
-
- return false;
-}
#endif
void ScrollAnimator::adjustScrollPositionToBoundsIfNecessary()
Modified: trunk/Source/WebCore/platform/ScrollAnimator.h (283334 => 283335)
--- trunk/Source/WebCore/platform/ScrollAnimator.h 2021-09-30 20:51:45 UTC (rev 283334)
+++ trunk/Source/WebCore/platform/ScrollAnimator.h 2021-09-30 20:58:03 UTC (rev 283335)
@@ -154,7 +154,7 @@
#if HAVE(RUBBER_BANDING)
IntSize stretchAmount() const final;
RectEdges<bool> edgePinnedState() const final;
- bool isPinnedForScrollDelta(const FloatSize&) const final;
+ bool isPinnedOnSide(BoxSide) const final;
#endif
#if PLATFORM(MAC)
Modified: trunk/Source/WebCore/platform/ScrollableArea.cpp (283334 => 283335)
--- trunk/Source/WebCore/platform/ScrollableArea.cpp 2021-09-30 20:51:45 UTC (rev 283334)
+++ trunk/Source/WebCore/platform/ScrollableArea.cpp 2021-09-30 20:58:03 UTC (rev 283335)
@@ -578,43 +578,29 @@
scrollAnimator->scrollToPositionWithAnimation(position);
}
-bool ScrollableArea::isPinnedForScrollDeltaOnAxis(float scrollDelta, ScrollEventAxis axis) const
+bool ScrollableArea::isPinnedOnSide(BoxSide side) const
{
- auto scrollPosition = this->scrollPosition();
- switch (axis) {
- case ScrollEventAxis::Vertical:
+ switch (side) {
+ case BoxSide::Top:
if (!allowsVerticalScrolling())
return true;
-
- if (scrollDelta < 0) // top
- return scrollPosition.y() <= minimumScrollPosition().y();
-
- if (scrollDelta > 0) // bottom
- return scrollPosition.y() >= maximumScrollPosition().y();
-
- break;
- case ScrollEventAxis::Horizontal:
+ return scrollPosition().y() <= minimumScrollPosition().y();
+ case BoxSide::Bottom:
+ if (!allowsVerticalScrolling())
+ return true;
+ return scrollPosition().y() >= maximumScrollPosition().y();
+ case BoxSide::Left:
if (!allowsHorizontalScrolling())
return true;
-
- if (scrollDelta < 0) // left
- return scrollPosition.x() <= minimumScrollPosition().x();
-
- if (scrollDelta > 0) // right
- return scrollPosition.x() >= maximumScrollPosition().x();
-
- break;
+ return scrollPosition().x() <= minimumScrollPosition().x();
+ case BoxSide::Right:
+ if (!allowsHorizontalScrolling())
+ return true;
+ return scrollPosition().x() >= maximumScrollPosition().x();
}
-
return false;
}
-bool ScrollableArea::isPinnedForScrollDelta(const FloatSize& scrollDelta) const
-{
- return (!scrollDelta.width() || isPinnedForScrollDeltaOnAxis(scrollDelta.width(), ScrollEventAxis::Horizontal))
- && (!scrollDelta.height() || isPinnedForScrollDeltaOnAxis(scrollDelta.height(), ScrollEventAxis::Vertical));
-}
-
RectEdges<bool> ScrollableArea::edgePinnedState() const
{
auto scrollPosition = this->scrollPosition();
@@ -797,6 +783,29 @@
}
}
+std::optional<BoxSide> ScrollableArea::targetSideForScrollDelta(FloatSize delta, ScrollEventAxis axis)
+{
+ switch (axis) {
+ case ScrollEventAxis::Horizontal:
+ if (delta.width() < 0)
+ return BoxSide::Left;
+
+ if (delta.width() > 0)
+ return BoxSide::Right;
+ break;
+
+ case ScrollEventAxis::Vertical:
+ if (delta.height() < 0)
+ return BoxSide::Top;
+
+ if (delta.height() > 0)
+ return BoxSide::Bottom;
+ break;
+ }
+
+ return { };
+}
+
TextStream& operator<<(TextStream& ts, const ScrollableArea& scrollableArea)
{
ts << scrollableArea.debugDescription();
Modified: trunk/Source/WebCore/platform/ScrollableArea.h (283334 => 283335)
--- trunk/Source/WebCore/platform/ScrollableArea.h 2021-09-30 20:51:45 UTC (rev 283334)
+++ trunk/Source/WebCore/platform/ScrollableArea.h 2021-09-30 20:58:03 UTC (rev 283335)
@@ -317,8 +317,10 @@
// This function is static so that it can be called from the main thread or the scrolling thread.
WEBCORE_EXPORT static void computeScrollbarValueAndOverhang(float currentPosition, float totalSize, float visibleSize, float& doubleValue, float& overhangAmount);
- bool isPinnedForScrollDeltaOnAxis(float scrollDelta, ScrollEventAxis) const;
- bool isPinnedForScrollDelta(const FloatSize&) const;
+ static std::optional<BoxSide> targetSideForScrollDelta(FloatSize, ScrollEventAxis);
+
+ // "Pinned" means scrolled at or beyond the edge.
+ bool isPinnedOnSide(BoxSide) const;
RectEdges<bool> edgePinnedState() const;
// True if scrolling happens by moving compositing layers.
Modified: trunk/Source/WebCore/platform/ScrollingEffectsController.h (283334 => 283335)
--- trunk/Source/WebCore/platform/ScrollingEffectsController.h 2021-09-30 20:51:45 UTC (rev 283334)
+++ trunk/Source/WebCore/platform/ScrollingEffectsController.h 2021-09-30 20:58:03 UTC (rev 283335)
@@ -85,6 +85,7 @@
virtual void setScrollBehaviorStatus(ScrollBehaviorStatus) = 0;
virtual ScrollBehaviorStatus scrollBehaviorStatus() const = 0;
+ // FIXME: use ScrollClamping to collapse these to one.
virtual void immediateScrollBy(const FloatSize&) = 0;
virtual void immediateScrollByWithoutContentEdgeConstraints(const FloatSize&) = 0;
@@ -97,13 +98,12 @@
virtual bool allowsVerticalStretching(const PlatformWheelEvent&) const = 0;
virtual IntSize stretchAmount() const = 0;
- virtual bool isPinnedForScrollDelta(const FloatSize&) const = 0;
-
+ // "Pinned" means scrolled at or beyond the edge.
+ virtual bool isPinnedOnSide(BoxSide) const = 0;
virtual RectEdges<bool> edgePinnedState() const = 0;
- virtual bool shouldRubberBandInDirection(ScrollDirection) const = 0;
+ virtual bool shouldRubberBandOnSide(BoxSide) const = 0;
- // FIXME: use ScrollClamping to collapse these to one.
virtual void willStartRubberBandSnapAnimation() { }
virtual void didStopRubberbandSnapAnimation() { }
@@ -167,8 +167,6 @@
// Returns true if handled.
bool handleWheelEvent(const PlatformWheelEvent&);
- enum class WheelAxisBias { None, Vertical };
- static std::optional<ScrollDirection> directionFromEvent(const PlatformWheelEvent&, std::optional<ScrollEventAxis>, WheelAxisBias = WheelAxisBias::None);
static FloatSize wheelDeltaBiasingTowardsVertical(const PlatformWheelEvent&);
bool isScrollSnapInProgress() const;
@@ -204,8 +202,7 @@
void stopSnapRubberbandAnimation();
void snapRubberBand();
- bool shouldRubberBandInHorizontalDirection(const PlatformWheelEvent&) const;
- bool shouldRubberBandInDirection(ScrollDirection) const;
+ bool shouldRubberBandOnSide(BoxSide) const;
bool isRubberBandInProgressInternal() const;
void updateRubberBandingState();
void updateRubberBandingEdges(IntSize clientStretch);
Modified: trunk/Source/WebCore/platform/ios/ScrollAnimatorIOS.mm (283334 => 283335)
--- trunk/Source/WebCore/platform/ios/ScrollAnimatorIOS.mm 2021-09-30 20:51:45 UTC (rev 283334)
+++ trunk/Source/WebCore/platform/ios/ScrollAnimatorIOS.mm 2021-09-30 20:58:03 UTC (rev 283335)
@@ -31,6 +31,7 @@
#import "Frame.h"
#import "RenderLayer.h"
#import "ScrollableArea.h"
+#import "ScrollingEffectsController.h"
#if ENABLE(TOUCH_EVENTS)
#import "PlatformTouchEventIOS.h"
@@ -163,12 +164,18 @@
{
ASSERT(!m_scrollableAreaForTouchSequence);
- ScrollableArea* scrollableArea = &m_scrollableArea;
+ auto horizontalEdge = ScrollableArea::targetSideForScrollDelta(scrollDelta, ScrollEventAxis::Horizontal);
+ auto verticalEdge = ScrollableArea::targetSideForScrollDelta(scrollDelta, ScrollEventAxis::Vertical);
+
+ auto* scrollableArea = &m_scrollableArea;
while (true) {
- if (!scrollableArea->isPinnedForScrollDelta(scrollDelta))
+ if (verticalEdge && !scrollableArea->isPinnedOnSide(*verticalEdge))
break;
- ScrollableArea* enclosingArea = scrollableArea->enclosingScrollableArea();
+ if (horizontalEdge && !scrollableArea->isPinnedOnSide(*horizontalEdge))
+ break;
+
+ auto* enclosingArea = scrollableArea->enclosingScrollableArea();
if (!enclosingArea)
break;
Modified: trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.h (283334 => 283335)
--- trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.h 2021-09-30 20:51:45 UTC (rev 283334)
+++ trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.h 2021-09-30 20:58:03 UTC (rev 283335)
@@ -59,7 +59,7 @@
// ScrollingEffectsControllerClient.
bool allowsHorizontalStretching(const PlatformWheelEvent&) const final;
bool allowsVerticalStretching(const PlatformWheelEvent&) const final;
- bool shouldRubberBandInDirection(ScrollDirection) const final;
+ bool shouldRubberBandOnSide(BoxSide) const final;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm (283334 => 283335)
--- trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm 2021-09-30 20:51:45 UTC (rev 283334)
+++ trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm 2021-09-30 20:58:03 UTC (rev 283335)
@@ -158,7 +158,8 @@
Scrollbar* hScroller = m_scrollableArea.horizontalScrollbar();
Scrollbar* vScroller = m_scrollableArea.verticalScrollbar();
bool scrollbarsAllowStretching = ((vScroller && vScroller->enabled()) || (!hScroller || !hScroller->enabled()));
- bool eventPreventsStretching = m_scrollableArea.hasScrollableOrRubberbandableAncestor() && wheelEvent.isGestureStart() && m_scrollableArea.isPinnedForScrollDeltaOnAxis(-wheelEvent.deltaY(), ScrollEventAxis::Vertical);
+ auto relevantSide = ScrollableArea::targetSideForScrollDelta(-wheelEvent.delta(), ScrollEventAxis::Vertical);
+ bool eventPreventsStretching = m_scrollableArea.hasScrollableOrRubberbandableAncestor() && wheelEvent.isGestureStart() && relevantSide && m_scrollableArea.isPinnedOnSide(*relevantSide);
if (!eventPreventsStretching)
eventPreventsStretching = gestureShouldBeginSnap(wheelEvent, ScrollEventAxis::Vertical, m_scrollableArea.snapOffsetsInfo());
return scrollbarsAllowStretching && !eventPreventsStretching;
@@ -180,7 +181,8 @@
Scrollbar* hScroller = m_scrollableArea.horizontalScrollbar();
Scrollbar* vScroller = m_scrollableArea.verticalScrollbar();
bool scrollbarsAllowStretching = ((hScroller && hScroller->enabled()) || (!vScroller || !vScroller->enabled()));
- bool eventPreventsStretching = m_scrollableArea.hasScrollableOrRubberbandableAncestor() && wheelEvent.isGestureStart() && m_scrollableArea.isPinnedForScrollDeltaOnAxis(-wheelEvent.deltaX(), ScrollEventAxis::Horizontal);
+ auto relevantSide = ScrollableArea::targetSideForScrollDelta(-wheelEvent.delta(), ScrollEventAxis::Horizontal);
+ bool eventPreventsStretching = m_scrollableArea.hasScrollableOrRubberbandableAncestor() && wheelEvent.isGestureStart() && relevantSide && m_scrollableArea.isPinnedOnSide(*relevantSide);
if (!eventPreventsStretching)
eventPreventsStretching = gestureShouldBeginSnap(wheelEvent, ScrollEventAxis::Horizontal, m_scrollableArea.snapOffsetsInfo());
return scrollbarsAllowStretching && !eventPreventsStretching;
@@ -195,7 +197,7 @@
return false;
}
-bool ScrollAnimatorMac::shouldRubberBandInDirection(ScrollDirection) const
+bool ScrollAnimatorMac::shouldRubberBandOnSide(BoxSide) const
{
return false;
}
Modified: trunk/Source/WebCore/platform/mac/ScrollingEffectsController.mm (283334 => 283335)
--- trunk/Source/WebCore/platform/mac/ScrollingEffectsController.mm 2021-09-30 20:51:45 UTC (rev 283334)
+++ trunk/Source/WebCore/platform/mac/ScrollingEffectsController.mm 2021-09-30 20:58:03 UTC (rev 283335)
@@ -83,15 +83,46 @@
#endif
}
-
-static FloatSize convertToProminentAxisFavoringVertical(FloatSize delta)
+static ScrollEventAxis dominantAxisFavoringVertical(FloatSize delta)
{
if (fabsf(delta.height()) >= fabsf(delta.width()))
- return { 0, delta.height() };
+ return ScrollEventAxis::Vertical;
- return { delta.width(), 0 };
+ return ScrollEventAxis::Horizontal;
}
+static FloatSize deltaAlignedToAxis(FloatSize delta, ScrollEventAxis axis)
+{
+ switch (axis) {
+ case ScrollEventAxis::Horizontal: return FloatSize { delta.width(), 0 };
+ case ScrollEventAxis::Vertical: return FloatSize { 0, delta.height() };
+ }
+
+ return { };
+}
+
+static FloatSize deltaAlignedToDominantAxis(FloatSize delta)
+{
+ auto dominantAxis = dominantAxisFavoringVertical(delta);
+ return deltaAlignedToAxis(delta, dominantAxis);
+}
+
+static std::optional<BoxSide> affectedSideOnDominantAxis(FloatSize delta)
+{
+ auto dominantAxis = dominantAxisFavoringVertical(delta);
+ return ScrollableArea::targetSideForScrollDelta(delta, dominantAxis);
+}
+
+static bool isHorizontalSide(std::optional<BoxSide> side)
+{
+ return side && (*side == BoxSide::Left || *side == BoxSide::Right);
+}
+
+static bool isVerticalSide(std::optional<BoxSide> side)
+{
+ return side && (*side == BoxSide::Top || *side == BoxSide::Bottom);
+}
+
bool ScrollingEffectsController::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
{
if (processWheelEventForScrollSnap(wheelEvent))
@@ -102,12 +133,12 @@
if (wheelEvent.phase() == PlatformWheelEventPhase::Began) {
// FIXME: Trying to decide if a gesture is horizontal or vertical at the "began" phase is very error-prone.
- auto direction = directionFromEvent(wheelEvent, ScrollEventAxis::Horizontal);
- if (direction && m_client.isPinnedForScrollDelta(FloatSize(-wheelEvent.deltaX(), 0)) && !shouldRubberBandInDirection(direction.value()))
+ auto horizontalSide = ScrollableArea::targetSideForScrollDelta(-wheelEvent.delta(), ScrollEventAxis::Horizontal);
+ if (horizontalSide && m_client.isPinnedOnSide(*horizontalSide) && !shouldRubberBandOnSide(*horizontalSide))
return false;
- direction = directionFromEvent(wheelEvent, ScrollEventAxis::Vertical);
- if (direction && m_client.isPinnedForScrollDelta(FloatSize(0, -wheelEvent.deltaY())) && !shouldRubberBandInDirection(direction.value()))
+ auto verticalSide = ScrollableArea::targetSideForScrollDelta(-wheelEvent.delta(), ScrollEventAxis::Vertical);
+ if (verticalSide && m_client.isPinnedOnSide(*verticalSide) && !shouldRubberBandOnSide(*verticalSide))
return false;
m_momentumScrollInProgress = false;
@@ -155,7 +186,9 @@
auto eventCoalescedDelta = (isVerticallyStretched || isHorizontallyStretched) ? -wheelEvent.unacceleratedScrollingDelta() : -wheelEvent.delta();
delta += eventCoalescedDelta;
- delta = convertToProminentAxisFavoringVertical(delta);
+ // FIXME: All of the code below could be simplified since predominantAxis is known, and we zero out the delta on the other axis.
+ auto affectedSide = affectedSideOnDominantAxis(delta);
+
float deltaX = delta.width();
float deltaY = delta.height();
@@ -177,7 +210,7 @@
}
if (isVerticallyStretched) {
- if (!isHorizontallyStretched && m_client.isPinnedForScrollDelta(FloatSize(deltaX, 0))) {
+ if (!isHorizontallyStretched && isHorizontalSide(affectedSide) && m_client.isPinnedOnSide(*affectedSide)) {
// Stretching only in the vertical.
if (deltaY && (fabsf(deltaX / deltaY) < rubberbandDirectionLockStretchRatio))
deltaX = 0;
@@ -189,7 +222,7 @@
}
} else if (isHorizontallyStretched) {
// Stretching only in the horizontal.
- if (m_client.isPinnedForScrollDelta(FloatSize(0, deltaY))) {
+ if (isVerticalSide(affectedSide) && m_client.isPinnedOnSide(*affectedSide)) {
if (deltaX && (fabsf(deltaY / deltaX) < rubberbandDirectionLockStretchRatio))
deltaY = 0;
else if (fabsf(deltaY) < rubberbandMinimumRequiredDeltaBeforeStretch) {
@@ -200,7 +233,7 @@
}
} else {
// Not stretching at all yet.
- if (m_client.isPinnedForScrollDelta(FloatSize(deltaX, deltaY))) {
+ if (affectedSide && m_client.isPinnedOnSide(*affectedSide)) {
if (fabsf(deltaY) >= fabsf(deltaX)) {
if (fabsf(deltaX) < rubberbandMinimumRequiredDeltaBeforeStretch) {
m_unappliedOverscrollDelta.expand(deltaX, 0);
@@ -233,12 +266,13 @@
m_client.immediateScrollBy(FloatSize(deltaX, 0));
}
} else {
+ affectedSide = affectedSideOnDominantAxis({ deltaX, deltaY });
if (deltaX) {
if (!m_client.allowsHorizontalStretching(wheelEvent)) {
deltaX = 0;
eventCoalescedDelta.setWidth(0);
handled = false;
- } else if (!isHorizontallyStretched && !m_client.isPinnedForScrollDelta(FloatSize(deltaX, 0))) {
+ } else if (!isHorizontallyStretched && !m_client.isPinnedOnSide(*affectedSide)) {
deltaX *= scrollWheelMultiplier();
m_client.immediateScrollByWithoutContentEdgeConstraints(FloatSize(deltaX, 0));
@@ -251,7 +285,7 @@
deltaY = 0;
eventCoalescedDelta.setHeight(0);
handled = false;
- } else if (!isVerticallyStretched && !m_client.isPinnedForScrollDelta(FloatSize(0, deltaY))) {
+ } else if (!isVerticallyStretched && !m_client.isPinnedOnSide(*affectedSide)) {
deltaY *= scrollWheelMultiplier();
m_client.immediateScrollByWithoutContentEdgeConstraints(FloatSize(0, deltaY));
@@ -262,7 +296,8 @@
IntSize stretchAmount = m_client.stretchAmount();
if (m_momentumScrollInProgress) {
- if ((m_client.isPinnedForScrollDelta(eventCoalescedDelta) || eventCoalescedDelta.isZero()) && m_lastMomentumScrollTimestamp) {
+ auto sideAffectedByEventDelta = affectedSideOnDominantAxis(eventCoalescedDelta);
+ if ((!sideAffectedByEventDelta || m_client.isPinnedOnSide(*sideAffectedByEventDelta)) && m_lastMomentumScrollTimestamp) {
m_ignoreMomentumScrolls = true;
m_momentumScrollInProgress = false;
snapRubberBand();
@@ -293,55 +328,9 @@
FloatSize ScrollingEffectsController::wheelDeltaBiasingTowardsVertical(const PlatformWheelEvent& wheelEvent)
{
- return convertToProminentAxisFavoringVertical(wheelEvent.delta());
+ return deltaAlignedToDominantAxis(wheelEvent.delta());
}
-std::optional<ScrollDirection> ScrollingEffectsController::directionFromEvent(const PlatformWheelEvent& wheelEvent, std::optional<ScrollEventAxis> axis, WheelAxisBias bias)
-{
- // FIXME: It's impossible to infer direction from a single event, since the start of a gesture is either zero or
- // has small deltas on both axes.
-
- auto wheelDelta = FloatSize { wheelEvent.deltaX(), wheelEvent.deltaY() };
- if (bias == WheelAxisBias::Vertical)
- wheelDelta = wheelDeltaBiasingTowardsVertical(wheelEvent);
-
- if (axis) {
- switch (axis.value()) {
- case ScrollEventAxis::Vertical:
- if (wheelDelta.height() < 0)
- return ScrollDown;
-
- if (wheelDelta.height() > 0)
- return ScrollUp;
- break;
-
- case ScrollEventAxis::Horizontal:
- if (wheelDelta.width() > 0)
- return ScrollLeft;
-
- if (wheelDelta.width() < 0)
- return ScrollRight;
- }
-
- return std::nullopt;
- }
-
- // Check Y first because vertical scrolling dominates.
- if (wheelDelta.height() < 0)
- return ScrollDown;
-
- if (wheelDelta.height() > 0)
- return ScrollUp;
-
- if (wheelDelta.width() > 0)
- return ScrollLeft;
-
- if (wheelDelta.width() < 0)
- return ScrollRight;
-
- return std::nullopt;
-}
-
static inline float roundTowardZero(float num)
{
return num > 0 ? ceilf(num - 0.5f) : floorf(num + 0.5f);
@@ -493,20 +482,11 @@
startRubberbandAnimation();
}
-bool ScrollingEffectsController::shouldRubberBandInHorizontalDirection(const PlatformWheelEvent& wheelEvent) const
+bool ScrollingEffectsController::shouldRubberBandOnSide(BoxSide side) const
{
- auto direction = directionFromEvent(wheelEvent, ScrollEventAxis::Horizontal);
- if (direction)
- return shouldRubberBandInDirection(direction.value());
-
- return true;
+ return m_client.shouldRubberBandOnSide(side);
}
-bool ScrollingEffectsController::shouldRubberBandInDirection(ScrollDirection direction) const
-{
- return m_client.shouldRubberBandInDirection(direction);
-}
-
bool ScrollingEffectsController::isRubberBandInProgressInternal() const
{
if (!m_inScrollGesture && !m_momentumScrollInProgress && !m_isAnimatingRubberBand)