diff options
author | lanwei <lanwei@chromium.org> | 2014-12-22 14:36:59 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-12-22 22:37:58 +0000 |
commit | b3361bcdd3766a67c702c19781154c895fee75ca (patch) | |
tree | 5a3573c8490deaa93d1ef67169e2cdf7cfe1d43d /content | |
parent | d355ff75f2eb9129cb06e160c5beb1590d7d0ee3 (diff) | |
download | chromium_src-b3361bcdd3766a67c702c19781154c895fee75ca.zip chromium_src-b3361bcdd3766a67c702c19781154c895fee75ca.tar.gz chromium_src-b3361bcdd3766a67c702c19781154c895fee75ca.tar.bz2 |
Explicitly suppress scrolling for wheel events that will trigger zooming
We added a flag in Blink to decide if Ctrl-wheel-scroll should scroll or zoom, and now we use this flag in chromium code.
This patch is part of a series:
patch #1: https://codereview.chromium.org/759073002
patch #2: This CL
patch #3: https://codereview.chromium.org/768443002
BUG=397027, 378755
Review URL: https://codereview.chromium.org/739013008
Cr-Commit-Position: refs/heads/master@{#309472}
Diffstat (limited to 'content')
12 files changed, 198 insertions, 49 deletions
diff --git a/content/browser/renderer_host/input/input_router_impl.cc b/content/browser/renderer_host/input/input_router_impl.cc index 9113bee..b802aed 100644 --- a/content/browser/renderer_host/input/input_router_impl.cc +++ b/content/browser/renderer_host/input/input_router_impl.cc @@ -136,11 +136,14 @@ void InputRouterImpl::SendWheelEvent(const QueuedWheelEvent& wheel_event) { // dropping the old event, as for mouse moves) results in very slow // scrolling on the Mac (on which many, very small wheel events are sent). // Note that we can't coalesce wheel events for pinches because the GEQ - // expects one ACK for each (but it's fine to coalesce non-pinch wheels - // into a pinch one). Note that the GestureEventQueue ensures we only - // ever have a single pinch event queued here. + // expects one ACK for each. But such events always have canScroll==false + // and hasPreciseDeltas=true, which should never happen for a real wheel + // event and so coalescing shouldn't occur. Note that the + // GestureEventQueue ensures we only ever have a single pinch event queued + // here. if (coalesced_mouse_wheel_events_.empty() || - wheel_event.synthesized_from_pinch || + wheel_event.synthesized_from_pinch != + coalesced_mouse_wheel_events_.back().synthesized_from_pinch || !coalesced_mouse_wheel_events_.back().event.CanCoalesceWith( wheel_event.event)) { coalesced_mouse_wheel_events_.push_back(wheel_event); @@ -458,7 +461,7 @@ void InputRouterImpl::SendSyntheticWheelEventForPinch( wheelEvent.wheelTicksX = 0; wheelEvent.wheelTicksY = pinch_event.event.data.pinchUpdate.scale > 1 ? 1 : -1; - + wheelEvent.canScroll = false; SendWheelEvent(QueuedWheelEvent( MouseWheelEventWithLatencyInfo(wheelEvent, pinch_event.latency), true)); } diff --git a/content/browser/renderer_host/input/input_router_impl_unittest.cc b/content/browser/renderer_host/input/input_router_impl_unittest.cc index 3fa0b93..147f975 100644 --- a/content/browser/renderer_host/input/input_router_impl_unittest.cc +++ b/content/browser/renderer_host/input/input_router_impl_unittest.cc @@ -1631,6 +1631,7 @@ TEST_F(InputRouterImplTest, TouchpadPinchUpdate) { EXPECT_TRUE(wheel_event->hasPreciseScrollingDeltas); EXPECT_EQ(1, wheel_event->wheelTicksY); EXPECT_EQ(0, wheel_event->wheelTicksX); + EXPECT_FALSE(wheel_event->canScroll); EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); // Indicate that the wheel event was unhandled. @@ -1653,6 +1654,7 @@ TEST_F(InputRouterImplTest, TouchpadPinchUpdate) { EXPECT_FLOAT_EQ(PinchScaleToWheelDelta(0.3f), wheel_event->deltaY); EXPECT_TRUE(wheel_event->hasPreciseScrollingDeltas); EXPECT_EQ(-1, wheel_event->wheelTicksY); + EXPECT_FALSE(wheel_event->canScroll); EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); // Indicate that the wheel event was handled this time. @@ -1732,8 +1734,7 @@ TEST_F(InputRouterImplTest, TouchpadPinchAndWheel) { // Note that in practice interleaving pinch and wheel events should be rare // (eg. requires the use of a mouse and trackpad at the same time). - // Use the control modifier to match the synthetic wheel events so that - // they're elligble for coalescing. + // Synthetic wheel and real wheel events can never be coalesced together. int mod = WebInputEvent::ControlKey; // Event 1: sent directly. @@ -1744,7 +1745,8 @@ TEST_F(InputRouterImplTest, TouchpadPinchAndWheel) { SimulateWheelEvent(0, -10, mod, true); EXPECT_EQ(0U, GetSentMessageCountAndResetSink()); - // Event 3: enqueued in InputRouter, not coalesced into #2. + // Event 3: enqueued in InputRouter, not coalesced into #2 because of + // synthesized_from_pinch. SimulateGesturePinchUpdateEvent( 1.5f, 20, 25, 0, blink::WebGestureDeviceTouchpad); EXPECT_EQ(0U, GetSentMessageCountAndResetSink()); @@ -1754,10 +1756,15 @@ TEST_F(InputRouterImplTest, TouchpadPinchAndWheel) { 1.2f, 20, 25, 0, blink::WebGestureDeviceTouchpad); EXPECT_EQ(0U, GetSentMessageCountAndResetSink()); - // Event 5: coalesced into wheel event for #3. + // Event 5: enqueued in InputRouter, not coalesced into #3 because of + // synthesized_from_pinch. SimulateWheelEvent(2, 0, mod, true); EXPECT_EQ(0U, GetSentMessageCountAndResetSink()); + // Event 6: coalesced into #5. + SimulateWheelEvent(0, 3, mod, true); + EXPECT_EQ(0U, GetSentMessageCountAndResetSink()); + // Send ack for #1. SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); @@ -1774,6 +1781,7 @@ TEST_F(InputRouterImplTest, TouchpadPinchAndWheel) { EXPECT_EQ(0, wheel_event->deltaX); EXPECT_EQ(-10, wheel_event->deltaY); EXPECT_EQ(mod, wheel_event->modifiers); + EXPECT_TRUE(wheel_event->canScroll); EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); // Send ack for #2. @@ -1782,22 +1790,41 @@ TEST_F(InputRouterImplTest, TouchpadPinchAndWheel) { EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount()); EXPECT_EQ(WebInputEvent::MouseWheel, ack_handler_->ack_event_type()); - // Verify we sent #3 (with #5 coalesced in). + // Verify we sent #3. ASSERT_EQ(1U, process_->sink().message_count()); input_event = GetInputEventFromMessage(*process_->sink().GetMessageAt(0)); ASSERT_EQ(WebInputEvent::MouseWheel, input_event->type); wheel_event = static_cast<const WebMouseWheelEvent*>(input_event); - EXPECT_EQ(2, wheel_event->deltaX); + EXPECT_EQ(0, wheel_event->deltaX); EXPECT_EQ(PinchScaleToWheelDelta(1.5f), wheel_event->deltaY); EXPECT_EQ(mod, wheel_event->modifiers); + EXPECT_FALSE(wheel_event->canScroll); EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); + // Send ack for #3. SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount()); EXPECT_EQ(WebInputEvent::GesturePinchUpdate, ack_handler_->ack_event_type()); + // Verify we sent #5 with #6 coalesced into it. + ASSERT_EQ(1U, process_->sink().message_count()); + input_event = GetInputEventFromMessage(*process_->sink().GetMessageAt(0)); + ASSERT_EQ(WebInputEvent::MouseWheel, input_event->type); + wheel_event = static_cast<const WebMouseWheelEvent*>(input_event); + EXPECT_EQ(2, wheel_event->deltaX); + EXPECT_EQ(3, wheel_event->deltaY); + EXPECT_EQ(mod, wheel_event->modifiers); + EXPECT_TRUE(wheel_event->canScroll); + EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); + + // Send ack for #5. + SendInputEventACK(WebInputEvent::MouseWheel, + INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount()); + EXPECT_EQ(WebInputEvent::MouseWheel, ack_handler_->ack_event_type()); + // Verify we sent #4. ASSERT_EQ(1U, process_->sink().message_count()); input_event = GetInputEventFromMessage(*process_->sink().GetMessageAt(0)); @@ -1806,6 +1833,7 @@ TEST_F(InputRouterImplTest, TouchpadPinchAndWheel) { EXPECT_EQ(0, wheel_event->deltaX); EXPECT_FLOAT_EQ(PinchScaleToWheelDelta(1.2f), wheel_event->deltaY); EXPECT_EQ(mod, wheel_event->modifiers); + EXPECT_FALSE(wheel_event->canScroll); EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); // Send ack for #4. diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc index 13d986b..9bdfbcc 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc @@ -308,6 +308,15 @@ class MockWindowObserver : public aura::WindowObserver { MOCK_METHOD2(OnDelegatedFrameDamage, void(aura::Window*, const gfx::Rect&)); }; +const WebInputEvent* GetInputEventFromMessage(const IPC::Message& message) { + PickleIterator iter(message); + const char* data; + int data_length; + if (!iter.ReadData(&data, &data_length)) + return NULL; + return reinterpret_cast<const WebInputEvent*>(data); +} + } // namespace class RenderWidgetHostViewAuraTest : public testing::Test { @@ -388,6 +397,15 @@ class RenderWidgetHostViewAuraTest : public testing::Test { RendererFrameManager::GetInstance()->OnMemoryPressure(level); } + void SendInputEventACK(WebInputEvent::Type type, + InputEventAckState ack_result) { + InputHostMsg_HandleInputEvent_ACK_Params ack; + ack.type = type; + ack.state = ack_result; + InputHostMsg_HandleInputEvent_ACK response(0, ack); + widget_host_->OnMessageReceived(response); + } + protected: // If true, then calls RWH::Shutdown() instead of deleting RWH. bool widget_host_uses_shutdown_to_destroy_; @@ -580,15 +598,6 @@ class RenderWidgetHostViewAuraOverscrollTest velocityX, velocityY, sourceDevice)); } - void SendInputEventACK(WebInputEvent::Type type, - InputEventAckState ack_result) { - InputHostMsg_HandleInputEvent_ACK_Params ack; - ack.type = type; - ack.state = ack_result; - InputHostMsg_HandleInputEvent_ACK response(0, ack); - widget_host_->OnMessageReceived(response); - } - bool ScrollStateIsContentScrolling() const { return scroll_state() == OverscrollController::STATE_CONTENT_SCROLLING; } @@ -3071,4 +3080,57 @@ TEST_F(RenderWidgetHostViewAuraTest, KeyEvent) { } } +TEST_F(RenderWidgetHostViewAuraTest, SetCanScrollForWebMouseWheelEvent) { + view_->InitAsChild(NULL); + view_->Show(); + + sink_->ClearMessages(); + + // Simulates the mouse wheel event with ctrl modifier applied. + ui::MouseWheelEvent event(gfx::Vector2d(1, 1), + gfx::Point(), gfx::Point(), + ui::EF_CONTROL_DOWN, 0); + view_->OnMouseEvent(&event); + + const WebInputEvent* input_event = + GetInputEventFromMessage(*sink_->GetMessageAt(0)); + const WebMouseWheelEvent* wheel_event = + static_cast<const WebMouseWheelEvent*>(input_event); + // Check if the canScroll set to false when ctrl-scroll is generated from + // mouse wheel event. + EXPECT_FALSE(wheel_event->canScroll); + sink_->ClearMessages(); + + // Ack'ing the outstanding event should flush the pending event queue. + SendInputEventACK(blink::WebInputEvent::MouseWheel, + INPUT_EVENT_ACK_STATE_CONSUMED); + + // Simulates the mouse wheel event with no modifier applied. + event = ui::MouseWheelEvent(gfx::Vector2d(1, 1), gfx::Point(), gfx::Point(), + ui::EF_NONE, 0); + + view_->OnMouseEvent(&event); + + input_event = GetInputEventFromMessage(*sink_->GetMessageAt(0)); + wheel_event = static_cast<const WebMouseWheelEvent*>(input_event); + // Check if the canScroll set to true when no modifier is applied to the + // mouse wheel event. + EXPECT_TRUE(wheel_event->canScroll); + sink_->ClearMessages(); + + SendInputEventACK(blink::WebInputEvent::MouseWheel, + INPUT_EVENT_ACK_STATE_CONSUMED); + + // Simulates the scroll event with ctrl modifier applied. + ui::ScrollEvent scroll(ui::ET_SCROLL, gfx::Point(2, 2), ui::EventTimeForNow(), + ui::EF_CONTROL_DOWN, 0, 5, 0, 5, 2); + view_->OnScrollEvent(&scroll); + + input_event = GetInputEventFromMessage(*sink_->GetMessageAt(0)); + wheel_event = static_cast<const WebMouseWheelEvent*>(input_event); + // Check if the canScroll set to true when ctrl-touchpad-scroll is generated + // from scroll event. + EXPECT_TRUE(wheel_event->canScroll); +} + } // namespace content diff --git a/content/browser/renderer_host/web_input_event_aura.cc b/content/browser/renderer_host/web_input_event_aura.cc index c4a766a..76bdbf1 100644 --- a/content/browser/renderer_host/web_input_event_aura.cc +++ b/content/browser/renderer_host/web_input_event_aura.cc @@ -193,14 +193,23 @@ blink::WebMouseWheelEvent MakeWebMouseWheelEvent( webkit_event.globalX = root_point.x(); webkit_event.globalY = root_point.y(); + // Scroll events generated from the mouse wheel when the control key is held + // don't trigger scrolling. Instead, they may cause zooming. + bool from_mouse_wheel = !webkit_event.hasPreciseScrollingDeltas; + if ((webkit_event.modifiers & blink::WebInputEvent::ControlKey) && + from_mouse_wheel) { + webkit_event.canScroll = false; + } + return webkit_event; } blink::WebMouseWheelEvent MakeWebMouseWheelEvent(const ui::ScrollEvent& event) { #if defined(OS_WIN) // Construct an untranslated event from the platform event data. - blink::WebMouseWheelEvent webkit_event = - MakeUntranslatedWebMouseWheelEventFromNativeEvent(event.native_event()); + blink::WebMouseWheelEvent webkit_event = event.native_event().message ? + MakeUntranslatedWebMouseWheelEventFromNativeEvent(event.native_event()) : + MakeWebMouseWheelEventFromAuraEvent(event); #else blink::WebMouseWheelEvent webkit_event = MakeWebMouseWheelEventFromAuraEvent(event); diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 7151e15..44f103c 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -1333,18 +1333,15 @@ void WebContentsImpl::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) { bool WebContentsImpl::HandleWheelEvent( const blink::WebMouseWheelEvent& event) { #if !defined(OS_MACOSX) - // On platforms other than Mac, control+mousewheel changes zoom. On Mac, this - // isn't done for two reasons: + // On platforms other than Mac, control+mousewheel may change zoom. On Mac, + // this isn't done for two reasons: // -the OS already has a gesture to do this through pinch-zoom // -if a user starts an inertial scroll, let's go, and presses control // (i.e. control+tab) then the OS's buffered scroll events will come in // with control key set which isn't what the user wants - if (delegate_ && - event.wheelTicksY && + if (delegate_ && event.wheelTicksY && (event.modifiers & blink::WebInputEvent::ControlKey) && - // Avoid adjusting the zoom in response to two-finger-scrolling touchpad - // gestures, which are regrettably easy to trigger accidentally. - !event.hasPreciseScrollingDeltas) { + !event.canScroll) { delegate_->ContentsZoomChange(event.wheelTicksY > 0); return true; } diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc index ba1a8f0..12d04ee 100644 --- a/content/browser/web_contents/web_contents_impl_unittest.cc +++ b/content/browser/web_contents/web_contents_impl_unittest.cc @@ -2476,15 +2476,18 @@ TEST_F(WebContentsImplTest, HandleWheelEvent) { EXPECT_FALSE(contents()->HandleWheelEvent(event)); EXPECT_EQ(0, delegate->GetAndResetContentsZoomChangedCallCount()); - modifiers = WebInputEvent::ShiftKey | WebInputEvent::AltKey; + modifiers = WebInputEvent::ShiftKey | WebInputEvent::AltKey | + WebInputEvent::ControlKey; event = SyntheticWebMouseWheelEventBuilder::Build(0, 1, modifiers, false); EXPECT_FALSE(contents()->HandleWheelEvent(event)); EXPECT_EQ(0, delegate->GetAndResetContentsZoomChangedCallCount()); - // But whenever the ctrl modifier is applied, they can increase/decrease zoom. - // Except on MacOS where we never want to adjust zoom with mousewheel. + // But whenever the ctrl modifier is applied with canScroll=false, they can + // increase/decrease zoom. Except on MacOS where we never want to adjust zoom + // with mousewheel. modifiers = WebInputEvent::ControlKey; event = SyntheticWebMouseWheelEventBuilder::Build(0, 1, modifiers, false); + event.canScroll = false; bool handled = contents()->HandleWheelEvent(event); #if defined(OS_MACOSX) EXPECT_FALSE(handled); @@ -2498,6 +2501,7 @@ TEST_F(WebContentsImplTest, HandleWheelEvent) { modifiers = WebInputEvent::ControlKey | WebInputEvent::ShiftKey | WebInputEvent::AltKey; event = SyntheticWebMouseWheelEventBuilder::Build(2, -5, modifiers, false); + event.canScroll = false; handled = contents()->HandleWheelEvent(event); #if defined(OS_MACOSX) EXPECT_FALSE(handled); diff --git a/content/common/input/synthetic_web_input_event_builders.cc b/content/common/input/synthetic_web_input_event_builders.cc index ab2968a..3efbbb7 100644 --- a/content/common/input/synthetic_web_input_event_builders.cc +++ b/content/common/input/synthetic_web_input_event_builders.cc @@ -68,6 +68,7 @@ WebMouseWheelEvent SyntheticWebMouseWheelEventBuilder::Build(float dx, result.wheelTicksY = dy > 0.0f ? 1.0f : -1.0f; result.modifiers = modifiers; result.hasPreciseScrollingDeltas = precise; + result.canScroll = true; return result; } diff --git a/content/common/input/web_input_event_traits.cc b/content/common/input/web_input_event_traits.cc index 4e9c754..9466a17 100644 --- a/content/common/input/web_input_event_traits.cc +++ b/content/common/input/web_input_event_traits.cc @@ -58,7 +58,7 @@ void ApppendEventDetails(const WebMouseWheelEvent& event, std::string* result) { StringAppendF(result, "{\n Delta: (%f, %f)\n WheelTicks: (%f, %f)\n Accel: (%f, %f)\n" " ScrollByPage: %d\n HasPreciseScrollingDeltas: %d\n" - " Phase: (%d, %d)\n CanRubberband: (%d, %d)\n}", + " Phase: (%d, %d)\n CanRubberband: (%d, %d)\n CanScroll: %d\n}", event.deltaX, event.deltaY, event.wheelTicksX, @@ -70,7 +70,8 @@ void ApppendEventDetails(const WebMouseWheelEvent& event, std::string* result) { event.phase, event.momentumPhase, event.canRubberbandLeft, - event.canRubberbandRight); + event.canRubberbandRight, + event.canScroll); } void ApppendEventDetails(const WebGestureEvent& event, std::string* result) { @@ -149,7 +150,8 @@ bool CanCoalesce(const WebMouseWheelEvent& event_to_coalesce, event.phase == event_to_coalesce.phase && event.momentumPhase == event_to_coalesce.momentumPhase && event.hasPreciseScrollingDeltas == - event_to_coalesce.hasPreciseScrollingDeltas; + event_to_coalesce.hasPreciseScrollingDeltas && + event.canScroll == event_to_coalesce.canScroll; } float GetUnacceleratedDelta(float accelerated_delta, float acceleration_ratio) { diff --git a/content/common/input/web_input_event_traits_unittest.cc b/content/common/input/web_input_event_traits_unittest.cc index 7a7cb7f..d4bbeba 100644 --- a/content/common/input/web_input_event_traits_unittest.cc +++ b/content/common/input/web_input_event_traits_unittest.cc @@ -51,6 +51,17 @@ class WebInputEventTraitsTest : public testing::Test { event.y = y; return event; } + + static WebMouseWheelEvent CreateMouseWheel(float deltaX, + float deltaY, + bool canScroll) { + WebMouseWheelEvent event; + event.type = WebInputEvent::MouseWheel; + event.deltaX = deltaX; + event.deltaY = deltaY; + event.canScroll = canScroll; + return event; + } }; TEST_F(WebInputEventTraitsTest, TouchEventCoalescing) { @@ -162,6 +173,31 @@ TEST_F(WebInputEventTraitsTest, PinchEventCoalescing) { EXPECT_EQ(numeric_limits<float>::max(), pinch1.data.pinchUpdate.scale); } +TEST_F(WebInputEventTraitsTest, WebMouseWheelEventCoalescing) { + WebMouseWheelEvent mouseWheel0 = + CreateMouseWheel(1, 1, true); + WebMouseWheelEvent mouseWheel1 = + CreateMouseWheel(2, 2, true); + + // WebMouseWheelEvent objects with same values except different deltaX and + // deltaY should coalesce. + EXPECT_TRUE(WebInputEventTraits::CanCoalesce(mouseWheel0, mouseWheel1)); + + mouseWheel0 = CreateMouseWheel(1, 1, true); + mouseWheel1 = CreateMouseWheel(1, 1, false); + + // WebMouseWheelEvent objects with different canScroll values should not + // coalesce. + EXPECT_FALSE(WebInputEventTraits::CanCoalesce(mouseWheel0, mouseWheel1)); + + // WebMouseWheelEvent objects with different modifiers should not coalesce. + mouseWheel0 = CreateMouseWheel(1, 1, true); + mouseWheel1 = CreateMouseWheel(1, 1, true); + mouseWheel0.modifiers = blink::WebInputEvent::ControlKey; + mouseWheel1.modifiers = blink::WebInputEvent::ShiftKey; + EXPECT_FALSE(WebInputEventTraits::CanCoalesce(mouseWheel0, mouseWheel1)); +} + // Very basic smoke test to ensure stringification doesn't explode. TEST_F(WebInputEventTraitsTest, ToString) { WebKeyboardEvent key; diff --git a/content/renderer/input/input_handler_proxy.cc b/content/renderer/input/input_handler_proxy.cc index 3edb957..602f113 100644 --- a/content/renderer/input/input_handler_proxy.cc +++ b/content/renderer/input/input_handler_proxy.cc @@ -324,9 +324,9 @@ InputHandlerProxy::EventDisposition InputHandlerProxy::HandleMouseWheel( // TODO(jamesr): We don't properly handle scroll by page in the compositor // thread, so punt it to the main thread. http://crbug.com/236639 result = DID_NOT_HANDLE; - } else if (wheel_event.modifiers & WebInputEvent::ControlKey) { - // Wheel events involving the control key never trigger scrolling, only - // event handlers. Forward to the main thread. + } else if (!wheel_event.canScroll) { + // Wheel events with |canScroll| == false will not trigger scrolling, + // only event handlers. Forward to the main thread. result = DID_NOT_HANDLE; } else if (smooth_scroll_enabled_) { cc::InputHandler::ScrollStatus scroll_status = diff --git a/content/renderer/input/input_handler_proxy_unittest.cc b/content/renderer/input/input_handler_proxy_unittest.cc index cb85701..ad715ac 100644 --- a/content/renderer/input/input_handler_proxy_unittest.cc +++ b/content/renderer/input/input_handler_proxy_unittest.cc @@ -288,12 +288,12 @@ TEST_F(InputHandlerProxyTest, MouseWheelByPageMainThread) { testing::Mock::VerifyAndClearExpectations(&mock_client_); } -TEST_F(InputHandlerProxyTest, MouseWheelWithCtrl) { +TEST_F(InputHandlerProxyTest, MouseWheelWithCtrlNotScroll) { expected_disposition_ = InputHandlerProxy::DID_NOT_HANDLE; WebMouseWheelEvent wheel; wheel.type = WebInputEvent::MouseWheel; wheel.modifiers = WebInputEvent::ControlKey; - + wheel.canScroll = false; EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(wheel)); testing::Mock::VerifyAndClearExpectations(&mock_client_); } diff --git a/content/shell/renderer/test_runner/event_sender.cc b/content/shell/renderer/test_runner/event_sender.cc index b22fe72..8971ab6 100644 --- a/content/shell/renderer/test_runner/event_sender.cc +++ b/content/shell/renderer/test_runner/event_sender.cc @@ -2207,14 +2207,21 @@ void EventSender::InitMouseWheelEvent(gin::Arguments* args, bool paged = false; bool has_precise_scrolling_deltas = false; int modifiers = 0; - if (!args->PeekNext().IsEmpty()) { - args->GetNext(&paged); - if (!args->PeekNext().IsEmpty()) { - args->GetNext(&has_precise_scrolling_deltas); - if (!args->PeekNext().IsEmpty()) - modifiers = GetKeyModifiersFromV8(args->PeekNext()); - } - } + bool can_scroll = true; + if (args->PeekNext().IsEmpty()) + return; + args->GetNext(&paged); + if (args->PeekNext().IsEmpty()) + return; + args->GetNext(&has_precise_scrolling_deltas); + if (args->PeekNext().IsEmpty()) + return; + v8::Handle<v8::Value> value; + args->GetNext(&value); + modifiers = GetKeyModifiersFromV8(value); + if (args->PeekNext().IsEmpty()) + return; + args->GetNext(&can_scroll); InitMouseEvent(WebInputEvent::MouseWheel, pressed_button_, @@ -2229,7 +2236,7 @@ void EventSender::InitMouseWheelEvent(gin::Arguments* args, event->deltaY = event->wheelTicksY; event->scrollByPage = paged; event->hasPreciseScrollingDeltas = has_precise_scrolling_deltas; - + event->canScroll = can_scroll; if (continuous) { event->wheelTicksX /= kScrollbarPixelsPerTick; event->wheelTicksY /= kScrollbarPixelsPerTick; |