Diff
Modified: trunk/Source/WebCore/ChangeLog (184138 => 184139)
--- trunk/Source/WebCore/ChangeLog 2015-05-12 01:06:59 UTC (rev 184138)
+++ trunk/Source/WebCore/ChangeLog 2015-05-12 01:12:01 UTC (rev 184139)
@@ -1,3 +1,102 @@
+2015-05-11 Brent Fulgham <[email protected]>
+
+ Scroll snap logic should be triggered when resizing the WebView
+ https://bugs.webkit.org/show_bug.cgi?id=142590
+ <rdar://problem/20125088>
+
+ Reviewed by Simon Fraser.
+
+ Tests coming in a second patch.
+
+ Resizing of the main frame or overflow regions was properly recalculating the scroll snap points,
+ but there was no code to honor these values when window resizing was occurring. The correction was
+ handled in two ways:
+ 1. Scrolling thread operations that moved to new snap points needed to notify the main thread that
+ it had shifted to a new snap point, so that the resize code (which happens on the main thread)
+ could ensure that we stayed clamped to the correct 'tile' in the snap region.
+ 2. Main thread (overflow) resizes were likewise missing code to honor the current snap position
+ after resizing calculations were complete.
+
+ This change also required the addition of two indices to the scrollable area to track which scroll
+ snap point was currently being used. We don't bother with a 'none' case because you cannot have a
+ 'none' state when you have an active set of scroll snap points, and we do not execute this code
+ if the scroll snap points are null.
+
+ The FrameView code was computing updated snap offsets after it had dispatched frame view layout
+ information to the scrolling thread, which was wrong. This was also corrected.
+
+ I think it might be possible to track all of this state inside the ScrollController, but the current
+ scroll snap architecture destroys and recreates the state each time a new set of interactions starts.
+ This should be fixed in the future, which would allow us to remove some of this local state.
+
+ * page/FrameView.cpp:
+ (WebCore::FrameView::performPostLayoutTasks): Make sure 'updateSnapOffsets' is called prior to
+ calling 'frameViewLayoutUpdated' so the scrolling thread gets correct updated points. Add a new
+ call to 'scrollToNearestActiveSnapPoint', which will keep us on our current snap point during
+ resize (if appropriate).
+ * page/scrolling/AsyncScrollingCoordinator.cpp:
+ (WebCore::AsyncScrollingCoordinator::updateScrollSnapOffsetIndices): Added. This finds and notifies
+ the correct scroll region when a new snap position (index) has been selected by user interaction on
+ the scrolling thread.
+ (WebCore::AsyncScrollingCoordinator::deferTestsForReason): Added an assertion for 'isMainThread'.
+ (WebCore::AsyncScrollingCoordinator::removeTestDeferralForReason): Ditto.
+ * page/scrolling/AsyncScrollingCoordinator.h:
+ * page/scrolling/AxisScrollSnapOffsets.h:
+ (WebCore::closestSnapOffset): Modified to also return the selected snap point index so we can track
+ it to handle resize operations.
+ * page/scrolling/ScrollingTree.h:
+ (WebCore::ScrollingTree::updateScrollSnapOffsetIndices):
+ * page/scrolling/ThreadedScrollingTree.cpp:
+ (WebCore::ThreadedScrollingTree::updateScrollSnapOffsetIndices): Added method to dispatch the active
+ horizontal and vertical scroll snap indices back to the main thread.
+ * page/scrolling/ThreadedScrollingTree.h:
+ * page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm:
+ (WebCore::ScrollingTreeFrameScrollingNodeMac::handleWheelEvent): After the scroll controller processes
+ the current event, notify the main thread of any change in the active scroll snap index.
+ * platform/ScrollAnimator.cpp:
+ (WebCore::ScrollAnimator::activeScrollSnapOffsetIndexDidChange): Added method to allow ScrollAnimator
+ clients to find out about the current scroll snap state, which is only known by the ScrollController.
+ (WebCore::ScrollAnimator::activeScrollSnapOffsetIndexForAxis): Ditto.
+ * platform/ScrollAnimator.h:
+ * platform/ScrollView.cpp:
+ (WebCore::ScrollView::scrollToNearestActiveSnapPoint): Added method that allows us to set scroll position
+ to one of our active scroll snap offsets.
+ * platform/ScrollView.h:
+ * platform/ScrollableArea.cpp:
+ (WebCore::ScrollableArea::handleWheelEvent): If the active scroll snap offset has changed, make sure we
+ keep track of the new values for potential resize operations.
+ (WebCore::ScrollableArea::clearHorizontalSnapOffsets): Make sure to also clear out the current snap index.
+ (WebCore::ScrollableArea::clearVerticalSnapOffsets): Ditto.
+ (WebCore::ScrollableArea::nearestActiveSnapPoint): New method that returns an updated IntPoint reflecting
+ the proper scroll position based on the active scroll snap offset.
+ * platform/ScrollableArea.h:
+ (WebCore::ScrollableArea::currentHorizontalSnapPointIndex): Added.
+ (WebCore::ScrollableArea::setCurrentHorizontalSnapPointIndex): Added.
+ (WebCore::ScrollableArea::currentVerticalSnapPointIndex): Added.
+ (WebCore::ScrollableArea::setCurrentVerticalSnapPointIndex): Added.
+ (WebCore::ScrollableArea::scrollToNearestActiveSnapPoint): Added.
+ * platform/cocoa/ScrollController.h:
+ (WebCore::ScrollControllerClient::activeScrollOffsetIndex): Added new method for clients to implement.
+ (WebCore::ScrollController::activeScrollSnapOffsetIndexDidChange): Added.
+ (WebCore::ScrollController::setScrollSnapOffsetIndexDidChange): Added.
+ * platform/cocoa/ScrollController.mm:
+ (WebCore::ScrollController::activeScrollSnapOffsetIndexForAxis): Helper method to return current active
+ index (if applicable).
+ (WebCore::ScrollController::setActiveScrollSnapOffsetIndexForAxis): Helper function to safely set
+ the current active index.
+ (WebCore::ScrollController::beginScrollSnapAnimation): Updated to keep track of the new active scroll snap
+ index, as well as whether the current animation actually changed the active snap point offset.
+ * platform/cocoa/ScrollSnapAnimatorState.h: Revise to use modern C++ initializers, and to track a new index
+ that represents the current scroll snap offset.
+ * platform/cocoa/ScrollSnapAnimatorState.mm:
+ (WebCore::ScrollSnapAnimatorState::ScrollSnapAnimatorState): Update for modern C++ syntax.
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::scrollToNearestActiveSnapPoint): New method to set scroll position to be one of our
+ active scroll snap points.
+ (WebCore::RenderLayer::updateScrollInfoAfterLayout): Add a new call to 'scrollToNearestActiveSnapPoint' so that
+ we stay on the current scroll snap offset during resizing.
+ * rendering/RenderLayer.h:
+
2015-05-11 Myles C. Maxfield <[email protected]>
Addressing post-review comments after r184037.
Modified: trunk/Source/WebCore/page/FrameView.cpp (184138 => 184139)
--- trunk/Source/WebCore/page/FrameView.cpp 2015-05-12 01:06:59 UTC (rev 184138)
+++ trunk/Source/WebCore/page/FrameView.cpp 2015-05-12 01:12:01 UTC (rev 184139)
@@ -2974,7 +2974,11 @@
frame().loader().client().dispatchDidLayout();
updateWidgetPositions();
-
+
+#if ENABLE(CSS_SCROLL_SNAP)
+ updateSnapOffsets();
+#endif
+
// layout() protects FrameView, but it still can get destroyed when updateEmbeddedObjects()
// is called through the post layout timer.
Ref<FrameView> protect(*this);
@@ -2996,15 +3000,7 @@
sendResizeEventIfNeeded();
viewportContentsChanged();
-#if ENABLE(CSS_SCROLL_SNAP)
- if (!frame().isMainFrame()) {
- updateSnapOffsets();
-#if PLATFORM(MAC)
- if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
- return scrollAnimator->updateScrollAnimatorsAndTimers();
-#endif
- }
-#endif
+ updateScrollSnapState();
}
IntSize FrameView::sizeForResizeEvent() const
Modified: trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp (184138 => 184139)
--- trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp 2015-05-12 01:06:59 UTC (rev 184138)
+++ trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp 2015-05-12 01:12:01 UTC (rev 184139)
@@ -562,8 +562,33 @@
}
#if PLATFORM(COCOA)
+void AsyncScrollingCoordinator::setActiveScrollSnapIndices(ScrollingNodeID scrollingNodeID, unsigned horizontalIndex, unsigned verticalIndex)
+{
+ ASSERT(isMainThread());
+
+ if (!m_page)
+ return;
+
+ FrameView* frameView = frameViewForScrollingNode(scrollingNodeID);
+ if (!frameView)
+ return;
+
+ if (scrollingNodeID == frameView->scrollLayerID()) {
+ frameView->setCurrentHorizontalSnapPointIndex(horizontalIndex);
+ frameView->setCurrentVerticalSnapPointIndex(verticalIndex);
+ return;
+ }
+
+ // Overflow-scroll area.
+ if (ScrollableArea* scrollableArea = frameView->scrollableAreaForScrollLayerID(scrollingNodeID)) {
+ scrollableArea->setCurrentHorizontalSnapPointIndex(horizontalIndex);
+ scrollableArea->setCurrentVerticalSnapPointIndex(verticalIndex);
+ }
+}
+
void AsyncScrollingCoordinator::deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason) const
{
+ ASSERT(isMainThread());
if (!m_page || !m_page->expectsWheelEventTriggers())
return;
@@ -575,6 +600,7 @@
void AsyncScrollingCoordinator::removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason) const
{
+ ASSERT(isMainThread());
if (!m_page || !m_page->expectsWheelEventTriggers())
return;
Modified: trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h (184138 => 184139)
--- trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h 2015-05-12 01:06:59 UTC (rev 184138)
+++ trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h 2015-05-12 01:12:01 UTC (rev 184139)
@@ -57,6 +57,7 @@
WEBCORE_EXPORT void scheduleUpdateScrollPositionAfterAsyncScroll(ScrollingNodeID, const FloatPoint&, bool programmaticScroll, SetOrSyncScrollingLayerPosition);
#if PLATFORM(COCOA)
+ void setActiveScrollSnapIndices(ScrollingNodeID, unsigned horizontalIndex, unsigned verticalIndex);
void deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const;
void removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const;
#endif
Modified: trunk/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.h (184138 => 184139)
--- trunk/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.h 2015-05-12 01:06:59 UTC (rev 184138)
+++ trunk/Source/WebCore/page/scrolling/AxisScrollSnapOffsets.h 2015-05-12 01:12:01 UTC (rev 184139)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -44,12 +44,14 @@
// as well as a VelocityType indicating the velocity (e.g. float, CGFloat, etc.) This function is templated because the UI process will now
// use pixel snapped floats to represent snap offsets rather than LayoutUnits.
template <typename LayoutType, typename VelocityType>
-LayoutType closestSnapOffset(const Vector<LayoutType>& snapOffsets, LayoutType scrollDestination, VelocityType velocity)
+LayoutType closestSnapOffset(const Vector<LayoutType>& snapOffsets, LayoutType scrollDestination, VelocityType velocity, unsigned& activeSnapIndex)
{
ASSERT(snapOffsets.size());
+ activeSnapIndex = 0;
if (scrollDestination <= snapOffsets.first())
return snapOffsets.first();
+ activeSnapIndex = snapOffsets.size() - 1;
if (scrollDestination >= snapOffsets.last())
return snapOffsets.last();
@@ -70,10 +72,13 @@
LayoutType lowerSnapPosition = snapOffsets[lowerIndex];
LayoutType upperSnapPosition = snapOffsets[upperIndex];
// Nonzero velocity indicates a flick gesture. Even if another snap point is closer, snap to the one in the direction of the flick gesture.
- if (velocity)
+ if (velocity) {
+ activeSnapIndex = (velocity < 0) ? lowerIndex : upperIndex;
return velocity < 0 ? lowerSnapPosition : upperSnapPosition;
+ }
bool isCloserToLowerSnapPosition = scrollDestination - lowerSnapPosition <= upperSnapPosition - scrollDestination;
+ activeSnapIndex = isCloserToLowerSnapPosition ? lowerIndex : upperIndex;
return isCloserToLowerSnapPosition ? lowerSnapPosition : upperSnapPosition;
}
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.h (184138 => 184139)
--- trunk/Source/WebCore/page/scrolling/ScrollingTree.h 2015-05-12 01:06:59 UTC (rev 184138)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.h 2015-05-12 01:12:01 UTC (rev 184139)
@@ -100,6 +100,7 @@
#if PLATFORM(MAC)
virtual void handleWheelEventPhase(PlatformWheelEventPhase) = 0;
+ virtual void setActiveScrollSnapIndices(ScrollingNodeID, unsigned /*horizontalIndex*/, unsigned /*verticalIndex*/) { }
virtual void deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) { }
virtual void removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) { }
#endif
Modified: trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp (184138 => 184139)
--- trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp 2015-05-12 01:06:59 UTC (rev 184138)
+++ trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp 2015-05-12 01:12:01 UTC (rev 184139)
@@ -123,6 +123,17 @@
});
}
+void ThreadedScrollingTree::setActiveScrollSnapIndices(ScrollingNodeID nodeID, unsigned horizontalIndex, unsigned verticalIndex)
+{
+ if (!m_scrollingCoordinator)
+ return;
+
+ RefPtr<AsyncScrollingCoordinator> scrollingCoordinator = m_scrollingCoordinator;
+ RunLoop::main().dispatch([scrollingCoordinator, nodeID, horizontalIndex, verticalIndex] {
+ scrollingCoordinator->setActiveScrollSnapIndices(nodeID, horizontalIndex, verticalIndex);
+ });
+}
+
void ThreadedScrollingTree::deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason)
{
if (!m_scrollingCoordinator)
Modified: trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h (184138 => 184139)
--- trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h 2015-05-12 01:06:59 UTC (rev 184138)
+++ trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h 2015-05-12 01:12:01 UTC (rev 184139)
@@ -62,6 +62,7 @@
virtual void scrollingTreeNodeDidScroll(ScrollingNodeID, const FloatPoint& scrollPosition, SetOrSyncScrollingLayerPosition = SyncScrollingLayerPosition) override;
#if PLATFORM(MAC)
void handleWheelEventPhase(PlatformWheelEventPhase) override;
+ void setActiveScrollSnapIndices(ScrollingNodeID, unsigned horizontalIndex, unsigned verticalIndex) override;
void deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) override;
void removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) override;
#endif
Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm (184138 => 184139)
--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm 2015-05-12 01:06:59 UTC (rev 184138)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm 2015-05-12 01:12:01 UTC (rev 184139)
@@ -184,6 +184,10 @@
#endif
m_scrollController.handleWheelEvent(wheelEvent);
+#if ENABLE(CSS_SCROLL_SNAP)
+ if (m_scrollController.activeScrollSnapIndexDidChange())
+ scrollingTree().setActiveScrollSnapIndices(scrollingNodeID(), m_scrollController.activeScrollSnapIndexForAxis(ScrollEventAxis::Horizontal), m_scrollController.activeScrollSnapIndexForAxis(ScrollEventAxis::Vertical));
+#endif
scrollingTree().setOrClearLatchedNode(wheelEvent, scrollingNodeID());
scrollingTree().handleWheelEventPhase(wheelEvent.phase());
}
Modified: trunk/Source/WebCore/platform/ScrollAnimator.cpp (184138 => 184139)
--- trunk/Source/WebCore/platform/ScrollAnimator.cpp 2015-05-12 01:06:59 UTC (rev 184138)
+++ trunk/Source/WebCore/platform/ScrollAnimator.cpp 2015-05-12 01:12:01 UTC (rev 184139)
@@ -87,6 +87,16 @@
{
return m_scrollController.processWheelEventForScrollSnap(wheelEvent);
}
+
+bool ScrollAnimator::activeScrollSnapIndexDidChange() const
+{
+ return m_scrollController.activeScrollSnapIndexDidChange();
+}
+
+unsigned ScrollAnimator::activeScrollSnapIndexForAxis(ScrollEventAxis axis) const
+{
+ return m_scrollController.activeScrollSnapIndexForAxis(axis);
+}
#endif
bool ScrollAnimator::handleWheelEvent(const PlatformWheelEvent& e)
Modified: trunk/Source/WebCore/platform/ScrollAnimator.h (184138 => 184139)
--- trunk/Source/WebCore/platform/ScrollAnimator.h 2015-05-12 01:06:59 UTC (rev 184138)
+++ trunk/Source/WebCore/platform/ScrollAnimator.h 2015-05-12 01:12:01 UTC (rev 184139)
@@ -130,6 +130,8 @@
void updateScrollAnimatorsAndTimers();
LayoutUnit scrollOffsetOnAxis(ScrollEventAxis) const override;
void immediateScrollOnAxis(ScrollEventAxis, float delta) override;
+ bool activeScrollSnapIndexDidChange() const;
+ unsigned activeScrollSnapIndexForAxis(ScrollEventAxis) const;
#endif
protected:
Modified: trunk/Source/WebCore/platform/ScrollableArea.cpp (184138 => 184139)
--- trunk/Source/WebCore/platform/ScrollableArea.cpp 2015-05-12 01:06:59 UTC (rev 184138)
+++ trunk/Source/WebCore/platform/ScrollableArea.cpp 2015-05-12 01:12:01 UTC (rev 184139)
@@ -46,6 +46,7 @@
virtual ~SameSizeAsScrollableArea();
#if ENABLE(CSS_SCROLL_SNAP)
void* pointers[3];
+ unsigned currentIndices[2];
#else
void* pointer;
#endif
@@ -188,7 +189,14 @@
if (!isScrollableOrRubberbandable())
return false;
- return scrollAnimator().handleWheelEvent(wheelEvent);
+ bool handledEvent = scrollAnimator().handleWheelEvent(wheelEvent);
+#if ENABLE(CSS_SCROLL_SNAP) && PLATFORM(MAC)
+ if (scrollAnimator().activeScrollSnapIndexDidChange()) {
+ setCurrentHorizontalSnapPointIndex(scrollAnimator().activeScrollSnapIndexForAxis(ScrollEventAxis::Horizontal));
+ setCurrentVerticalSnapPointIndex(scrollAnimator().activeScrollSnapIndexForAxis(ScrollEventAxis::Vertical));
+ }
+#endif
+ return handledEvent;
}
#if ENABLE(TOUCH_EVENTS)
@@ -409,14 +417,64 @@
void ScrollableArea::clearHorizontalSnapOffsets()
{
m_horizontalSnapOffsets = nullptr;
+ m_currentHorizontalSnapPointIndex = 0;
}
void ScrollableArea::clearVerticalSnapOffsets()
{
m_verticalSnapOffsets = nullptr;
+ m_currentVerticalSnapPointIndex = 0;
}
+
+IntPoint ScrollableArea::nearestActiveSnapPoint(const IntPoint& currentPosition)
+{
+ if (!horizontalSnapOffsets() && !verticalSnapOffsets())
+ return currentPosition;
+
+ if (!existingScrollAnimator())
+ return currentPosition;
+
+ IntPoint correctedPosition = currentPosition;
+
+ if (horizontalSnapOffsets()) {
+ const auto& horizontal = *horizontalSnapOffsets();
+
+ size_t activeIndex = currentHorizontalSnapPointIndex();
+ if (activeIndex < horizontal.size())
+ correctedPosition.setX(horizontal[activeIndex].toInt());
+ }
+
+ if (verticalSnapOffsets()) {
+ const auto& vertical = *verticalSnapOffsets();
+
+ size_t activeIndex = currentVerticalSnapPointIndex();
+ if (activeIndex < vertical.size())
+ correctedPosition.setY(vertical[activeIndex].toInt());
+ }
+
+ return correctedPosition;
+}
+
+void ScrollableArea::updateScrollSnapState()
+{
+#if PLATFORM(MAC)
+ if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
+ scrollAnimator->updateScrollAnimatorsAndTimers();
#endif
+ IntPoint currentPosition = scrollPosition();
+ IntPoint correctedPosition = nearestActiveSnapPoint(currentPosition);
+
+ if (correctedPosition != currentPosition)
+ scrollToOffsetWithoutAnimation(correctedPosition);
+}
+#else
+void ScrollableArea::updateScrollSnapState()
+{
+}
+#endif
+
+
void ScrollableArea::serviceScrollAnimations()
{
if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
Modified: trunk/Source/WebCore/platform/ScrollableArea.h (184138 => 184139)
--- trunk/Source/WebCore/platform/ScrollableArea.h 2015-05-12 01:06:59 UTC (rev 184138)
+++ trunk/Source/WebCore/platform/ScrollableArea.h 2015-05-12 01:12:01 UTC (rev 184139)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2011, 2014 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2011, 2014-2015 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -66,8 +66,15 @@
void setVerticalSnapOffsets(std::unique_ptr<Vector<LayoutUnit>>);
void clearHorizontalSnapOffsets();
void clearVerticalSnapOffsets();
+ unsigned currentHorizontalSnapPointIndex() const { return m_currentHorizontalSnapPointIndex; }
+ void setCurrentHorizontalSnapPointIndex(unsigned index) { m_currentHorizontalSnapPointIndex = index; }
+ unsigned currentVerticalSnapPointIndex() const { return m_currentVerticalSnapPointIndex; }
+ void setCurrentVerticalSnapPointIndex(unsigned index) { m_currentVerticalSnapPointIndex = index; }
+ IntPoint nearestActiveSnapPoint(const IntPoint&);
#endif
+ void updateScrollSnapState();
+
#if ENABLE(TOUCH_EVENTS)
virtual bool isTouchScrollable() const { return false; }
virtual bool handleTouchEvent(const PlatformTouchEvent&);
@@ -305,6 +312,8 @@
#if ENABLE(CSS_SCROLL_SNAP)
std::unique_ptr<Vector<LayoutUnit>> m_horizontalSnapOffsets;
std::unique_ptr<Vector<LayoutUnit>> m_verticalSnapOffsets;
+ unsigned m_currentHorizontalSnapPointIndex { 0 };
+ unsigned m_currentVerticalSnapPointIndex { 0 };
#endif
// There are 8 possible combinations of writing mode and direction. Scroll origin will be non-zero in the x or y axis
Modified: trunk/Source/WebCore/platform/cocoa/ScrollController.h (184138 => 184139)
--- trunk/Source/WebCore/platform/cocoa/ScrollController.h 2015-05-12 01:06:59 UTC (rev 184138)
+++ trunk/Source/WebCore/platform/cocoa/ScrollController.h 2015-05-12 01:12:01 UTC (rev 184139)
@@ -97,6 +97,11 @@
{
return 1.0f;
}
+
+ virtual unsigned activeScrollOffsetIndex(ScrollEventAxis) const
+ {
+ return 0;
+ }
#endif
};
@@ -114,6 +119,10 @@
bool processWheelEventForScrollSnap(const PlatformWheelEvent&);
void updateScrollAnimatorsAndTimers(const ScrollableArea&);
void updateScrollSnapPoints(ScrollEventAxis, const Vector<LayoutUnit>&);
+ unsigned activeScrollSnapIndexForAxis(ScrollEventAxis) const;
+ void setActiveScrollSnapIndexForAxis(ScrollEventAxis, unsigned);
+ bool activeScrollSnapIndexDidChange() const { return m_activeScrollSnapIndexDidChange; }
+ void setScrollSnapIndexDidChange(bool state) { m_activeScrollSnapIndexDidChange = state; }
#endif
private:
@@ -172,6 +181,7 @@
bool m_momentumScrollInProgress { false };
bool m_ignoreMomentumScrolls { false };
bool m_snapRubberbandTimerIsActive { false };
+ bool m_activeScrollSnapIndexDidChange { false };
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/cocoa/ScrollController.mm (184138 => 184139)
--- trunk/Source/WebCore/platform/cocoa/ScrollController.mm 2015-05-12 01:06:59 UTC (rev 184138)
+++ trunk/Source/WebCore/platform/cocoa/ScrollController.mm 2015-05-12 01:12:01 UTC (rev 184139)
@@ -685,6 +685,26 @@
snapState.m_glidePhaseShift = acos((snapState.m_glideInitialWheelDelta - targetFinalWheelDelta) / (snapState.m_glideInitialWheelDelta + targetFinalWheelDelta));
}
+unsigned ScrollController::activeScrollSnapIndexForAxis(ScrollEventAxis axis) const
+{
+ if ((axis == ScrollEventAxis::Horizontal) && !m_horizontalScrollSnapState)
+ return 0;
+ if ((axis == ScrollEventAxis::Vertical) && !m_verticalScrollSnapState)
+ return 0;
+
+ const ScrollSnapAnimatorState& snapState = scrollSnapPointState(axis);
+ return snapState.m_activeSnapIndex;
+}
+
+void ScrollController::setActiveScrollSnapIndexForAxis(ScrollEventAxis axis, unsigned index)
+{
+ auto* snapState = (axis == ScrollEventAxis::Horizontal) ? m_horizontalScrollSnapState.get() : m_verticalScrollSnapState.get();
+ if (!snapState)
+ return;
+
+ snapState->m_activeSnapIndex = index;
+}
+
void ScrollController::beginScrollSnapAnimation(ScrollEventAxis axis, ScrollSnapState newState)
{
ASSERT(newState == ScrollSnapState::Gliding || newState == ScrollSnapState::Snapping);
@@ -701,10 +721,12 @@
projectedScrollDestination = std::min(std::max(LayoutUnit(projectedScrollDestination / scaleFactor), snapState.m_snapOffsets.first()), snapState.m_snapOffsets.last());
snapState.m_initialOffset = offset;
- snapState.m_targetOffset = scaleFactor * closestSnapOffset<LayoutUnit, float>(snapState.m_snapOffsets, projectedScrollDestination, initialWheelDelta);
+ m_activeScrollSnapIndexDidChange = false;
+ snapState.m_targetOffset = scaleFactor * closestSnapOffset<LayoutUnit, float>(snapState.m_snapOffsets, projectedScrollDestination, initialWheelDelta, snapState.m_activeSnapIndex);
if (snapState.m_initialOffset == snapState.m_targetOffset)
return;
+ m_activeScrollSnapIndexDidChange = true;
snapState.m_currentState = newState;
if (newState == ScrollSnapState::Gliding) {
snapState.m_shouldOverrideWheelEvent = true;
Modified: trunk/Source/WebCore/platform/cocoa/ScrollSnapAnimatorState.h (184138 => 184139)
--- trunk/Source/WebCore/platform/cocoa/ScrollSnapAnimatorState.h 2015-05-12 01:06:59 UTC (rev 184138)
+++ trunk/Source/WebCore/platform/cocoa/ScrollSnapAnimatorState.h 2015-05-12 01:12:01 UTC (rev 184139)
@@ -59,12 +59,13 @@
LayoutUnit m_targetOffset;
// Used to track gliding behavior.
LayoutUnit m_beginTrackingWheelDeltaOffset;
- int m_numWheelDeltasTracked;
+ int m_numWheelDeltasTracked { 0 };
+ unsigned m_activeSnapIndex { 0 };
float m_wheelDeltaWindow[wheelDeltaWindowSize];
- float m_glideMagnitude;
- float m_glidePhaseShift;
- float m_glideInitialWheelDelta;
- bool m_shouldOverrideWheelEvent;
+ float m_glideMagnitude { 0 };
+ float m_glidePhaseShift { 0 };
+ float m_glideInitialWheelDelta { 0 };
+ bool m_shouldOverrideWheelEvent { false };
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/cocoa/ScrollSnapAnimatorState.mm (184138 => 184139)
--- trunk/Source/WebCore/platform/cocoa/ScrollSnapAnimatorState.mm 2015-05-12 01:06:59 UTC (rev 184138)
+++ trunk/Source/WebCore/platform/cocoa/ScrollSnapAnimatorState.mm 2015-05-12 01:12:01 UTC (rev 184139)
@@ -37,11 +37,6 @@
, m_initialOffset(0)
, m_targetOffset(0)
, m_beginTrackingWheelDeltaOffset(0)
- , m_numWheelDeltasTracked(0)
- , m_glideMagnitude(0)
- , m_glidePhaseShift(0)
- , m_glideInitialWheelDelta(0)
- , m_shouldOverrideWheelEvent(false)
{
}
Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (184138 => 184139)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2015-05-12 01:06:59 UTC (rev 184138)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2015-05-12 01:12:01 UTC (rev 184139)
@@ -3461,6 +3461,12 @@
computeScrollDimensions();
+#if ENABLE(CSS_SCROLL_SNAP)
+ // FIXME: Ensure that offsets are also updated in case of programmatic style changes.
+ // https://bugs.webkit.org/show_bug.cgi?id=135964
+ updateSnapOffsets();
+#endif
+
if (box->style().overflowX() != OMARQUEE && !isRubberBandInProgress()) {
// Layout may cause us to be at an invalid scroll position. In this case we need
// to pull our scroll offsets back to the max (or push them up to the min).
@@ -3488,15 +3494,7 @@
if (compositor().updateLayerCompositingState(*this))
compositor().setCompositingLayersNeedRebuild();
-#if ENABLE(CSS_SCROLL_SNAP)
- // FIXME: Ensure that offsets are also updated in case of programmatic style changes.
- // https://bugs.webkit.org/show_bug.cgi?id=135964
- updateSnapOffsets();
-#if PLATFORM(MAC)
- if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
- return scrollAnimator->updateScrollAnimatorsAndTimers();
-#endif
-#endif
+ updateScrollSnapState();
}
bool RenderLayer::overflowControlsIntersectRect(const IntRect& localRect) const
Modified: trunk/Source/WebKit2/ChangeLog (184138 => 184139)
--- trunk/Source/WebKit2/ChangeLog 2015-05-12 01:06:59 UTC (rev 184138)
+++ trunk/Source/WebKit2/ChangeLog 2015-05-12 01:12:01 UTC (rev 184139)
@@ -1,3 +1,16 @@
+2015-05-11 Brent Fulgham <[email protected]>
+
+ Scroll snap logic should be triggered when resizing the WebView
+ https://bugs.webkit.org/show_bug.cgi?id=142590
+ <rdar://problem/20125088>
+
+ Reviewed by Simon Fraser.
+
+ * UIProcess/ios/RemoteScrollingCoordinatorProxyIOS.mm:
+ (RemoteScrollingCoordinatorProxy::closestSnapOffsetForMainFrameScrolling): Modify use of 'closestSnapOffset' to satisfy the additional
+ argument I added. This is currently not used for anything on iOS.
+ * UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.mm: Ditto.
+
2015-05-11 Andreas Kling <[email protected]>
Force a rebuild of JSNPObject.cpp on bots.
Modified: trunk/Source/WebKit2/UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.mm (184138 => 184139)
--- trunk/Source/WebKit2/UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.mm 2015-05-12 01:06:59 UTC (rev 184138)
+++ trunk/Source/WebKit2/UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.mm 2015-05-12 01:12:01 UTC (rev 184139)
@@ -80,10 +80,11 @@
#if ENABLE(CSS_SCROLL_SNAP)
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{
+ unsigned ignore;
if (!_scrollingTreeNode->horizontalSnapOffsets().isEmpty())
- targetContentOffset->x = closestSnapOffset<float, CGFloat>(_scrollingTreeNode->horizontalSnapOffsets(), targetContentOffset->x, velocity.x);
+ targetContentOffset->x = closestSnapOffset<float, CGFloat>(_scrollingTreeNode->horizontalSnapOffsets(), targetContentOffset->x, velocity.x, ignore);
if (!_scrollingTreeNode->verticalSnapOffsets().isEmpty())
- targetContentOffset->y = closestSnapOffset<float, CGFloat>(_scrollingTreeNode->verticalSnapOffsets(), targetContentOffset->y, velocity.y);
+ targetContentOffset->y = closestSnapOffset<float, CGFloat>(_scrollingTreeNode->verticalSnapOffsets(), targetContentOffset->y, velocity.y, ignore);
}
#endif
Modified: trunk/Source/WebKit2/UIProcess/ios/RemoteScrollingCoordinatorProxyIOS.mm (184138 => 184139)
--- trunk/Source/WebKit2/UIProcess/ios/RemoteScrollingCoordinatorProxyIOS.mm 2015-05-12 01:06:59 UTC (rev 184138)
+++ trunk/Source/WebKit2/UIProcess/ios/RemoteScrollingCoordinatorProxyIOS.mm 2015-05-12 01:12:01 UTC (rev 184139)
@@ -150,8 +150,9 @@
ScrollingTreeFrameScrollingNode* rootFrame = static_cast<ScrollingTreeFrameScrollingNode*>(root);
const Vector<float>& snapOffsets = axis == ScrollEventAxis::Horizontal ? rootFrame->horizontalSnapOffsets() : rootFrame->verticalSnapOffsets();
+ unsigned ignore = 0;
float scaledScrollDestination = scrollDestination / m_webPageProxy.displayedContentScale();
- float rawClosestSnapOffset = closestSnapOffset<float, float>(snapOffsets, scaledScrollDestination, velocity);
+ float rawClosestSnapOffset = closestSnapOffset<float, float>(snapOffsets, scaledScrollDestination, velocity, ignore);
return rawClosestSnapOffset * m_webPageProxy.displayedContentScale();
}
#endif