Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(295)

Unified Diff: Source/WebCore/page/EventHandler.cpp

Issue 12817006: Merge 144519 "EventHandler::handleGestureScrollUpdate() should i..." (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/1410/
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/WebCore/page/EventHandler.h ('k') | Source/WebCore/platform/PlatformWheelEvent.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/WebCore/page/EventHandler.cpp
===================================================================
--- Source/WebCore/page/EventHandler.cpp (revision 145820)
+++ Source/WebCore/page/EventHandler.cpp (working copy)
@@ -403,6 +403,7 @@
#if ENABLE(GESTURE_EVENTS)
m_scrollGestureHandlingNode = 0;
m_lastHitTestResultOverWidget = false;
+ m_previousGestureScrolledNode = 0;
m_scrollbarHandlingScrollGesture = 0;
#endif
m_maxMouseMovedDuration = 0;
@@ -2498,6 +2499,9 @@
case PlatformEvent::GestureScrollUpdate:
case PlatformEvent::GestureScrollUpdateWithoutPropagation:
return handleGestureScrollUpdate(gestureEvent);
+ case PlatformEvent::GestureScrollEnd:
+ clearGestureScrollNodes();
+ return true;
case PlatformEvent::GestureTap:
return handleGestureTap(gestureEvent);
case PlatformEvent::GestureTapDown:
@@ -2508,7 +2512,6 @@
return handleGestureLongTap(gestureEvent);
case PlatformEvent::GestureTwoFingerTap:
return handleGestureTwoFingerTap(gestureEvent);
- case PlatformEvent::GestureScrollEnd:
case PlatformEvent::GestureDoubleTap:
case PlatformEvent::GesturePinchBegin:
case PlatformEvent::GesturePinchEnd:
@@ -2636,18 +2639,6 @@
return false;
}
-static const Node* closestScrollableNodeCandidate(const Node* node)
-{
- for (const Node* scrollableNode = node; scrollableNode; scrollableNode = scrollableNode->parentNode()) {
- if (scrollableNode->isDocumentNode())
- return scrollableNode;
- RenderObject* renderer = scrollableNode->renderer();
- if (renderer && renderer->isBox() && toRenderBox(renderer)->canBeScrolledAndHasScrollableArea())
- return scrollableNode;
- }
- return node;
-}
-
bool EventHandler::handleGestureScrollBegin(const PlatformGestureEvent& gestureEvent)
{
Document* document = m_frame->document();
@@ -2666,6 +2657,7 @@
m_lastHitTestResultOverWidget = result.isOverWidget();
m_scrollGestureHandlingNode = result.innerNode();
+ m_previousGestureScrolledNode = 0;
Node* node = m_scrollGestureHandlingNode.get();
if (node)
@@ -2676,50 +2668,81 @@
bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gestureEvent)
{
- // Ignore this event if we don't already have a targeted node with a valid renderer.
- const Node* node = m_scrollGestureHandlingNode.get();
- if (!node)
+ FloatSize delta(gestureEvent.deltaX(), gestureEvent.deltaY());
+ if (delta.isZero())
return false;
- RenderObject* latchedRenderer = node->renderer();
- if (!latchedRenderer)
- return false;
+ const float scaleFactor = m_frame->pageZoomFactor() * m_frame->frameScaleFactor();
+ delta.scale(1 / scaleFactor, 1 / scaleFactor);
- IntSize delta(-gestureEvent.deltaX(), -gestureEvent.deltaY());
- if (delta.isZero())
+ Node* node = m_scrollGestureHandlingNode.get();
+ if (!node)
+ return sendScrollEventToView(gestureEvent, delta);
+
+ // Ignore this event if the targeted node does not have a valid renderer.
+ RenderObject* renderer = node->renderer();
+ if (!renderer)
return false;
RefPtr<FrameView> protector(m_frame->view());
// Try to send the event to the correct view.
- if (passGestureEventToWidgetIfPossible(gestureEvent, latchedRenderer))
+ if (passGestureEventToWidgetIfPossible(gestureEvent, renderer))
return true;
- // Otherwise if this is the correct view for the event, find the closest scrollable
- // ancestor of the targeted node and scroll the layer that contains this node's renderer.
- node = closestScrollableNodeCandidate(node);
- if (!node)
- return false;
+ Node* stopNode = 0;
+ bool scrollShouldNotPropagate = gestureEvent.type() == PlatformEvent::GestureScrollUpdateWithoutPropagation;
+ if (scrollShouldNotPropagate)
+ stopNode = m_previousGestureScrolledNode.get();
- latchedRenderer = node->renderer();
- if (!latchedRenderer)
- return false;
+ // First try to scroll the closest scrollable RenderBox ancestor of |node|.
+ ScrollGranularity granularity = ScrollByPixel;
+ bool horizontalScroll = scrollNode(delta.width(), granularity, ScrollLeft, ScrollRight, node, &stopNode);
+ bool verticalScroll = scrollNode(delta.height(), granularity, ScrollUp, ScrollDown, node, &stopNode);
- RenderLayer::ScrollPropagation shouldPropagate = RenderLayer::ShouldPropagateScroll;
- if (gestureEvent.type() == PlatformEvent::GestureScrollUpdateWithoutPropagation)
- shouldPropagate = RenderLayer::DontPropagateScroll;
+ if (scrollShouldNotPropagate)
+ m_previousGestureScrolledNode = stopNode;
- const float scaleFactor = m_frame->pageZoomFactor() * m_frame->frameScaleFactor();
- delta.scale(1 / scaleFactor, 1 / scaleFactor);
+ if (horizontalScroll || verticalScroll) {
+ setFrameWasScrolledByUser();
+ return true;
+ }
- bool result = latchedRenderer->enclosingLayer()->scrollBy(delta, RenderLayer::ScrollOffsetClamped, shouldPropagate);
+ // Otherwise try to scroll the view.
+ return sendScrollEventToView(gestureEvent, delta);
+}
- if (result)
+bool EventHandler::sendScrollEventToView(const PlatformGestureEvent& gestureEvent, const FloatSize& scaledDelta)
+{
+ FrameView* view = m_frame->view();
+ if (!view)
+ return false;
+
+ const float tickDivisor = static_cast<float>(WheelEvent::TickMultiplier);
+ IntPoint point(gestureEvent.position().x(), gestureEvent.position().y());
+ IntPoint globalPoint(gestureEvent.globalPosition().x(), gestureEvent.globalPosition().y());
+ PlatformWheelEvent syntheticWheelEvent(point, globalPoint,
+ scaledDelta.width(), scaledDelta.height(),
+ scaledDelta.width() / tickDivisor, scaledDelta.height() / tickDivisor,
+ ScrollByPixelWheelEvent,
+ gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey());
+#if PLATFORM(MAC) || PLATFORM(CHROMIUM)
+ syntheticWheelEvent.setHasPreciseScrollingDeltas(true);
+#endif
+
+ bool scrolledFrame = view->wheelEvent(syntheticWheelEvent);
+ if (scrolledFrame)
setFrameWasScrolledByUser();
- return result;
+ return scrolledFrame;
}
+void EventHandler::clearGestureScrollNodes()
+{
+ m_scrollGestureHandlingNode = 0;
+ m_previousGestureScrolledNode = 0;
+}
+
bool EventHandler::isScrollbarHandlingGestures() const
{
return m_scrollbarHandlingScrollGesture.get();
« no previous file with comments | « Source/WebCore/page/EventHandler.h ('k') | Source/WebCore/platform/PlatformWheelEvent.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698