Chromium Code Reviews| Index: Source/core/page/EventHandler.cpp |
| diff --git a/Source/core/page/EventHandler.cpp b/Source/core/page/EventHandler.cpp |
| index 17680fb568c943022b1296e3bf08c7893a8f51ad..ea129a6db132f7960ff31b68ca05c32f3b17ca1c 100644 |
| --- a/Source/core/page/EventHandler.cpp |
| +++ b/Source/core/page/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,18 @@ bool EventHandler::handleGestureScrollBegin(const PlatformGestureEvent& gestureE |
| return true; |
| } |
| +void EventHandler::resetOverscroll(bool didScrollX, bool didScrollY, FloatSize& unusedDelta) |
|
bokan
2015/06/04 12:05:42
I don't think you need to reset unusedDelta. The f
MuVen
2015/06/04 14:01:19
Done.
|
| +{ |
| + if (didScrollX) { |
| + m_accumulatedRootOverscroll.setWidth(0); |
| + unusedDelta.setWidth(0); |
| + } |
| + if (didScrollY) { |
| + m_accumulatedRootOverscroll.setHeight(0); |
| + unusedDelta.setHeight(0); |
| + } |
| +} |
| + |
| bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gestureEvent) |
| { |
| ASSERT(gestureEvent.type() == PlatformEvent::GestureScrollUpdate); |
| @@ -2657,6 +2671,7 @@ bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gesture |
| return false; |
| Node* node = m_scrollGestureHandlingNode.get(); |
| + FloatSize unusedDelta; |
| if (node) { |
| LayoutObject* layoutObject = node->layoutObject(); |
| if (!layoutObject) |
| @@ -2707,14 +2722,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, unusedDelta); |
| } |
| if (scrolled) { |
| setFrameWasScrolledByUser(); |
| @@ -2726,7 +2745,21 @@ 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); |
| + if (m_frame->isMainFrame() && m_frame->view() && m_frame->view()->scrollableArea()) { |
| + ScrollableArea* scrollablearea = m_frame->view()->scrollableArea(); |
| + // Set unusedDelta if axes is scrollable, else set 0 to ensure overflow is not reported on non-scrollable axes. |
| + unusedDelta.setWidth(scrollablearea->scrollSize(HorizontalScrollbar) ? scrollResult.unusedScrollDeltaX : 0); |
| + unusedDelta.setHeight(scrollablearea->scrollSize(VerticalScrollbar) ? scrollResult.unusedScrollDeltaY : 0); |
| + resetOverscroll(scrollResult.didScrollX, scrollResult.didScrollY, unusedDelta); |
| + 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); |
| + } |
| + } |
| + if (scrollResult.didScroll()) { |
| setFrameWasScrolledByUser(); |
| return true; |
| } |
| @@ -2734,12 +2767,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 +3676,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 +3688,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(); |
| } |