Skip to content

Commit

Permalink
Fix WebKeyboardEvent interruption of compositor scrolling
Browse files Browse the repository at this point in the history
Fix an issue where keyboard events improperly reset the scroll status while
a touch scroll was active in InputHandlerProxy.

BUG=361160

Review URL: https://codereview.chromium.org/230663004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@262985 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
jdduke@chromium.org committed Apr 10, 2014
1 parent 882ccdf commit c9440b2
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 1 deletion.
5 changes: 4 additions & 1 deletion content/renderer/input/input_handler_proxy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,10 @@ InputHandlerProxy::EventDisposition InputHandlerProxy::HandleInputEvent(
}
return DROP_EVENT;
} else if (WebInputEvent::isKeyboardEventType(event.type)) {
CancelCurrentFling(true);
// Only call |CancelCurrentFling()| if a fling was active, as it will
// otherwise disrupt an in-progress touch scroll.
if (fling_curve_)
CancelCurrentFling(true);
} else if (event.type == WebInputEvent::MouseMove) {
const WebMouseEvent& mouse_event =
*static_cast<const WebMouseEvent*>(&event);
Expand Down
53 changes: 53 additions & 0 deletions content/renderer/input/input_handler_proxy_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ using blink::WebFloatPoint;
using blink::WebFloatSize;
using blink::WebGestureEvent;
using blink::WebInputEvent;
using blink::WebKeyboardEvent;
using blink::WebMouseWheelEvent;
using blink::WebPoint;
using blink::WebSize;
Expand Down Expand Up @@ -1257,5 +1258,57 @@ TEST_F(InputHandlerProxyTest, MultiTouchPointHitTestPositive) {
EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(touch));
}

TEST_F(InputHandlerProxyTest, GestureFlingCancelledByKeyboardEvent) {
// We shouldn't send any events to the widget for this gesture.
expected_disposition_ = InputHandlerProxy::DID_HANDLE;
VERIFY_AND_RESET_MOCKS();

EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
gesture_.type = WebInputEvent::GestureScrollBegin;
gesture_.sourceDevice = WebGestureEvent::Touchscreen;
EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);

// Keyboard events received during a scroll should have no effect.
WebKeyboardEvent key_event;
key_event.type = WebInputEvent::KeyDown;
EXPECT_EQ(InputHandlerProxy::DID_NOT_HANDLE,
input_handler_->HandleInputEvent(key_event));
EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);

// On the fling start, animation should be scheduled, but no scrolling occurs.
gesture_.type = WebInputEvent::GestureFlingStart;
WebFloatPoint fling_delta = WebFloatPoint(1000, 1000);
gesture_.data.flingStart.velocityX = fling_delta.x;
gesture_.data.flingStart.velocityY = fling_delta.y;
EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
.WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);

// Keyboard events received during a fling should cancel the active fling.
EXPECT_CALL(mock_input_handler_, ScrollEnd());
EXPECT_EQ(InputHandlerProxy::DID_NOT_HANDLE,
input_handler_->HandleInputEvent(key_event));
EXPECT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);

// The call to animate should have no effect, as the fling was cancelled.
base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
input_handler_->Animate(time);
testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);

// A fling cancel should be dropped, as there is nothing to cancel.
gesture_.type = WebInputEvent::GestureFlingCancel;
EXPECT_EQ(InputHandlerProxy::DROP_EVENT,
input_handler_->HandleInputEvent(gesture_));
EXPECT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
}

} // namespace
} // namespace content

0 comments on commit c9440b2

Please sign in to comment.