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/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);
+}
+
+}