Title: [135808] trunk/Source/WebKit/chromium
Revision
135808
Author
[email protected]
Date
2012-11-26 20:08:51 -0800 (Mon, 26 Nov 2012)

Log Message

[chromium] Touchscreen fling handling
https://bugs.webkit.org/show_bug.cgi?id=103278

Reviewed by James Robinson.

The fling logic for touchpad can fall through to bad
performance in several ways. This patch introduces an alternate
path for touchscreen fling that simplifies it as follows:

- Stop generating wheel events, to prevent unnecessary scrollBegin hit
tests and to avoid falling back to slow path if a wheel handler is
registered.

- Drop the event on ScrollStatusIgnored. There's no real reason to
send the event to the WebKit thread here.

- Don't call transferActiveWheelFlingAnimation. This type of
transition shouldn't be needed with touchscreen flings.

* src/WebCompositorInputHandlerImpl.cpp:
(WebKit::WebCompositorInputHandlerImpl::handleGestureFling):
(WebKit::WebCompositorInputHandlerImpl::animate):
(WebKit::WebCompositorInputHandlerImpl::cancelCurrentFling):
(WebKit::WebCompositorInputHandlerImpl::scrollBy):
* src/WebCompositorInputHandlerImpl.h:

Modified Paths

Diff

Modified: trunk/Source/WebKit/chromium/ChangeLog (135807 => 135808)


--- trunk/Source/WebKit/chromium/ChangeLog	2012-11-27 04:03:53 UTC (rev 135807)
+++ trunk/Source/WebKit/chromium/ChangeLog	2012-11-27 04:08:51 UTC (rev 135808)
@@ -1,3 +1,31 @@
+2012-11-26  Alexandre Elias  <[email protected]>
+
+        [chromium] Touchscreen fling handling
+        https://bugs.webkit.org/show_bug.cgi?id=103278
+
+        Reviewed by James Robinson.
+
+        The fling logic for touchpad can fall through to bad
+        performance in several ways. This patch introduces an alternate
+        path for touchscreen fling that simplifies it as follows:
+
+        - Stop generating wheel events, to prevent unnecessary scrollBegin hit
+        tests and to avoid falling back to slow path if a wheel handler is
+        registered.
+
+        - Drop the event on ScrollStatusIgnored. There's no real reason to
+        send the event to the WebKit thread here.
+
+        - Don't call transferActiveWheelFlingAnimation. This type of
+        transition shouldn't be needed with touchscreen flings.
+
+        * src/WebCompositorInputHandlerImpl.cpp:
+        (WebKit::WebCompositorInputHandlerImpl::handleGestureFling):
+        (WebKit::WebCompositorInputHandlerImpl::animate):
+        (WebKit::WebCompositorInputHandlerImpl::cancelCurrentFling):
+        (WebKit::WebCompositorInputHandlerImpl::scrollBy):
+        * src/WebCompositorInputHandlerImpl.h:
+
 2012-11-26  Kentaro Hara  <[email protected]>
 
         [V8] Remove WorkerContextExecutionProxy.{h,cpp}

Modified: trunk/Source/WebKit/chromium/src/WebCompositorInputHandlerImpl.cpp (135807 => 135808)


--- trunk/Source/WebKit/chromium/src/WebCompositorInputHandlerImpl.cpp	2012-11-27 04:03:53 UTC (rev 135807)
+++ trunk/Source/WebKit/chromium/src/WebCompositorInputHandlerImpl.cpp	2012-11-27 04:08:51 UTC (rev 135808)
@@ -118,7 +118,7 @@
         WebInputHandlerClient::ScrollStatus scrollStatus = m_inputHandlerClient->scrollBegin(WebPoint(wheelEvent.x, wheelEvent.y), WebInputHandlerClient::ScrollInputTypeWheel);
         switch (scrollStatus) {
         case WebInputHandlerClient::ScrollStatusStarted: {
-            TRACE_EVENT_INSTANT2("cc", "WebCompositorInputHandlerImpl::handleInput wheel scroll", "deltaX", -wheelEvent.deltaX, "deltaY", -wheelEvent.deltaY);
+            TRACE_EVENT_INSTANT2("webkit", "WebCompositorInputHandlerImpl::handleInput wheel scroll", "deltaX", -wheelEvent.deltaX, "deltaY", -wheelEvent.deltaY);
             bool didScroll = m_inputHandlerClient->scrollByIfPossible(WebPoint(wheelEvent.x, wheelEvent.y), IntSize(-wheelEvent.deltaX, -wheelEvent.deltaY));
             m_inputHandlerClient->scrollEnd();
             return didScroll ? DidHandle : DropEvent;
@@ -205,26 +205,30 @@
     WebInputHandlerClient::ScrollStatus scrollStatus = m_inputHandlerClient->scrollBegin(WebPoint(gestureEvent.x, gestureEvent.y), WebInputHandlerClient::ScrollInputTypeGesture);
     switch (scrollStatus) {
     case WebInputHandlerClient::ScrollStatusStarted: {
-        m_inputHandlerClient->scrollEnd();
-        m_wheelFlingCurve = adoptPtr(Platform::current()->createFlingAnimationCurve(gestureEvent.data.flingStart.sourceDevice, WebFloatPoint(gestureEvent.data.flingStart.velocityX, gestureEvent.data.flingStart.velocityY), WebSize()));
-        TRACE_EVENT_ASYNC_BEGIN0("cc", "WebCompositorInputHandlerImpl::handleGestureFling::started", this);
-        m_wheelFlingParameters.delta = WebFloatPoint(gestureEvent.data.flingStart.velocityX, gestureEvent.data.flingStart.velocityY);
-        m_wheelFlingParameters.point = WebPoint(gestureEvent.x, gestureEvent.y);
-        m_wheelFlingParameters.globalPoint = WebPoint(gestureEvent.globalX, gestureEvent.globalY);
-        m_wheelFlingParameters.modifiers = gestureEvent.modifiers;
-        m_wheelFlingParameters.sourceDevice = gestureEvent.data.flingStart.sourceDevice;
+        if (gestureEvent.data.flingStart.sourceDevice == WebGestureEvent::Touchpad)
+            m_inputHandlerClient->scrollEnd();
+        m_flingCurve = adoptPtr(Platform::current()->createFlingAnimationCurve(gestureEvent.data.flingStart.sourceDevice, WebFloatPoint(gestureEvent.data.flingStart.velocityX, gestureEvent.data.flingStart.velocityY), WebSize()));
+        TRACE_EVENT_ASYNC_BEGIN0("webkit", "WebCompositorInputHandlerImpl::handleGestureFling::started", this);
+        m_flingParameters.delta = WebFloatPoint(gestureEvent.data.flingStart.velocityX, gestureEvent.data.flingStart.velocityY);
+        m_flingParameters.point = WebPoint(gestureEvent.x, gestureEvent.y);
+        m_flingParameters.globalPoint = WebPoint(gestureEvent.globalX, gestureEvent.globalY);
+        m_flingParameters.modifiers = gestureEvent.modifiers;
+        m_flingParameters.sourceDevice = gestureEvent.data.flingStart.sourceDevice;
         m_inputHandlerClient->scheduleAnimation();
         return DidHandle;
     }
     case WebInputHandlerClient::ScrollStatusOnMainThread: {
-        TRACE_EVENT_INSTANT0("cc", "WebCompositorInputHandlerImpl::handleGestureFling::scrollOnMainThread");
+        TRACE_EVENT_INSTANT0("webkit", "WebCompositorInputHandlerImpl::handleGestureFling::scrollOnMainThread");
         return DidNotHandle;
     }
     case WebInputHandlerClient::ScrollStatusIgnored: {
-        TRACE_EVENT_INSTANT0("cc", "WebCompositorInputHandlerImpl::handleGestureFling::ignored");
-        // We still pass the curve to the main thread if there's nothing scrollable, in case something
-        // registers a handler before the curve is over.
-        return DidNotHandle;
+        TRACE_EVENT_INSTANT0("webkit", "WebCompositorInputHandlerImpl::handleGestureFling::ignored");
+        if (gestureEvent.data.flingStart.sourceDevice == WebGestureEvent::Touchpad) {
+            // We still pass the curve to the main thread if there's nothing scrollable, in case something
+            // registers a handler before the curve is over.
+            return DidNotHandle;
+        }
+        return DropEvent;
     }
     }
     return DidNotHandle;
@@ -234,7 +238,7 @@
 {
     ASSERT(!m_inputHandlerClient);
 
-    TRACE_EVENT_INSTANT0("cc", "WebCompositorInputHandlerImpl::bindToClient");
+    TRACE_EVENT_INSTANT0("webkit", "WebCompositorInputHandlerImpl::bindToClient");
     if (!s_compositors)
         s_compositors = new HashSet<WebCompositorInputHandlerImpl*>;
     s_compositors->add(this);
@@ -244,71 +248,94 @@
 
 void WebCompositorInputHandlerImpl::animate(double monotonicTime)
 {
-    if (!m_wheelFlingCurve)
+    if (!m_flingCurve)
         return;
 
-    if (!m_wheelFlingParameters.startTime) {
-        m_wheelFlingParameters.startTime = monotonicTime;
+    if (!m_flingParameters.startTime) {
+        m_flingParameters.startTime = monotonicTime;
         m_inputHandlerClient->scheduleAnimation();
         return;
     }
 
-    if (m_wheelFlingCurve->apply(monotonicTime - m_wheelFlingParameters.startTime, this))
+    if (m_flingCurve->apply(monotonicTime - m_flingParameters.startTime, this))
         m_inputHandlerClient->scheduleAnimation();
     else {
-        TRACE_EVENT_INSTANT0("cc", "WebCompositorInputHandlerImpl::animate::flingOver");
+        TRACE_EVENT_INSTANT0("webkit", "WebCompositorInputHandlerImpl::animate::flingOver");
         cancelCurrentFling();
     }
 }
 
 bool WebCompositorInputHandlerImpl::cancelCurrentFling()
 {
-    bool hadFlingAnimation = m_wheelFlingCurve;
-    if (hadFlingAnimation)
-        TRACE_EVENT_ASYNC_END0("cc", "WebCompositorInputHandlerImpl::handleGestureFling::started", this);
+    bool hadFlingAnimation = m_flingCurve;
+    if (hadFlingAnimation && m_flingParameters.sourceDevice == WebGestureEvent::Touchscreen) {
+        m_inputHandlerClient->scrollEnd();
+        TRACE_EVENT_ASYNC_END0("webkit", "WebCompositorInputHandlerImpl::handleGestureFling::started", this);
+    }
 
-    TRACE_EVENT_INSTANT1("cc", "WebCompositorInputHandlerImpl::cancelCurrentFling", "hadFlingAnimation", hadFlingAnimation);
-    m_wheelFlingCurve.clear();
-    m_wheelFlingParameters = WebActiveWheelFlingParameters();
+    TRACE_EVENT_INSTANT1("webkit", "WebCompositorInputHandlerImpl::cancelCurrentFling", "hadFlingAnimation", hadFlingAnimation);
+    m_flingCurve.clear();
+    m_flingParameters = WebActiveWheelFlingParameters();
     return hadFlingAnimation;
 }
 
-void WebCompositorInputHandlerImpl::scrollBy(const WebPoint& increment)
+bool WebCompositorInputHandlerImpl::touchpadFlingScroll(const WebPoint& increment)
 {
-    if (increment == WebPoint())
-        return;
-
-    TRACE_EVENT2("cc", "WebCompositorInputHandlerImpl::scrollBy", "x", increment.x, "y", increment.y);
     WebMouseWheelEvent syntheticWheel;
     syntheticWheel.type = WebInputEvent::MouseWheel;
     syntheticWheel.deltaX = increment.x;
     syntheticWheel.deltaY = increment.y;
     syntheticWheel.hasPreciseScrollingDeltas = true;
-    syntheticWheel.x = m_wheelFlingParameters.point.x;
-    syntheticWheel.y = m_wheelFlingParameters.point.y;
-    syntheticWheel.globalX = m_wheelFlingParameters.globalPoint.x;
-    syntheticWheel.globalY = m_wheelFlingParameters.globalPoint.y;
-    syntheticWheel.modifiers = m_wheelFlingParameters.modifiers;
+    syntheticWheel.x = m_flingParameters.point.x;
+    syntheticWheel.y = m_flingParameters.point.y;
+    syntheticWheel.globalX = m_flingParameters.globalPoint.x;
+    syntheticWheel.globalY = m_flingParameters.globalPoint.y;
+    syntheticWheel.modifiers = m_flingParameters.modifiers;
 
     WebCompositorInputHandlerImpl::EventDisposition disposition = handleInputEventInternal(syntheticWheel);
     switch (disposition) {
     case DidHandle:
-        m_wheelFlingParameters.cumulativeScroll.width += increment.x;
-        m_wheelFlingParameters.cumulativeScroll.height += increment.y;
+        return true;
     case DropEvent:
         break;
     case DidNotHandle:
-        TRACE_EVENT_INSTANT0("cc", "WebCompositorInputHandlerImpl::scrollBy::AbortFling");
+        TRACE_EVENT_INSTANT0("webkit", "WebCompositorInputHandlerImpl::scrollBy::AbortFling");
         // If we got a DidNotHandle, that means we need to deliver wheels on the main thread.
         // In this case we need to schedule a commit and transfer the fling curve over to the main
         // thread and run the rest of the wheels from there.
         // This can happen when flinging a page that contains a scrollable subarea that we can't
         // scroll on the thread if the fling starts outside the subarea but then is flung "under" the
         // pointer.
-        m_client->transferActiveWheelFlingAnimation(m_wheelFlingParameters);
+        m_client->transferActiveWheelFlingAnimation(m_flingParameters);
         cancelCurrentFling();
         break;
     }
+
+    return false;
 }
 
+void WebCompositorInputHandlerImpl::scrollBy(const WebPoint& increment)
+{
+    if (increment == WebPoint())
+        return;
+
+    TRACE_EVENT2("webkit", "WebCompositorInputHandlerImpl::scrollBy", "x", increment.x, "y", increment.y);
+
+    bool didScroll = false;
+
+    switch (m_flingParameters.sourceDevice) {
+    case WebGestureEvent::Touchpad:
+        didScroll = touchpadFlingScroll(increment);
+        break;
+    case WebGestureEvent::Touchscreen:
+        didScroll = m_inputHandlerClient->scrollByIfPossible(m_flingParameters.point, IntSize(-increment.x, -increment.y));
+        break;
+    }
+
+    if (didScroll) {
+        m_flingParameters.cumulativeScroll.width += increment.x;
+        m_flingParameters.cumulativeScroll.height += increment.y;
+    }
 }
+
+}

Modified: trunk/Source/WebKit/chromium/src/WebCompositorInputHandlerImpl.h (135807 => 135808)


--- trunk/Source/WebKit/chromium/src/WebCompositorInputHandlerImpl.h	2012-11-27 04:03:53 UTC (rev 135807)
+++ trunk/Source/WebKit/chromium/src/WebCompositorInputHandlerImpl.h	2012-11-27 04:08:51 UTC (rev 135808)
@@ -78,12 +78,15 @@
 
     EventDisposition handleGestureFling(const WebGestureEvent&);
 
+    // Returns true if we scrolled by the increment.
+    bool touchpadFlingScroll(const WebPoint& increment);
+
     // Returns true if we actually had an active fling to cancel.
     bool cancelCurrentFling();
 
-    OwnPtr<WebGestureCurve> m_wheelFlingCurve;
+    OwnPtr<WebGestureCurve> m_flingCurve;
     // Parameters for the active fling animation, stored in case we need to transfer it out later.
-    WebActiveWheelFlingParameters m_wheelFlingParameters;
+    WebActiveWheelFlingParameters m_flingParameters;
 
     WebCompositorInputHandlerClient* m_client;
     int m_identifier;

Modified: trunk/Source/WebKit/chromium/tests/WebCompositorInputHandlerImplTest.cpp (135807 => 135808)


--- trunk/Source/WebKit/chromium/tests/WebCompositorInputHandlerImplTest.cpp	2012-11-27 04:03:53 UTC (rev 135807)
+++ trunk/Source/WebKit/chromium/tests/WebCompositorInputHandlerImplTest.cpp	2012-11-27 04:08:51 UTC (rev 135808)
@@ -259,7 +259,7 @@
     m_inputHandler->handleInputEvent(gesture);
 }
 
-TEST_F(WebCompositorInputHandlerImplTest, gestureFlingStarted)
+TEST_F(WebCompositorInputHandlerImplTest, gestureFlingStartedTouchpad)
 {
     // We shouldn't send any events to the widget for this gesture.
     m_expectedDisposition = DidHandle;
@@ -272,16 +272,18 @@
 
     gesture.type = WebInputEvent::GestureFlingStart;
     gesture.data.flingStart.velocityX = 10;
+    gesture.data.flingStart.sourceDevice = WebGestureEvent::Touchpad;
     m_inputHandler->handleInputEvent(gesture);
 
     VERIFY_AND_RESET_MOCKS();
 
     // Verify that a GestureFlingCancel during an animation cancels it.
     gesture.type = WebInputEvent::GestureFlingCancel;
+    gesture.data.flingStart.sourceDevice = WebGestureEvent::Touchpad;
     m_inputHandler->handleInputEvent(gesture);
 }
 
-TEST_F(WebCompositorInputHandlerImplTest, gestureFlingFailed)
+TEST_F(WebCompositorInputHandlerImplTest, gestureFlingOnMainThreadTouchpad)
 {
     // We should send all events to the widget for this gesture.
     m_expectedDisposition = DidNotHandle;
@@ -291,16 +293,18 @@
         .WillOnce(testing::Return(WebInputHandlerClient::ScrollStatusOnMainThread));
 
     gesture.type = WebInputEvent::GestureFlingStart;
+    gesture.data.flingStart.sourceDevice = WebGestureEvent::Touchpad;
     m_inputHandler->handleInputEvent(gesture);
 
     VERIFY_AND_RESET_MOCKS();
 
     // Even if we didn't start a fling ourselves, we still need to send the cancel event to the widget.
     gesture.type = WebInputEvent::GestureFlingCancel;
+    gesture.data.flingStart.sourceDevice = WebGestureEvent::Touchpad;
     m_inputHandler->handleInputEvent(gesture);
 }
 
-TEST_F(WebCompositorInputHandlerImplTest, gestureFlingIgnored)
+TEST_F(WebCompositorInputHandlerImplTest, gestureFlingIgnoredTouchpad)
 {
     m_expectedDisposition = DidNotHandle;
     VERIFY_AND_RESET_MOCKS();
@@ -309,16 +313,18 @@
         .WillOnce(testing::Return(WebInputHandlerClient::ScrollStatusIgnored));
 
     gesture.type = WebInputEvent::GestureFlingStart;
+    gesture.data.flingStart.sourceDevice = WebGestureEvent::Touchpad;
     m_inputHandler->handleInputEvent(gesture);
 
     VERIFY_AND_RESET_MOCKS();
 
     // Even if we didn't start a fling ourselves, we still need to send the cancel event to the widget.
     gesture.type = WebInputEvent::GestureFlingCancel;
+    gesture.data.flingStart.sourceDevice = WebGestureEvent::Touchpad;
     m_inputHandler->handleInputEvent(gesture);
 }
 
-TEST_F(WebCompositorInputHandlerImplTest, gestureFlingAnimates)
+TEST_F(WebCompositorInputHandlerImplTest, gestureFlingAnimatesTouchpad)
 {
     // We shouldn't send any events to the widget for this gesture.
     m_expectedDisposition = DidHandle;
@@ -333,6 +339,7 @@
     int modifiers = 7;
     gesture.data.flingStart.velocityX = flingDelta.x;
     gesture.data.flingStart.velocityY = flingDelta.y;
+    gesture.data.flingStart.sourceDevice = WebGestureEvent::Touchpad;
     gesture.x = flingPoint.x;
     gesture.y = flingPoint.y;
     gesture.globalX = flingGlobalPoint.x;
@@ -405,7 +412,7 @@
     m_inputHandler->handleInputEvent(gesture);
 }
 
-TEST_F(WebCompositorInputHandlerImplTest, gestureFlingTransferResets)
+TEST_F(WebCompositorInputHandlerImplTest, gestureFlingTransferResetsTouchpad)
 {
     // We shouldn't send any events to the widget for this gesture.
     m_expectedDisposition = DidHandle;
@@ -419,6 +426,7 @@
     int modifiers = 1;
     gesture.data.flingStart.velocityX = flingDelta.x;
     gesture.data.flingStart.velocityY = flingDelta.y;
+    gesture.data.flingStart.sourceDevice = WebGestureEvent::Touchpad;
     gesture.x = flingPoint.x;
     gesture.y = flingPoint.y;
     gesture.globalX = flingGlobalPoint.x;
@@ -500,6 +508,7 @@
     modifiers = 2;
     gesture.data.flingStart.velocityX = flingDelta.x;
     gesture.data.flingStart.velocityY = flingDelta.y;
+    gesture.data.flingStart.sourceDevice = WebGestureEvent::Touchpad;
     gesture.x = flingPoint.x;
     gesture.y = flingPoint.y;
     gesture.globalX = flingGlobalPoint.x;
@@ -550,4 +559,121 @@
     m_inputHandler->animate(30.2);
 }
 
+TEST_F(WebCompositorInputHandlerImplTest, gestureFlingStartedTouchscreen)
+{
+    // We shouldn't send any events to the widget for this gesture.
+    m_expectedDisposition = DidHandle;
+    VERIFY_AND_RESET_MOCKS();
+
+    EXPECT_CALL(m_mockInputHandlerClient, scrollBegin(testing::_, testing::_))
+        .WillOnce(testing::Return(WebInputHandlerClient::ScrollStatusStarted));
+    EXPECT_CALL(m_mockInputHandlerClient, scheduleAnimation());
+
+    gesture.type = WebInputEvent::GestureFlingStart;
+    gesture.data.flingStart.velocityX = 10;
+    gesture.data.flingStart.sourceDevice = WebGestureEvent::Touchscreen;
+    m_inputHandler->handleInputEvent(gesture);
+
+    VERIFY_AND_RESET_MOCKS();
+
+    EXPECT_CALL(m_mockInputHandlerClient, scrollEnd());
+
+    // Verify that a GestureFlingCancel during an animation cancels it.
+    gesture.type = WebInputEvent::GestureFlingCancel;
+    gesture.data.flingStart.sourceDevice = WebGestureEvent::Touchscreen;
+    m_inputHandler->handleInputEvent(gesture);
 }
+
+TEST_F(WebCompositorInputHandlerImplTest, gestureFlingOnMainThreadTouchscreen)
+{
+    // We should send all events to the widget for this gesture.
+    m_expectedDisposition = DidNotHandle;
+    VERIFY_AND_RESET_MOCKS();
+
+    EXPECT_CALL(m_mockInputHandlerClient, scrollBegin(testing::_, testing::_))
+        .WillOnce(testing::Return(WebInputHandlerClient::ScrollStatusOnMainThread));
+
+    gesture.type = WebInputEvent::GestureFlingStart;
+    gesture.data.flingStart.sourceDevice = WebGestureEvent::Touchscreen;
+    m_inputHandler->handleInputEvent(gesture);
+
+    VERIFY_AND_RESET_MOCKS();
+
+    // Even if we didn't start a fling ourselves, we still need to send the cancel event to the widget.
+    gesture.type = WebInputEvent::GestureFlingCancel;
+    gesture.data.flingStart.sourceDevice = WebGestureEvent::Touchscreen;
+    m_inputHandler->handleInputEvent(gesture);
+}
+
+TEST_F(WebCompositorInputHandlerImplTest, gestureFlingIgnoredTouchscreen)
+{
+    m_expectedDisposition = DropEvent;
+    VERIFY_AND_RESET_MOCKS();
+
+    EXPECT_CALL(m_mockInputHandlerClient, scrollBegin(testing::_, testing::_))
+        .WillOnce(testing::Return(WebInputHandlerClient::ScrollStatusIgnored));
+
+    gesture.type = WebInputEvent::GestureFlingStart;
+    gesture.data.flingStart.sourceDevice = WebGestureEvent::Touchscreen;
+    m_inputHandler->handleInputEvent(gesture);
+
+    m_expectedDisposition = DidNotHandle;
+    VERIFY_AND_RESET_MOCKS();
+
+    // Even if we didn't start a fling ourselves, we still need to send the cancel event to the widget.
+    gesture.type = WebInputEvent::GestureFlingCancel;
+    gesture.data.flingStart.sourceDevice = WebGestureEvent::Touchscreen;
+    m_inputHandler->handleInputEvent(gesture);
+}
+
+TEST_F(WebCompositorInputHandlerImplTest, gestureFlingAnimatesTouchscreen)
+{
+    // We shouldn't send any events to the widget for this gesture.
+    m_expectedDisposition = DidHandle;
+    VERIFY_AND_RESET_MOCKS();
+
+    // On the fling start, we should schedule an animation but not actually start
+    // scrolling.
+    gesture.type = WebInputEvent::GestureFlingStart;
+    WebFloatPoint flingDelta = WebFloatPoint(1000, 0);
+    WebPoint flingPoint = WebPoint(7, 13);
+    WebPoint flingGlobalPoint = WebPoint(17, 23);
+    int modifiers = 7;
+    gesture.data.flingStart.velocityX = flingDelta.x;
+    gesture.data.flingStart.velocityY = flingDelta.y;
+    gesture.data.flingStart.sourceDevice = WebGestureEvent::Touchscreen;
+    gesture.x = flingPoint.x;
+    gesture.y = flingPoint.y;
+    gesture.globalX = flingGlobalPoint.x;
+    gesture.globalY = flingGlobalPoint.y;
+    gesture.modifiers = modifiers;
+    EXPECT_CALL(m_mockInputHandlerClient, scheduleAnimation());
+    EXPECT_CALL(m_mockInputHandlerClient, scrollBegin(testing::_, testing::_))
+        .WillOnce(testing::Return(WebInputHandlerClient::ScrollStatusStarted));
+    m_inputHandler->handleInputEvent(gesture);
+
+    testing::Mock::VerifyAndClearExpectations(&m_mockInputHandlerClient);
+    // The first animate call should let us pick up an animation start time, but we
+    // shouldn't actually move anywhere just yet. The first frame after the fling start
+    // will typically include the last scroll from the gesture that lead to the scroll
+    // (either wheel or gesture scroll), so there should be no visible hitch.
+    EXPECT_CALL(m_mockInputHandlerClient, scheduleAnimation());
+    m_inputHandler->animate(10);
+
+    testing::Mock::VerifyAndClearExpectations(&m_mockInputHandlerClient);
+
+    // The second call should start scrolling in the -X direction.
+    EXPECT_CALL(m_mockInputHandlerClient, scheduleAnimation());
+    EXPECT_CALL(m_mockInputHandlerClient, scrollByIfPossible(testing::_, testing::Field(&WebSize::width, testing::Lt(0))))
+        .WillOnce(testing::Return(true));
+    m_inputHandler->animate(10.1);
+
+    testing::Mock::VerifyAndClearExpectations(&m_mockInputHandlerClient);
+
+    EXPECT_CALL(m_mockClient, didHandleInputEvent());
+    EXPECT_CALL(m_mockInputHandlerClient, scrollEnd());
+    gesture.type = WebInputEvent::GestureFlingCancel;
+    m_inputHandler->handleInputEvent(gesture);
+}
+
+}
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to