| Index: Source/core/input/EventHandler.cpp
|
| diff --git a/Source/core/input/EventHandler.cpp b/Source/core/input/EventHandler.cpp
|
| index 5ce38751106f6d06f862f27b290b771cca457905..8685364df1e1c9e15a4f43ed583e936bdb586ae2 100644
|
| --- a/Source/core/input/EventHandler.cpp
|
| +++ b/Source/core/input/EventHandler.cpp
|
| @@ -232,6 +232,7 @@ EventHandler::EventHandler(LocalFrame* frame)
|
| , m_eventHandlerWillResetCapturingMouseEventsNode(0)
|
| , m_clickCount(0)
|
| , m_shouldOnlyFireDragOverEvent(false)
|
| + , m_accumulatedRootOverscroll(FloatSize())
|
| , m_mousePositionIsUnknown(true)
|
| , m_mouseDownTimestamp(0)
|
| , m_widgetIsLatched(false)
|
| @@ -923,10 +924,10 @@ void EventHandler::stopAutoscroll()
|
| controller->stopAutoscroll();
|
| }
|
|
|
| -bool EventHandler::scroll(ScrollDirection direction, ScrollGranularity granularity, Node* startNode, Node** stopNode, float delta, IntPoint absolutePoint)
|
| +ScrollResultOneDimensional EventHandler::scroll(ScrollDirection direction, ScrollGranularity granularity, Node* startNode, Node** stopNode, float delta, IntPoint absolutePoint)
|
| {
|
| if (!delta)
|
| - return false;
|
| + return ScrollResultOneDimensional(false);
|
|
|
| Node* node = startNode;
|
|
|
| @@ -937,7 +938,7 @@ bool EventHandler::scroll(ScrollDirection direction, ScrollGranularity granulari
|
| node = m_mousePressNode.get();
|
|
|
| if (!node || !node->layoutObject())
|
| - return false;
|
| + return ScrollResultOneDimensional(false, delta);
|
|
|
| LayoutBox* curBox = node->layoutObject()->enclosingBox();
|
| while (curBox && !curBox->isLayoutView()) {
|
| @@ -946,20 +947,21 @@ bool EventHandler::scroll(ScrollDirection direction, ScrollGranularity granulari
|
|
|
| // If we're at the stopNode, we should try to scroll it but we shouldn't bubble past it
|
| bool shouldStopBubbling = stopNode && *stopNode && curBox->node() == *stopNode;
|
| - bool didScroll = curBox->scroll(physicalDirection, granularity, delta);
|
| + ScrollResultOneDimensional result = curBox->scroll(physicalDirection, granularity, delta);
|
|
|
| - if (didScroll && stopNode)
|
| + if (result.didScroll && stopNode)
|
| *stopNode = curBox->node();
|
|
|
| - if (didScroll || shouldStopBubbling) {
|
| + if (result.didScroll || shouldStopBubbling) {
|
| setFrameWasScrolledByUser();
|
| - return true;
|
| + result.didScroll = true;
|
| + return result;
|
| }
|
|
|
| curBox = curBox->containingBlock();
|
| }
|
|
|
| - return false;
|
| + return ScrollResultOneDimensional(false, delta);
|
| }
|
|
|
| void EventHandler::customizedScroll(const Node& startNode, ScrollState& scrollState)
|
| @@ -979,14 +981,14 @@ bool EventHandler::bubblingScroll(ScrollDirection direction, ScrollGranularity g
|
| // here because of an onLoad event, in which case the final layout hasn't been performed yet.
|
| m_frame->document()->updateLayoutIgnorePendingStylesheets();
|
| // FIXME: enable scroll customization in this case. See crbug.com/410974.
|
| - if (scroll(direction, granularity, startingNode))
|
| + if (scroll(direction, granularity, startingNode).didScroll)
|
| return true;
|
| LocalFrame* frame = m_frame;
|
| FrameView* view = frame->view();
|
| if (view) {
|
| ScrollDirectionPhysical physicalDirection =
|
| toPhysicalDirection(direction, view->isVerticalDocument(), view->isFlippedDocument());
|
| - if (view->scrollableArea()->userScroll(physicalDirection, granularity)) {
|
| + if (view->scrollableArea()->userScroll(physicalDirection, granularity).didScroll) {
|
| setFrameWasScrolledByUser();
|
| return true;
|
| }
|
| @@ -2177,7 +2179,7 @@ bool EventHandler::handleWheelEvent(const PlatformWheelEvent& event)
|
| if (!view)
|
| return false;
|
|
|
| - if (view->scrollableArea()->handleWheel(event).didScroll)
|
| + if (view->scrollableArea()->handleWheel(event).didScroll())
|
| RETURN_WHEEL_EVENT_HANDLED();
|
|
|
| return false;
|
| @@ -2202,11 +2204,11 @@ void EventHandler::defaultWheelEventHandler(Node* startNode, WheelEvent* wheelEv
|
|
|
| // FIXME: enable scroll customization in this case. See crbug.com/410974.
|
| if (wheelEvent->railsMode() != Event::RailsModeVertical
|
| - && scroll(ScrollRightIgnoringWritingMode, granularity, startNode, &stopNode, wheelEvent->deltaX(), absolutePosition))
|
| + && scroll(ScrollRightIgnoringWritingMode, granularity, startNode, &stopNode, wheelEvent->deltaX(), absolutePosition).didScroll)
|
| wheelEvent->setDefaultHandled();
|
|
|
| if (wheelEvent->railsMode() != Event::RailsModeHorizontal
|
| - && scroll(ScrollDownIgnoringWritingMode, granularity, startNode, &stopNode, wheelEvent->deltaY(), absolutePosition))
|
| + && scroll(ScrollDownIgnoringWritingMode, granularity, startNode, &stopNode, wheelEvent->deltaY(), absolutePosition).didScroll)
|
| wheelEvent->setDefaultHandled();
|
|
|
| if (!m_latchedWheelEventNode)
|
| @@ -2607,7 +2609,7 @@ bool EventHandler::handleGestureScrollEnd(const PlatformGestureEvent& gestureEve
|
| }
|
| }
|
|
|
| - clearGestureScrollNodes();
|
| + clearGestureScrollState();
|
| return false;
|
| }
|
|
|
| @@ -2648,6 +2650,30 @@ bool EventHandler::handleGestureScrollBegin(const PlatformGestureEvent& gestureE
|
| return true;
|
| }
|
|
|
| +void EventHandler::resetOverscroll(bool didScrollX, bool didScrollY)
|
| +{
|
| + if (didScrollX)
|
| + m_accumulatedRootOverscroll.setWidth(0);
|
| + if (didScrollY)
|
| + m_accumulatedRootOverscroll.setHeight(0);
|
| +}
|
| +
|
| +void EventHandler::handleOverscroll(const ScrollResult& scrollResult, const PlatformGestureEvent& gestureEvent)
|
| +{
|
| + if (m_frame->isMainFrame() && m_frame->view() && m_frame->view()->scrollableArea()) {
|
| + ScrollableArea* scrollablearea = m_frame->view()->scrollableArea();
|
| + // Set unusedDelta if axis is scrollable, else set 0 to ensure overflow is not reported on non-scrollable axes.
|
| + FloatSize unusedDelta(scrollablearea->scrollSize(HorizontalScrollbar) ? scrollResult.unusedScrollDeltaX : 0, scrollablearea->scrollSize(VerticalScrollbar) ? scrollResult.unusedScrollDeltaY : 0);
|
| + resetOverscroll(scrollResult.didScrollX, scrollResult.didScrollY);
|
| + if (unusedDelta != FloatSize()) {
|
| + m_accumulatedRootOverscroll += unusedDelta;
|
| + FloatPoint position = FloatPoint(gestureEvent.position().x(), gestureEvent.position().y());
|
| + FloatSize velocity = FloatSize(gestureEvent.velocityX(), gestureEvent.velocityY());
|
| + m_frame->chromeClient().didOverscroll(unusedDelta, m_accumulatedRootOverscroll, position, velocity);
|
| + }
|
| + }
|
| +}
|
| +
|
| bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gestureEvent)
|
| {
|
| ASSERT(gestureEvent.type() == PlatformEvent::GestureScrollUpdate);
|
| @@ -2707,14 +2733,18 @@ bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gesture
|
|
|
| // First try to scroll the closest scrollable LayoutBox ancestor of |node|.
|
| ScrollGranularity granularity = ScrollByPrecisePixel;
|
| - bool horizontalScroll = scroll(ScrollLeftIgnoringWritingMode, granularity, node, &stopNode, delta.width());
|
| + ScrollResultOneDimensional result = scroll(ScrollLeftIgnoringWritingMode, granularity, node, &stopNode, delta.width());
|
| + bool horizontalScroll = result.didScroll;
|
| if (!gestureEvent.preventPropagation())
|
| stopNode = nullptr;
|
| - bool verticalScroll = scroll(ScrollUpIgnoringWritingMode, granularity, node, &stopNode, delta.height());
|
| + result = scroll(ScrollUpIgnoringWritingMode, granularity, node, &stopNode, delta.height());
|
| + bool verticalScroll = result.didScroll;
|
| scrolled = horizontalScroll || verticalScroll;
|
|
|
| if (gestureEvent.preventPropagation())
|
| m_previousGestureScrolledNode = stopNode;
|
| +
|
| + resetOverscroll(horizontalScroll, verticalScroll);
|
| }
|
| if (scrolled) {
|
| setFrameWasScrolledByUser();
|
| @@ -2726,7 +2756,9 @@ bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gesture
|
| return false;
|
|
|
| // Try to scroll the frame view.
|
| - if (m_frame->applyScrollDelta(delta, false)) {
|
| + ScrollResult scrollResult = m_frame->applyScrollDelta(delta, false);
|
| + handleOverscroll(scrollResult, gestureEvent);
|
| + if (scrollResult.didScroll()) {
|
| setFrameWasScrolledByUser();
|
| return true;
|
| }
|
| @@ -2734,12 +2766,13 @@ bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gesture
|
| return false;
|
| }
|
|
|
| -void EventHandler::clearGestureScrollNodes()
|
| +void EventHandler::clearGestureScrollState()
|
| {
|
| m_scrollGestureHandlingNode = nullptr;
|
| m_previousGestureScrolledNode = nullptr;
|
| m_deltaConsumedForScrollSequence = false;
|
| m_currentScrollChain.clear();
|
| + m_accumulatedRootOverscroll = FloatSize();
|
| }
|
|
|
| bool EventHandler::isScrollbarHandlingGestures() const
|
| @@ -3642,7 +3675,7 @@ void EventHandler::defaultSpaceEventHandler(KeyboardEvent* event)
|
| ScrollDirection direction = event->shiftKey() ? ScrollBlockDirectionBackward : ScrollBlockDirectionForward;
|
|
|
| // FIXME: enable scroll customization in this case. See crbug.com/410974.
|
| - if (scroll(direction, ScrollByPage)) {
|
| + if (scroll(direction, ScrollByPage).didScroll) {
|
| event->setDefaultHandled();
|
| return;
|
| }
|
| @@ -3654,7 +3687,7 @@ void EventHandler::defaultSpaceEventHandler(KeyboardEvent* event)
|
| ScrollDirectionPhysical physicalDirection =
|
| toPhysicalDirection(direction, view->isVerticalDocument(), view->isFlippedDocument());
|
|
|
| - if (view->scrollableArea()->userScroll(physicalDirection, ScrollByPage))
|
| + if (view->scrollableArea()->userScroll(physicalDirection, ScrollByPage).didScroll)
|
| event->setDefaultHandled();
|
| }
|
|
|
|
|