summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/renderer_host/gesture_event_filter.cc32
-rw-r--r--content/browser/renderer_host/gesture_event_filter.h20
-rw-r--r--content/browser/renderer_host/input/OWNERS2
-rw-r--r--content/browser/renderer_host/input/immediate_input_router.cc547
-rw-r--r--content/browser/renderer_host/input/immediate_input_router.h193
-rw-r--r--content/browser/renderer_host/input/input_router.h70
-rw-r--r--content/browser/renderer_host/input/input_router_client.h78
-rw-r--r--content/browser/renderer_host/overscroll_controller.cc24
-rw-r--r--content/browser/renderer_host/overscroll_controller.h4
-rw-r--r--content/browser/renderer_host/render_widget_host_impl.cc820
-rw-r--r--content/browser/renderer_host/render_widget_host_impl.h161
-rw-r--r--content/browser/renderer_host/render_widget_host_unittest.cc42
-rw-r--r--content/browser/renderer_host/touch_event_queue.cc40
-rw-r--r--content/browser/renderer_host/touch_event_queue.h32
-rw-r--r--content/browser/renderer_host/touchpad_tap_suppression_controller.cc4
-rw-r--r--content/browser/renderer_host/touchpad_tap_suppression_controller.h7
-rw-r--r--content/browser/renderer_host/touchpad_tap_suppression_controller_aura.cc10
-rw-r--r--content/content_browser.gypi4
18 files changed, 761 insertions, 1329 deletions
diff --git a/content/browser/renderer_host/gesture_event_filter.cc b/content/browser/renderer_host/gesture_event_filter.cc
index bdf360d..7f8d170 100644
--- a/content/browser/renderer_host/gesture_event_filter.cc
+++ b/content/browser/renderer_host/gesture_event_filter.cc
@@ -6,7 +6,7 @@
#include "base/command_line.h"
#include "base/strings/string_number_conversions.h"
-#include "content/browser/renderer_host/input/input_router.h"
+#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/touchpad_tap_suppression_controller.h"
#include "content/browser/renderer_host/touchscreen_tap_suppression_controller.h"
#include "content/public/common/content_switches.h"
@@ -58,14 +58,14 @@ static int GetTapDownDeferralTimeMs() {
}
} // namespace
-GestureEventFilter::GestureEventFilter(InputRouter* input_router)
- : input_router_(input_router),
+GestureEventFilter::GestureEventFilter(RenderWidgetHostImpl* rwhv)
+ : render_widget_host_(rwhv),
fling_in_progress_(false),
scrolling_in_progress_(false),
ignore_next_ack_(false),
combined_scroll_pinch_(gfx::Transform()),
touchpad_tap_suppression_controller_(
- new TouchpadTapSuppressionController(input_router)),
+ new TouchpadTapSuppressionController(rwhv)),
touchscreen_tap_suppression_controller_(
new TouchscreenTapSuppressionController(this)),
maximum_tap_gap_time_ms_(GetTapDownDeferralTimeMs()),
@@ -242,6 +242,19 @@ bool GestureEventFilter::ShouldForwardForCoalescing(
return ShouldHandleEventNow();
}
+void GestureEventFilter::Reset() {
+ fling_in_progress_ = false;
+ scrolling_in_progress_ = false;
+ ignore_next_ack_ = false;
+ combined_scroll_pinch_ = gfx::Transform();
+ coalesced_gesture_events_.clear();
+ deferred_tap_down_event_.event.type = WebInputEvent::Undefined;
+ debouncing_deferral_queue_.clear();
+ send_gtd_timer_.Stop();
+ debounce_deferring_timer_.Stop();
+ // TODO(rjkroege): Reset the tap suppression controller.
+}
+
void GestureEventFilter::ProcessGestureAck(bool processed, int type) {
if (coalesced_gesture_events_.empty()) {
DLOG(ERROR) << "Received unexpected ACK for event type " << type;
@@ -261,7 +274,7 @@ void GestureEventFilter::ProcessGestureAck(bool processed, int type) {
} else if (!coalesced_gesture_events_.empty()) {
const GestureEventWithLatencyInfo& next_gesture_event =
coalesced_gesture_events_.front();
- input_router_->SendGestureEventImmediately(next_gesture_event);
+ render_widget_host_->ForwardGestureEventImmediately(next_gesture_event);
// TODO(yusufo): Introduce GesturePanScroll so that these can be combined
// into one gesture and kept inside the queue that way.
if (coalesced_gesture_events_.size() > 1) {
@@ -271,7 +284,8 @@ void GestureEventFilter::ProcessGestureAck(bool processed, int type) {
WebInputEvent::GestureScrollUpdate &&
second_gesture_event.event.type ==
WebInputEvent::GesturePinchUpdate) {
- input_router_->SendGestureEventImmediately(second_gesture_event);
+ render_widget_host_->
+ ForwardGestureEventImmediately(second_gesture_event);
ignore_next_ack_ = true;
combined_scroll_pinch_ = gfx::Transform();
}
@@ -288,7 +302,7 @@ bool GestureEventFilter::HasQueuedGestureEvents() const {
return !coalesced_gesture_events_.empty();
}
-const WebKit::WebGestureEvent&
+const WebKit::WebInputEvent&
GestureEventFilter::GetGestureEventAwaitingAck() const {
DCHECK(!coalesced_gesture_events_.empty());
if (!ignore_next_ack_)
@@ -314,7 +328,7 @@ void GestureEventFilter::ForwardGestureEventForDeferral(
void GestureEventFilter::ForwardGestureEventSkipDeferral(
const GestureEventWithLatencyInfo& gesture_event) {
if (ShouldForwardForCoalescing(gesture_event))
- input_router_->SendGestureEventImmediately(gesture_event);
+ render_widget_host_->ForwardGestureEventImmediately(gesture_event);
}
void GestureEventFilter::SendGestureTapDownNow() {
@@ -335,7 +349,7 @@ void GestureEventFilter::SendScrollEndingEventsNow() {
ShouldForwardForTapSuppression(*it) &&
ShouldForwardForTapDeferral(*it) &&
ShouldForwardForCoalescing(*it)) {
- input_router_->SendGestureEventImmediately(*it);
+ render_widget_host_->ForwardGestureEventImmediately(*it);
}
}
debouncing_deferral_queue_.clear();
diff --git a/content/browser/renderer_host/gesture_event_filter.h b/content/browser/renderer_host/gesture_event_filter.h
index 8330502..23cce42 100644
--- a/content/browser/renderer_host/gesture_event_filter.h
+++ b/content/browser/renderer_host/gesture_event_filter.h
@@ -15,8 +15,8 @@
#include "ui/gfx/transform.h"
namespace content {
-class InputRouter;
class MockRenderWidgetHost;
+class RenderWidgetHostImpl;
class TouchpadTapSuppressionController;
class TouchscreenTapSuppressionController;
@@ -43,19 +43,21 @@ class TouchscreenTapSuppressionController;
// http://crbug.com/148443.
class GestureEventFilter {
public:
- // The |input_router| must outlive the GestureEventFilter.
- explicit GestureEventFilter(InputRouter* input_router);
+ explicit GestureEventFilter(RenderWidgetHostImpl*);
~GestureEventFilter();
// Returns |true| if the caller should immediately forward the provided
// |GestureEventWithLatencyInfo| argument to the renderer.
bool ShouldForward(const GestureEventWithLatencyInfo&);
- // Indicates that the caller has received an acknowledgement from the renderer
- // with state |processed| and event |type|. May send events if the queue is
- // not empty.
+ // Indicates that the calling RenderWidgetHostImpl has received an
+ // acknowledgement from the renderer with state |processed| and event |type|.
+ // May send events if the queue is not empty.
void ProcessGestureAck(bool processed, int type);
+ // Resets the state of the filter as would be needed when the renderer exits.
+ void Reset();
+
// Sets the state of the |fling_in_progress_| field to indicate that a fling
// is definitely not in progress.
void FlingHasBeenHalted();
@@ -67,7 +69,7 @@ class GestureEventFilter {
bool HasQueuedGestureEvents() const;
// Returns the last gesture event that was sent to the renderer.
- const WebKit::WebGestureEvent& GetGestureEventAwaitingAck() const;
+ const WebKit::WebInputEvent& GetGestureEventAwaitingAck() const;
// Tries forwarding the event to the tap deferral sub-filter.
void ForwardGestureEventForDeferral(
@@ -144,8 +146,8 @@ class GestureEventFilter {
gfx::Transform GetTransformForEvent(
const GestureEventWithLatencyInfo& gesture_event);
- // The receiver of all forwarded gesture events.
- InputRouter* input_router_;
+ // Only a RenderWidgetHostViewImpl can own an instance.
+ RenderWidgetHostImpl* render_widget_host_;
// True if a GestureFlingStart is in progress on the renderer or
// queued without a subsequent queued GestureFlingCancel event.
diff --git a/content/browser/renderer_host/input/OWNERS b/content/browser/renderer_host/input/OWNERS
deleted file mode 100644
index 4dabaf0..0000000
--- a/content/browser/renderer_host/input/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-nduca@chromium.org
-aelias@chromium.org
diff --git a/content/browser/renderer_host/input/immediate_input_router.cc b/content/browser/renderer_host/input/immediate_input_router.cc
deleted file mode 100644
index cd1e490..0000000
--- a/content/browser/renderer_host/input/immediate_input_router.cc
+++ /dev/null
@@ -1,547 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/renderer_host/input/immediate_input_router.h"
-
-#include "base/command_line.h"
-#include "base/metrics/histogram.h"
-#include "content/browser/renderer_host/gesture_event_filter.h"
-#include "content/browser/renderer_host/input/input_router_client.h"
-#include "content/browser/renderer_host/render_process_host_impl.h"
-#include "content/browser/renderer_host/touch_event_queue.h"
-#include "content/browser/renderer_host/touchpad_tap_suppression_controller.h"
-#include "content/common/content_constants_internal.h"
-#include "content/common/edit_command.h"
-#include "content/common/input_messages.h"
-#include "content/common/view_messages.h"
-#include "content/port/common/input_event_ack_state.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/notification_types.h"
-#include "content/public/browser/user_metrics.h"
-#include "content/public/common/content_switches.h"
-#include "ui/base/events/event.h"
-#include "ui/base/keycodes/keyboard_codes.h"
-
-using base::Time;
-using base::TimeDelta;
-using base::TimeTicks;
-using WebKit::WebGestureEvent;
-using WebKit::WebInputEvent;
-using WebKit::WebKeyboardEvent;
-using WebKit::WebMouseEvent;
-using WebKit::WebMouseWheelEvent;
-
-namespace content {
-namespace {
-
-// Returns |true| if the two wheel events should be coalesced.
-bool ShouldCoalesceMouseWheelEvents(const WebMouseWheelEvent& last_event,
- const WebMouseWheelEvent& new_event) {
- return last_event.modifiers == new_event.modifiers &&
- last_event.scrollByPage == new_event.scrollByPage &&
- last_event.hasPreciseScrollingDeltas
- == new_event.hasPreciseScrollingDeltas &&
- last_event.phase == new_event.phase &&
- last_event.momentumPhase == new_event.momentumPhase;
-}
-
-float GetUnacceleratedDelta(float accelerated_delta, float acceleration_ratio) {
- return accelerated_delta * acceleration_ratio;
-}
-
-float GetAccelerationRatio(float accelerated_delta, float unaccelerated_delta) {
- if (unaccelerated_delta == 0.f || accelerated_delta == 0.f)
- return 1.f;
- return unaccelerated_delta / accelerated_delta;
-}
-
-const char* GetEventAckName(InputEventAckState ack_result) {
- switch(ack_result) {
- case INPUT_EVENT_ACK_STATE_UNKNOWN: return "UNKNOWN";
- case INPUT_EVENT_ACK_STATE_CONSUMED: return "CONSUMED";
- case INPUT_EVENT_ACK_STATE_NOT_CONSUMED: return "NOT_CONSUMED";
- case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: return "NO_CONSUMER_EXISTS";
- default:
- DLOG(WARNING) << "Unhandled InputEventAckState in GetEventAckName.\n";
- break;
- }
- return "";
-}
-
-} // namespace
-
-ImmediateInputRouter::ImmediateInputRouter(
- RenderProcessHost* process,
- InputRouterClient* client,
- int routing_id)
- : process_(process),
- client_(client),
- routing_id_(routing_id),
- select_range_pending_(false),
- move_caret_pending_(false),
- mouse_move_pending_(false),
- mouse_wheel_pending_(false),
- has_touch_handler_(false),
- touch_event_queue_(new TouchEventQueue(this)),
- gesture_event_filter_(new GestureEventFilter(this)) {
- DCHECK(process);
- DCHECK(client);
-}
-
-ImmediateInputRouter::~ImmediateInputRouter() {
-}
-
-bool ImmediateInputRouter::SendInput(IPC::Message* message) {
- DCHECK(IPC_MESSAGE_ID_CLASS(message->type()) == InputMsgStart);
- scoped_ptr<IPC::Message> scoped_message(message);
- switch (scoped_message->type()) {
- // Check for types that require an ACK.
- case InputMsg_SelectRange::ID:
- return SendSelectRange(scoped_message.release());
- case InputMsg_MoveCaret::ID:
- return SendMoveCaret(scoped_message.release());
- case InputMsg_HandleInputEvent::ID:
- NOTREACHED() << "WebInputEvents should never be sent via SendInput.";
- return false;
- default:
- return Send(scoped_message.release());
- }
-}
-
-void ImmediateInputRouter::SendMouseEvent(
- const MouseEventWithLatencyInfo& mouse_event) {
- if (!client_->OnSendMouseEvent(mouse_event))
- return;
-
- if (mouse_event.event.type == WebInputEvent::MouseDown &&
- gesture_event_filter_->GetTouchpadTapSuppressionController()->
- ShouldDeferMouseDown(mouse_event))
- return;
- if (mouse_event.event.type == WebInputEvent::MouseUp &&
- gesture_event_filter_->GetTouchpadTapSuppressionController()->
- ShouldSuppressMouseUp())
- return;
-
- SendMouseEventImmediately(mouse_event);
-}
-
-void ImmediateInputRouter::SendWheelEvent(
- const MouseWheelEventWithLatencyInfo& wheel_event) {
- if (!client_->OnSendWheelEvent(wheel_event))
- return;
-
- // If there's already a mouse wheel event waiting to be sent to the renderer,
- // add the new deltas to that event. Not doing so (e.g., by 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).
- if (mouse_wheel_pending_) {
- if (coalesced_mouse_wheel_events_.empty() ||
- !ShouldCoalesceMouseWheelEvents(
- coalesced_mouse_wheel_events_.back().event, wheel_event.event)) {
- coalesced_mouse_wheel_events_.push_back(wheel_event);
- } else {
- MouseWheelEventWithLatencyInfo* last_wheel_event =
- &coalesced_mouse_wheel_events_.back();
- float unaccelerated_x =
- GetUnacceleratedDelta(last_wheel_event->event.deltaX,
- last_wheel_event->event.accelerationRatioX) +
- GetUnacceleratedDelta(wheel_event.event.deltaX,
- wheel_event.event.accelerationRatioX);
- float unaccelerated_y =
- GetUnacceleratedDelta(last_wheel_event->event.deltaY,
- last_wheel_event->event.accelerationRatioY) +
- GetUnacceleratedDelta(wheel_event.event.deltaY,
- wheel_event.event.accelerationRatioY);
- last_wheel_event->event.deltaX += wheel_event.event.deltaX;
- last_wheel_event->event.deltaY += wheel_event.event.deltaY;
- last_wheel_event->event.wheelTicksX += wheel_event.event.wheelTicksX;
- last_wheel_event->event.wheelTicksY += wheel_event.event.wheelTicksY;
- last_wheel_event->event.accelerationRatioX =
- GetAccelerationRatio(last_wheel_event->event.deltaX, unaccelerated_x);
- last_wheel_event->event.accelerationRatioY =
- GetAccelerationRatio(last_wheel_event->event.deltaY, unaccelerated_y);
- DCHECK_GE(wheel_event.event.timeStampSeconds,
- last_wheel_event->event.timeStampSeconds);
- last_wheel_event->event.timeStampSeconds =
- wheel_event.event.timeStampSeconds;
- last_wheel_event->latency.MergeWith(wheel_event.latency);
- }
- return;
- }
- mouse_wheel_pending_ = true;
- current_wheel_event_ = wheel_event;
-
- HISTOGRAM_COUNTS_100("Renderer.WheelQueueSize",
- coalesced_mouse_wheel_events_.size());
-
- FilterAndSendWebInputEvent(wheel_event.event, wheel_event.latency, false);
-}
-
-void ImmediateInputRouter::SendKeyboardEvent(
- const NativeWebKeyboardEvent& key_event,
- const ui::LatencyInfo& latency_info) {
- bool is_shortcut = false;
- if (!client_->OnSendKeyboardEvent(key_event, latency_info, &is_shortcut))
- return;
-
- // Put all WebKeyboardEvent objects in a queue since we can't trust the
- // renderer and we need to give something to the HandleKeyboardEvent
- // handler.
- key_queue_.push_back(key_event);
- HISTOGRAM_COUNTS_100("Renderer.KeyboardQueueSize", key_queue_.size());
-
- gesture_event_filter_->FlingHasBeenHalted();
-
- // Only forward the non-native portions of our event.
- FilterAndSendWebInputEvent(key_event, latency_info, is_shortcut);
-}
-
-void ImmediateInputRouter::SendGestureEvent(
- const GestureEventWithLatencyInfo& gesture_event) {
- if (!client_->OnSendGestureEvent(gesture_event))
- return;
- FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false);
-}
-
-void ImmediateInputRouter::SendTouchEvent(
- const TouchEventWithLatencyInfo& touch_event) {
- // Always queue TouchEvents, even if the client request they be dropped.
- client_->OnSendTouchEvent(touch_event);
- touch_event_queue_->QueueEvent(touch_event);
-}
-
-// Forwards MouseEvent without passing it through
-// TouchpadTapSuppressionController.
-void ImmediateInputRouter::SendMouseEventImmediately(
- const MouseEventWithLatencyInfo& mouse_event) {
- if (!client_->OnSendMouseEventImmediately(mouse_event))
- return;
-
- // Avoid spamming the renderer with mouse move events. It is important
- // to note that WM_MOUSEMOVE events are anyways synthetic, but since our
- // thread is able to rapidly consume WM_MOUSEMOVE events, we may get way
- // more WM_MOUSEMOVE events than we wish to send to the renderer.
- if (mouse_event.event.type == WebInputEvent::MouseMove) {
- if (mouse_move_pending_) {
- if (!next_mouse_move_) {
- next_mouse_move_.reset(new MouseEventWithLatencyInfo(mouse_event));
- } else {
- // Accumulate movement deltas.
- int x = next_mouse_move_->event.movementX;
- int y = next_mouse_move_->event.movementY;
- next_mouse_move_->event = mouse_event.event;
- next_mouse_move_->event.movementX += x;
- next_mouse_move_->event.movementY += y;
- next_mouse_move_->latency.MergeWith(mouse_event.latency);
- }
- return;
- }
- mouse_move_pending_ = true;
- }
-
- FilterAndSendWebInputEvent(mouse_event.event, mouse_event.latency, false);
-}
-
-void ImmediateInputRouter::SendTouchEventImmediately(
- const TouchEventWithLatencyInfo& touch_event) {
- if (!client_->OnSendTouchEventImmediately(touch_event))
- return;
- FilterAndSendWebInputEvent(touch_event.event, touch_event.latency, false);
-}
-
-void ImmediateInputRouter::SendGestureEventImmediately(
- const GestureEventWithLatencyInfo& gesture_event) {
- if (!client_->OnSendGestureEventImmediately(gesture_event))
- return;
- FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false);
-}
-
-const NativeWebKeyboardEvent*
- ImmediateInputRouter::GetLastKeyboardEvent() const {
- if (key_queue_.empty())
- return NULL;
- return &key_queue_.front();
-}
-
-bool ImmediateInputRouter::ShouldForwardTouchEvent() const {
- // Always send a touch event if the renderer has a touch-event handler. It is
- // possible that a renderer stops listening to touch-events while there are
- // still events in the touch-queue. In such cases, the new events should still
- // get into the queue.
- return has_touch_handler_ || !touch_event_queue_->empty();
-}
-
-bool ImmediateInputRouter::ShouldForwardGestureEvent(
- const GestureEventWithLatencyInfo& touch_event) const {
- return gesture_event_filter_->ShouldForward(touch_event);
-}
-
-bool ImmediateInputRouter::HasQueuedGestureEvents() const {
- return gesture_event_filter_->HasQueuedGestureEvents();
-}
-
-bool ImmediateInputRouter::OnMessageReceived(const IPC::Message& message) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(ImmediateInputRouter, message)
- IPC_MESSAGE_HANDLER(InputHostMsg_HandleInputEvent_ACK, OnInputEventAck)
- IPC_MESSAGE_HANDLER(ViewHostMsg_MoveCaret_ACK, OnMsgMoveCaretAck)
- IPC_MESSAGE_HANDLER(ViewHostMsg_SelectRange_ACK, OnSelectRangeAck)
- IPC_MESSAGE_HANDLER(ViewHostMsg_HasTouchEventHandlers,
- OnHasTouchEventHandlers)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
-void ImmediateInputRouter::OnTouchEventAck(
- const TouchEventWithLatencyInfo& event,
- InputEventAckState ack_result) {
- client_->OnTouchEventAck(event, ack_result);
-}
-
-bool ImmediateInputRouter::SendSelectRange(IPC::Message* message) {
- DCHECK(message->type() == InputMsg_SelectRange::ID);
- if (select_range_pending_) {
- next_selection_range_.reset(message);
- return true;
- }
-
- select_range_pending_ = true;
- return Send(message);
-}
-
-bool ImmediateInputRouter::SendMoveCaret(IPC::Message* message) {
- DCHECK(message->type() == InputMsg_MoveCaret::ID);
- if (move_caret_pending_) {
- next_move_caret_.reset(message);
- return true;
- }
-
- move_caret_pending_ = true;
- return Send(message);
-}
-
-bool ImmediateInputRouter::Send(IPC::Message* message) {
- return process_->Send(message);
-}
-
-void ImmediateInputRouter::SendWebInputEvent(
- const WebInputEvent& input_event,
- const ui::LatencyInfo& latency_info,
- bool is_keyboard_shortcut) {
- input_event_start_time_ = TimeTicks::Now();
- Send(new InputMsg_HandleInputEvent(
- routing_id(), &input_event, latency_info, is_keyboard_shortcut));
- client_->IncrementInFlightEventCount();
-}
-
-void ImmediateInputRouter::FilterAndSendWebInputEvent(
- const WebInputEvent& input_event,
- const ui::LatencyInfo& latency_info,
- bool is_keyboard_shortcut) {
- TRACE_EVENT0("input", "ImmediateInputRouter::FilterAndSendWebInputEvent");
-
- if (!process_->HasConnection())
- return;
-
- DCHECK(!process_->IgnoreInputEvents());
-
- // Perform optional, synchronous event handling, sending ACK messages for
- // processed events, or proceeding as usual.
- InputEventAckState filter_ack = client_->FilterInputEvent(input_event,
- latency_info);
- switch (filter_ack) {
- // Send the ACK and early exit.
- case INPUT_EVENT_ACK_STATE_CONSUMED:
- case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS:
- next_mouse_move_.reset();
- ProcessInputEventAck(input_event.type, filter_ack);
- // WARNING: |this| may be deleted at this point.
- return;
-
- case INPUT_EVENT_ACK_STATE_UNKNOWN: {
- if (input_event.type == WebKit::WebInputEvent::MouseMove) {
- // Since this mouse-move event has been consumed, there will be no ACKs.
- // So reset the state here so that future mouse-move events do reach the
- // renderer.
- mouse_move_pending_ = false;
- } else if (input_event.type == WebKit::WebInputEvent::MouseWheel) {
- // Reset the wheel-event state when appropriate.
- mouse_wheel_pending_ = false;
- } else if (WebInputEvent::isGestureEventType(input_event.type) &&
- gesture_event_filter_->HasQueuedGestureEvents()) {
- // If the gesture-event filter has queued gesture events, that implies
- // it's awaiting an ack for the event. Since the event is being dropped,
- // it is never sent to the renderer, and so it won't receive any ACKs.
- // So send the ACK to the gesture event filter immediately, and mark it
- // as having been processed.
- gesture_event_filter_->ProcessGestureAck(true, input_event.type);
- } else if (WebInputEvent::isTouchEventType(input_event.type)) {
- // During an overscroll gesture initiated by touch-scrolling, the
- // touch-events do not reset or contribute to the overscroll gesture.
- // However, the touch-events are not sent to the renderer. So send an
- // ACK to the touch-event queue immediately. Mark the event as not
- // processed, to make sure that the touch-scroll gesture that initiated
- // the overscroll is updated properly.
- touch_event_queue_->ProcessTouchAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- }
- return;
- }
-
- // Proceed as normal.
- case INPUT_EVENT_ACK_STATE_NOT_CONSUMED:
- break;
- };
-
- // Transmit any pending wheel events on a non-wheel event. This ensures that
- // the renderer receives the final PhaseEnded wheel event, which is necessary
- // to terminate rubber-banding, for example.
- if (input_event.type != WebInputEvent::MouseWheel) {
- for (size_t i = 0; i < coalesced_mouse_wheel_events_.size(); ++i) {
- SendWebInputEvent(coalesced_mouse_wheel_events_[i].event,
- coalesced_mouse_wheel_events_[i].latency,
- false);
- }
- coalesced_mouse_wheel_events_.clear();
- }
-
- SendWebInputEvent(input_event, latency_info, is_keyboard_shortcut);
-
- // Any input event cancels a pending mouse move event.
- next_mouse_move_.reset();
-}
-
-void ImmediateInputRouter::OnInputEventAck(WebInputEvent::Type event_type,
- InputEventAckState ack_result) {
- // Log the time delta for processing an input event.
- TimeDelta delta = TimeTicks::Now() - input_event_start_time_;
- UMA_HISTOGRAM_TIMES("MPArch.IIR_InputEventDelta", delta);
-
- client_->DecrementInFlightEventCount();
-
- ProcessInputEventAck(event_type, ack_result);
-}
-
-void ImmediateInputRouter::OnMsgMoveCaretAck() {
- move_caret_pending_ = false;
- if (next_move_caret_)
- SendMoveCaret(next_move_caret_.release());
-}
-
-void ImmediateInputRouter::OnSelectRangeAck() {
- select_range_pending_ = false;
- if (next_selection_range_)
- SendSelectRange(next_selection_range_.release());
-}
-
-void ImmediateInputRouter::OnHasTouchEventHandlers(bool has_handlers) {
- if (has_touch_handler_ == has_handlers)
- return;
- has_touch_handler_ = has_handlers;
- if (!has_handlers)
- touch_event_queue_->FlushQueue();
- client_->OnHasTouchEventHandlers(has_handlers);
-}
-
-void ImmediateInputRouter::ProcessInputEventAck(WebInputEvent::Type event_type,
- InputEventAckState ack_result) {
- TRACE_EVENT1("input", "ImmediateInputRouter::ProcessInputEventAck",
- "ack", GetEventAckName(ack_result));
-
- int type = static_cast<int>(event_type);
- if (type < WebInputEvent::Undefined) {
- client_->OnUnexpectedEventAck(true);
- } else if (type == WebInputEvent::MouseMove) {
- mouse_move_pending_ = false;
-
- // now, we can send the next mouse move event
- if (next_mouse_move_) {
- DCHECK(next_mouse_move_->event.type == WebInputEvent::MouseMove);
- scoped_ptr<MouseEventWithLatencyInfo> next_mouse_move
- = next_mouse_move_.Pass();
- SendMouseEvent(*next_mouse_move);
- }
- } else if (WebInputEvent::isKeyboardEventType(type)) {
- ProcessKeyboardAck(type, ack_result);
- } else if (type == WebInputEvent::MouseWheel) {
- ProcessWheelAck(ack_result);
- } else if (WebInputEvent::isTouchEventType(type)) {
- ProcessTouchAck(ack_result);
- } else if (WebInputEvent::isGestureEventType(type)) {
- ProcessGestureAck(type, ack_result);
- }
-
- // WARNING: |this| may be deleted at this point.
-
- // This is used only for testing, and the other end does not use the
- // source object. On linux, specifying
- // Source<RenderWidgetHost> results in a very strange
- // runtime error in the epilogue of the enclosing
- // (ProcessInputEventAck) method, but not on other platforms; using
- // 'void' instead is just as safe (since NotificationSource
- // is not actually typesafe) and avoids this error.
- NotificationService::current()->Notify(
- NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_INPUT_EVENT_ACK,
- Source<void>(this),
- Details<int>(&type));
-}
-
-void ImmediateInputRouter::ProcessKeyboardAck(
- int type,
- InputEventAckState ack_result) {
- if (key_queue_.empty()) {
- LOG(ERROR) << "Got a KeyEvent back from the renderer but we "
- << "don't seem to have sent it to the renderer!";
- } else if (key_queue_.front().type != type) {
- LOG(ERROR) << "We seem to have a different key type sent from "
- << "the renderer. (" << key_queue_.front().type << " vs. "
- << type << "). Ignoring event.";
-
- // Something must be wrong. Clear the |key_queue_| and char event
- // suppression so that we can resume from the error.
- key_queue_.clear();
- client_->OnUnexpectedEventAck(false);
- } else {
- NativeWebKeyboardEvent front_item = key_queue_.front();
- key_queue_.pop_front();
-
- client_->OnKeyboardEventAck(front_item, ack_result);
-
- // WARNING: This ImmediateInputRouter can be deallocated at this point
- // (i.e. in the case of Ctrl+W, where the call to
- // HandleKeyboardEvent destroys this ImmediateInputRouter).
- }
-}
-
-void ImmediateInputRouter::ProcessWheelAck(InputEventAckState ack_result) {
- mouse_wheel_pending_ = false;
-
- // Process the unhandled wheel event here before calling
- // ForwardWheelEventWithLatencyInfo() since it will mutate
- // current_wheel_event_.
- client_->OnWheelEventAck(current_wheel_event_.event, ack_result);
-
- // Now send the next (coalesced) mouse wheel event.
- if (!coalesced_mouse_wheel_events_.empty()) {
- MouseWheelEventWithLatencyInfo next_wheel_event =
- coalesced_mouse_wheel_events_.front();
- coalesced_mouse_wheel_events_.pop_front();
- SendWheelEvent(next_wheel_event);
- }
-}
-
-void ImmediateInputRouter::ProcessGestureAck(int type,
- InputEventAckState ack_result) {
- const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result);
- client_->OnGestureEventAck(
- gesture_event_filter_->GetGestureEventAwaitingAck(), ack_result);
- gesture_event_filter_->ProcessGestureAck(processed, type);
-}
-
-void ImmediateInputRouter::ProcessTouchAck(InputEventAckState ack_result) {
- // |touch_event_queue_| will forward to OnTouchEventAck when appropriate.
- touch_event_queue_->ProcessTouchAck(ack_result);
-}
-
-} // namespace content
diff --git a/content/browser/renderer_host/input/immediate_input_router.h b/content/browser/renderer_host/input/immediate_input_router.h
deleted file mode 100644
index ca3fd24..0000000
--- a/content/browser/renderer_host/input/immediate_input_router.h
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_IMMEDIATE_INPUT_ROUTER_H_
-#define CONTENT_BROWSER_RENDERER_HOST_INPUT_IMMEDIATE_INPUT_ROUTER_H_
-
-#include <queue>
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/time/time.h"
-#include "content/browser/renderer_host/input/input_router.h"
-#include "content/browser/renderer_host/touch_event_queue.h"
-#include "content/public/browser/native_web_keyboard_event.h"
-
-namespace ui {
-struct LatencyInfo;
-}
-
-namespace content {
-
-class GestureEventFilter;
-class InputRouterClient;
-class RenderProcessHost;
-class RenderWidgetHostImpl;
-
-// A default implementation for browser input event routing. Input commands are
-// forwarded to the renderer immediately upon receipt.
-class ImmediateInputRouter : public InputRouter,
- public TouchEventQueueClient {
- public:
- ImmediateInputRouter(RenderProcessHost* process,
- InputRouterClient* client,
- int routing_id);
- virtual ~ImmediateInputRouter();
-
- // InputRouter
- virtual bool SendInput(IPC::Message* message) OVERRIDE;
- virtual void SendMouseEvent(
- const MouseEventWithLatencyInfo& mouse_event) OVERRIDE;
- virtual void SendWheelEvent(
- const MouseWheelEventWithLatencyInfo& wheel_event) OVERRIDE;
- virtual void SendKeyboardEvent(
- const NativeWebKeyboardEvent& key_event,
- const ui::LatencyInfo& latency_info) OVERRIDE;
- virtual void SendGestureEvent(
- const GestureEventWithLatencyInfo& gesture_event) OVERRIDE;
- virtual void SendTouchEvent(
- const TouchEventWithLatencyInfo& touch_event) OVERRIDE;
- virtual void SendMouseEventImmediately(
- const MouseEventWithLatencyInfo& mouse_event) OVERRIDE;
- virtual void SendTouchEventImmediately(
- const TouchEventWithLatencyInfo& touch_event) OVERRIDE;
- virtual void SendGestureEventImmediately(
- const GestureEventWithLatencyInfo& gesture_event) OVERRIDE;
- virtual const NativeWebKeyboardEvent* GetLastKeyboardEvent() const OVERRIDE;
- virtual bool ShouldForwardTouchEvent() const OVERRIDE;
- virtual bool ShouldForwardGestureEvent(
- const GestureEventWithLatencyInfo& gesture_event) const OVERRIDE;
- virtual bool HasQueuedGestureEvents() const OVERRIDE;
-
- // IPC::Listener
- virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
-
- GestureEventFilter* gesture_event_filter() {
- return gesture_event_filter_.get();
- }
-
- TouchEventQueue* touch_event_queue() {
- return touch_event_queue_.get();
- }
-
-private:
- // TouchEventQueueClient
- virtual void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
- InputEventAckState ack_result) OVERRIDE;
-
- bool SendMoveCaret(IPC::Message* message);
- bool SendSelectRange(IPC::Message* message);
- bool Send(IPC::Message* message);
-
- // Transmits the given input event an as an IPC::Message. This is an internal
- // helper for |FilterAndSendInputEvent()| and should not be used otherwise.
- void SendWebInputEvent(const WebKit::WebInputEvent& input_event,
- const ui::LatencyInfo& latency_info,
- bool is_keyboard_shortcut);
-
- // Filters and forwards the given WebInputEvent to |SendWebInputEvent()|. This
- // is an internal helper for |Send*Event()| and should not be used otherwise.
- void FilterAndSendWebInputEvent(const WebKit::WebInputEvent& input_event,
- const ui::LatencyInfo& latency_info,
- bool is_keyboard_shortcut);
-
- // IPC message handlers
- void OnInputEventAck(WebKit::WebInputEvent::Type event_type,
- InputEventAckState ack_result);
- void OnMsgMoveCaretAck();
- void OnSelectRangeAck();
- void OnHasTouchEventHandlers(bool has_handlers);
-
- // Handle the event ack. Triggered via |OnInputEventAck()| if the event was
- // processed in the renderer, or synchonously from |FilterAndSendInputevent()|
- // if the event was filtered by the |client_| prior to sending.
- void ProcessInputEventAck(WebKit::WebInputEvent::Type event_type,
- InputEventAckState ack_result);
-
- // Called by ProcessInputEventAck() to process a keyboard event ack message.
- void ProcessKeyboardAck(int type, InputEventAckState ack_result);
-
- // Called by ProcessInputEventAck() to process a wheel event ack message.
- // This could result in a task being posted to allow additional wheel
- // input messages to be coalesced.
- void ProcessWheelAck(InputEventAckState ack_result);
-
- // Called by ProcessInputEventAck() to process a gesture event ack message.
- // This validates the gesture for suppression of touchpad taps and sends one
- // previously queued coalesced gesture if it exists.
- void ProcessGestureAck(int type, InputEventAckState ack_result);
-
- // Called on ProcessInputEventAck() to process a touch event ack message.
- // This can result in a gesture event being generated and sent back to the
- // renderer.
- void ProcessTouchAck(InputEventAckState ack_result);
-
- int routing_id() const { return routing_id_; }
-
-
- RenderProcessHost* process_;
- InputRouterClient* client_;
- int routing_id_;
-
- // (Similar to |mouse_move_pending_|.) True while waiting for SelectRange_ACK.
- bool select_range_pending_;
-
- // (Similar to |next_mouse_move_|.) The next SelectRange to send, if any.
- scoped_ptr<IPC::Message> next_selection_range_;
-
- // (Similar to |mouse_move_pending_|.) True while waiting for MoveCaret_ACK.
- bool move_caret_pending_;
-
- // (Similar to |next_mouse_move_|.) The next MoveCaret to send, if any.
- scoped_ptr<IPC::Message> next_move_caret_;
-
- // True if a mouse move event was sent to the render view and we are waiting
- // for a corresponding InputHostMsg_HandleInputEvent_ACK message.
- bool mouse_move_pending_;
-
- // The next mouse move event to send (only non-null while mouse_move_pending_
- // is true).
- scoped_ptr<MouseEventWithLatencyInfo> next_mouse_move_;
-
- // (Similar to |mouse_move_pending_|.) True if a mouse wheel event was sent
- // and we are waiting for a corresponding ack.
- bool mouse_wheel_pending_;
- MouseWheelEventWithLatencyInfo current_wheel_event_;
-
- typedef std::deque<MouseWheelEventWithLatencyInfo> WheelEventQueue;
-
- // (Similar to |next_mouse_move_|.) The next mouse wheel events to send.
- // Unlike mouse moves, mouse wheel events received while one is pending are
- // coalesced (by accumulating deltas) if they match the previous event in
- // modifiers. On the Mac, in particular, mouse wheel events are received at a
- // high rate; not waiting for the ack results in jankiness, and using the same
- // mechanism as for mouse moves (just dropping old events when multiple ones
- // would be queued) results in very slow scrolling.
- WheelEventQueue coalesced_mouse_wheel_events_;
-
- // The time when an input event was sent to the RenderWidget.
- base::TimeTicks input_event_start_time_;
-
- // Queue of keyboard events that we need to track.
- typedef std::deque<NativeWebKeyboardEvent> KeyQueue;
-
- // A queue of keyboard events. We can't trust data from the renderer so we
- // stuff key events into a queue and pop them out on ACK, feeding our copy
- // back to whatever unhandled handler instead of the returned version.
- KeyQueue key_queue_;
-
- // Keeps track of whether the webpage has any touch event handler. If it does,
- // then touch events are sent to the renderer. Otherwise, the touch events are
- // not sent to the renderer.
- bool has_touch_handler_;
-
- scoped_ptr<TouchEventQueue> touch_event_queue_;
- scoped_ptr<GestureEventFilter> gesture_event_filter_;
-
- DISALLOW_COPY_AND_ASSIGN(ImmediateInputRouter);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_IMMEDIATE_INPUT_ROUTER_H_
diff --git a/content/browser/renderer_host/input/input_router.h b/content/browser/renderer_host/input/input_router.h
deleted file mode 100644
index 2d8a4c6..0000000
--- a/content/browser/renderer_host/input/input_router.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_H_
-#define CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_H_
-
-#include "base/basictypes.h"
-#include "content/port/browser/event_with_latency_info.h"
-#include "content/port/common/input_event_ack_state.h"
-#include "content/public/browser/native_web_keyboard_event.h"
-#include "ipc/ipc_listener.h"
-#include "third_party/WebKit/public/web/WebInputEvent.h"
-
-namespace content {
-
-class InputRouterClient;
-
-// The InputRouter allows the embedder to customize how input events are
-// sent to the renderer, and how responses are dispatched to the browser.
-// While the router should respect the relative order in which events are
-// received, it is free to customize when those events are dispatched.
-class InputRouter : public IPC::Listener {
- public:
- virtual ~InputRouter() {}
-
- // Send and take ownership of the the given InputMsg_*. This should be used
- // only for event types not associated with a WebInputEvent. Returns true on
- // success and false otherwise.
- virtual bool SendInput(IPC::Message* message) = 0;
-
- // WebInputEvents
- virtual void SendMouseEvent(
- const MouseEventWithLatencyInfo& mouse_event) = 0;
- virtual void SendWheelEvent(
- const MouseWheelEventWithLatencyInfo& wheel_event) = 0;
- virtual void SendKeyboardEvent(
- const NativeWebKeyboardEvent& key_event,
- const ui::LatencyInfo& latency_info) = 0;
- virtual void SendGestureEvent(
- const GestureEventWithLatencyInfo& gesture_event) = 0;
- virtual void SendTouchEvent(
- const TouchEventWithLatencyInfo& touch_event) = 0;
- virtual void SendMouseEventImmediately(
- const MouseEventWithLatencyInfo& mouse_event) = 0;
- virtual void SendTouchEventImmediately(
- const TouchEventWithLatencyInfo& touch_event) = 0;
- virtual void SendGestureEventImmediately(
- const GestureEventWithLatencyInfo& gesture_event) = 0;
-
- // Returns the oldest queued or in-flight keyboard event sent to the router.
- virtual const NativeWebKeyboardEvent* GetLastKeyboardEvent() const = 0;
-
- // Returns |true| if the caller should immediately forward touch events to the
- // router. When |false|, the caller can forego sending touch events, and
- // instead consume them directly.
- virtual bool ShouldForwardTouchEvent() const = 0;
-
- // Returns |true| if the caller should immediately forward the provided
- // |gesture_event| to the router.
- virtual bool ShouldForwardGestureEvent(
- const GestureEventWithLatencyInfo& gesture_event) const = 0;
-
- // Returns |true| if the router has any queued or in-flight gesture events.
- virtual bool HasQueuedGestureEvents() const = 0;
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_H_
diff --git a/content/browser/renderer_host/input/input_router_client.h b/content/browser/renderer_host/input/input_router_client.h
deleted file mode 100644
index 9c85422..0000000
--- a/content/browser/renderer_host/input/input_router_client.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_CLIENT_H_
-#define CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_CLIENT_H_
-
-#include "content/common/content_export.h"
-#include "content/port/browser/event_with_latency_info.h"
-#include "content/port/common/input_event_ack_state.h"
-#include "content/public/browser/native_web_keyboard_event.h"
-#include "third_party/WebKit/public/web/WebInputEvent.h"
-
-namespace ui {
-struct LatencyInfo;
-}
-
-namespace content {
-
-class CONTENT_EXPORT InputRouterClient {
- public:
- virtual ~InputRouterClient() {}
-
- // Called just prior to events being sent to the renderer, giving the client
- // a chance to perform in-process event filtering.
- // The returned disposition will yield the following behavior:
- // * |NOT_CONSUMED| will result in |input_event| being sent as usual.
- // * |CONSUMED| or |NO_CONSUMER_EXISTS| will trigger the appropriate ack.
- // * |UNKNOWN| will result in |input_event| being dropped.
- virtual InputEventAckState FilterInputEvent(
- const WebKit::WebInputEvent& input_event,
- const ui::LatencyInfo& latency_info) = 0;
-
- // Called each time a WebInputEvent IPC is sent.
- virtual void IncrementInFlightEventCount() = 0;
-
- // Called each time a WebInputEvent ACK IPC is received.
- virtual void DecrementInFlightEventCount() = 0;
-
- // Called when the renderer notifies that it has touch event handlers.
- virtual void OnHasTouchEventHandlers(bool has_handlers) = 0;
-
- // Called upon Send*Event. Should return true if the event should be sent, and
- // false if the event should be dropped.
- virtual bool OnSendKeyboardEvent(
- const NativeWebKeyboardEvent& key_event,
- const ui::LatencyInfo& latency_info,
- bool* is_shortcut) = 0;
- virtual bool OnSendWheelEvent(
- const MouseWheelEventWithLatencyInfo& wheel_event) = 0;
- virtual bool OnSendMouseEvent(
- const MouseEventWithLatencyInfo& mouse_event) = 0;
- virtual bool OnSendTouchEvent(
- const TouchEventWithLatencyInfo& touch_event) = 0;
- virtual bool OnSendGestureEvent(
- const GestureEventWithLatencyInfo& gesture_event) = 0;
- virtual bool OnSendMouseEventImmediately(
- const MouseEventWithLatencyInfo& mouse_event) = 0;
- virtual bool OnSendTouchEventImmediately(
- const TouchEventWithLatencyInfo& touch_event) = 0;
- virtual bool OnSendGestureEventImmediately(
- const GestureEventWithLatencyInfo& gesture_event) = 0;
-
- // Called upon event ack receipt from the renderer.
- virtual void OnKeyboardEventAck(const NativeWebKeyboardEvent& event,
- InputEventAckState ack_result) = 0;
- virtual void OnWheelEventAck(const WebKit::WebMouseWheelEvent& event,
- InputEventAckState ack_result) = 0;
- virtual void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
- InputEventAckState ack_result) = 0;
- virtual void OnGestureEventAck(const WebKit::WebGestureEvent& event,
- InputEventAckState ack_result) = 0;
- virtual void OnUnexpectedEventAck(bool bad_message) = 0;
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_CLIENT_H_
diff --git a/content/browser/renderer_host/overscroll_controller.cc b/content/browser/renderer_host/overscroll_controller.cc
index 7e9ba4b..2babec8 100644
--- a/content/browser/renderer_host/overscroll_controller.cc
+++ b/content/browser/renderer_host/overscroll_controller.cc
@@ -4,6 +4,7 @@
#include "content/browser/renderer_host/overscroll_controller.h"
+#include "content/browser/renderer_host/gesture_event_filter.h"
#include "content/browser/renderer_host/overscroll_controller_delegate.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/public/browser/overscroll_configuration.h"
@@ -62,12 +63,12 @@ bool OverscrollController::WillDispatchEvent(
// touch-scrolls maintain state in the renderer side (in the compositor, for
// example), and the event that completes this action needs to be sent to
// the renderer so that those states can be updated/reset appropriately.
- // Send the event through the host when appropriate.
- if (ShouldForwardToHost(event)) {
+ // Send the event through the gesture-event filter when appropriate.
+ if (ShouldForwardToGestureFilter(event)) {
const WebKit::WebGestureEvent& gevent =
static_cast<const WebKit::WebGestureEvent&>(event);
- return render_widget_host_->ShouldForwardGestureEvent(
- GestureEventWithLatencyInfo(gevent, latency_info));
+ return render_widget_host_->gesture_event_filter()->
+ ShouldForward(GestureEventWithLatencyInfo(gevent, latency_info));
}
return false;
@@ -77,11 +78,12 @@ bool OverscrollController::WillDispatchEvent(
SetOverscrollMode(OVERSCROLL_NONE);
// The overscroll gesture status is being reset. If the event is a
// gesture event (from either touchscreen or trackpad), then make sure the
- // host gets the event first (if it didn't already process it).
- if (ShouldForwardToHost(event)) {
+ // gesture event filter gets the event first (if it didn't already process
+ // it).
+ if (ShouldForwardToGestureFilter(event)) {
const WebKit::WebGestureEvent& gevent =
static_cast<const WebKit::WebGestureEvent&>(event);
- return render_widget_host_->ShouldForwardGestureEvent(
+ return render_widget_host_->gesture_event_filter()->ShouldForward(
GestureEventWithLatencyInfo(gevent, latency_info));
}
@@ -360,14 +362,14 @@ void OverscrollController::SetOverscrollMode(OverscrollMode mode) {
delegate_->OnOverscrollModeChange(old_mode, overscroll_mode_);
}
-bool OverscrollController::ShouldForwardToHost(
+bool OverscrollController::ShouldForwardToGestureFilter(
const WebKit::WebInputEvent& event) const {
if (!WebKit::WebInputEvent::isGestureEventType(event.type))
return false;
- // If the RenderWidgetHost already processed this event, then the event must
- // not be sent again.
- return !render_widget_host_->HasQueuedGestureEvents();
+ // If the GestureEventFilter already processed this event, then the event must
+ // not be sent to the filter again.
+ return !render_widget_host_->gesture_event_filter()->HasQueuedGestureEvents();
}
} // namespace content
diff --git a/content/browser/renderer_host/overscroll_controller.h b/content/browser/renderer_host/overscroll_controller.h
index c9e477b..2259f3f 100644
--- a/content/browser/renderer_host/overscroll_controller.h
+++ b/content/browser/renderer_host/overscroll_controller.h
@@ -103,8 +103,8 @@ class OverscrollController {
void SetOverscrollMode(OverscrollMode new_mode);
// Returns whether the input event should be forwarded to the
- // RenderWidgetHost.
- bool ShouldForwardToHost(const WebKit::WebInputEvent& event) const;
+ // GestureEventFilter.
+ bool ShouldForwardToGestureFilter(const WebKit::WebInputEvent& event) const;
// The RenderWidgetHost that owns this overscroll controller.
RenderWidgetHostImpl* render_widget_host_;
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 0eb19cb..c1696a7 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -28,12 +28,14 @@
#include "content/browser/renderer_host/backing_store.h"
#include "content/browser/renderer_host/backing_store_manager.h"
#include "content/browser/renderer_host/dip_util.h"
-#include "content/browser/renderer_host/input/immediate_input_router.h"
+#include "content/browser/renderer_host/gesture_event_filter.h"
#include "content/browser/renderer_host/overscroll_controller.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_helper.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
+#include "content/browser/renderer_host/touch_event_queue.h"
+#include "content/browser/renderer_host/touchpad_tap_suppression_controller.h"
#include "content/common/accessibility_messages.h"
#include "content/common/content_constants_internal.h"
#include "content/common/gpu/gpu_messages.h"
@@ -88,6 +90,27 @@ bool g_check_for_pending_resize_ack = true;
// This timeout impacts the "choppiness" of our window resize perf.
const int kPaintMsgTimeoutMS = 50;
+// Returns |true| if the two wheel events should be coalesced.
+bool ShouldCoalesceMouseWheelEvents(const WebMouseWheelEvent& last_event,
+ const WebMouseWheelEvent& new_event) {
+ return last_event.modifiers == new_event.modifiers &&
+ last_event.scrollByPage == new_event.scrollByPage &&
+ last_event.hasPreciseScrollingDeltas
+ == new_event.hasPreciseScrollingDeltas &&
+ last_event.phase == new_event.phase &&
+ last_event.momentumPhase == new_event.momentumPhase;
+}
+
+float GetUnacceleratedDelta(float accelerated_delta, float acceleration_ratio) {
+ return accelerated_delta * acceleration_ratio;
+}
+
+float GetAccelerationRatio(float accelerated_delta, float unaccelerated_delta) {
+ if (unaccelerated_delta == 0.f || accelerated_delta == 0.f)
+ return 1.f;
+ return unaccelerated_delta / accelerated_delta;
+}
+
base::LazyInstance<std::vector<RenderWidgetHost::CreatedCallback> >
g_created_callbacks = LAZY_INSTANCE_INITIALIZER;
@@ -133,7 +156,11 @@ RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
overdraw_bottom_height_(0.f),
should_auto_resize_(false),
waiting_for_screen_rects_ack_(false),
+ mouse_move_pending_(false),
+ mouse_wheel_pending_(false),
accessibility_mode_(AccessibilityModeOff),
+ select_range_pending_(false),
+ move_caret_pending_(false),
needs_repainting_on_restore_(false),
is_unresponsive_(false),
in_flight_event_count_(0),
@@ -150,6 +177,8 @@ RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
allow_privileged_mouse_lock_(false),
has_touch_handler_(false),
weak_factory_(this),
+ touch_event_queue_(new TouchEventQueue(this)),
+ gesture_event_filter_(new GestureEventFilter(this)),
last_input_number_(0) {
CHECK(delegate_);
if (routing_id_ == MSG_ROUTING_NONE) {
@@ -186,8 +215,6 @@ RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
for (size_t i = 0; i < g_created_callbacks.Get().size(); i++)
g_created_callbacks.Get().at(i).Run(this);
- input_router_.reset(new ImmediateInputRouter(process, this, routing_id_));
-
#if defined(USE_AURA)
bool overscroll_enabled = CommandLine::ForCurrentProcess()->
GetSwitchValueASCII(switches::kOverscrollHistoryNavigation) != "0";
@@ -430,9 +457,14 @@ bool RenderWidgetHostImpl::OnMessageReceived(const IPC::Message &msg) {
IPC_MESSAGE_HANDLER(ViewHostMsg_DidOverscroll, OnOverscrolled)
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateRect, OnUpdateRect)
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateIsDelayed, OnUpdateIsDelayed)
+ IPC_MESSAGE_HANDLER(InputHostMsg_HandleInputEvent_ACK, OnInputEventAck)
IPC_MESSAGE_HANDLER(ViewHostMsg_BeginSmoothScroll, OnBeginSmoothScroll)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_SelectRange_ACK, OnSelectRangeAck)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_MoveCaret_ACK, OnMsgMoveCaretAck)
IPC_MESSAGE_HANDLER(ViewHostMsg_Focus, OnFocus)
IPC_MESSAGE_HANDLER(ViewHostMsg_Blur, OnBlur)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_HasTouchEventHandlers,
+ OnHasTouchEventHandlers)
IPC_MESSAGE_HANDLER(ViewHostMsg_SetCursor, OnSetCursor)
IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputTypeChanged,
OnTextInputTypeChanged)
@@ -458,9 +490,6 @@ bool RenderWidgetHostImpl::OnMessageReceived(const IPC::Message &msg) {
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP_EX()
- if (!handled && input_router_ && input_router_->OnMessageReceived(msg))
- return true;
-
if (!handled && view_ && view_->OnMessageReceived(msg))
return true;
@@ -473,9 +502,6 @@ bool RenderWidgetHostImpl::OnMessageReceived(const IPC::Message &msg) {
}
bool RenderWidgetHostImpl::Send(IPC::Message* msg) {
- if (IPC_MESSAGE_ID_CLASS(msg->type()) == InputMsgStart)
- return input_router_->SendInput(msg);
-
return process_->Send(msg);
}
@@ -1003,9 +1029,28 @@ void RenderWidgetHostImpl::ForwardMouseEvent(const WebMouseEvent& mouse_event) {
void RenderWidgetHostImpl::ForwardMouseEventWithLatencyInfo(
const MouseEventWithLatencyInfo& mouse_event) {
- TRACE_EVENT2("input", "RenderWidgetHostImpl::ForwardMouseEvent",
+ TRACE_EVENT2("input",
+ "RenderWidgetHostImpl::ForwardMouseEventWithLatencyInfo",
"x", mouse_event.event.x, "y", mouse_event.event.y);
- input_router_->SendMouseEvent(mouse_event);
+ if (ignore_input_events_ || process_->IgnoreInputEvents())
+ return;
+
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kSimulateTouchScreenWithMouse)) {
+ SimulateTouchGestureWithMouse(mouse_event.event);
+ return;
+ }
+
+ if (mouse_event.event.type == WebInputEvent::MouseDown &&
+ gesture_event_filter_->GetTouchpadTapSuppressionController()->
+ ShouldDeferMouseDown(mouse_event))
+ return;
+ if (mouse_event.event.type == WebInputEvent::MouseUp &&
+ gesture_event_filter_->GetTouchpadTapSuppressionController()->
+ ShouldSuppressMouseUp())
+ return;
+
+ ForwardMouseEventImmediately(mouse_event);
}
void RenderWidgetHostImpl::OnPointerEventActivate() {
@@ -1013,15 +1058,67 @@ void RenderWidgetHostImpl::OnPointerEventActivate() {
void RenderWidgetHostImpl::ForwardWheelEvent(
const WebMouseWheelEvent& wheel_event) {
- ForwardWheelEventWithLatencyInfo(
- MouseWheelEventWithLatencyInfo(wheel_event,
- CreateRWHLatencyInfoIfNotExist(NULL)));
+ ForwardWheelEventWithLatencyInfo(wheel_event,
+ CreateRWHLatencyInfoIfNotExist(NULL));
}
void RenderWidgetHostImpl::ForwardWheelEventWithLatencyInfo(
- const MouseWheelEventWithLatencyInfo& wheel_event) {
- TRACE_EVENT0("input", "RenderWidgetHostImpl::ForwardWheelEvent");
- input_router_->SendWheelEvent(wheel_event);
+ const WebMouseWheelEvent& wheel_event,
+ const ui::LatencyInfo& latency_info) {
+ TRACE_EVENT0("input",
+ "RenderWidgetHostImpl::ForwardWheelEventWithLatencyInfo");
+ if (ignore_input_events_ || process_->IgnoreInputEvents())
+ return;
+
+ if (delegate_->PreHandleWheelEvent(wheel_event))
+ return;
+
+ // If there's already a mouse wheel event waiting to be sent to the renderer,
+ // add the new deltas to that event. Not doing so (e.g., by 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).
+ if (mouse_wheel_pending_) {
+ if (coalesced_mouse_wheel_events_.empty() ||
+ !ShouldCoalesceMouseWheelEvents(
+ coalesced_mouse_wheel_events_.back().event, wheel_event)) {
+ coalesced_mouse_wheel_events_.push_back(
+ MouseWheelEventWithLatencyInfo(wheel_event, latency_info));
+ } else {
+ MouseWheelEventWithLatencyInfo* last_wheel_event =
+ &coalesced_mouse_wheel_events_.back();
+ float unaccelerated_x =
+ GetUnacceleratedDelta(last_wheel_event->event.deltaX,
+ last_wheel_event->event.accelerationRatioX) +
+ GetUnacceleratedDelta(wheel_event.deltaX,
+ wheel_event.accelerationRatioX);
+ float unaccelerated_y =
+ GetUnacceleratedDelta(last_wheel_event->event.deltaY,
+ last_wheel_event->event.accelerationRatioY) +
+ GetUnacceleratedDelta(wheel_event.deltaY,
+ wheel_event.accelerationRatioY);
+ last_wheel_event->event.deltaX += wheel_event.deltaX;
+ last_wheel_event->event.deltaY += wheel_event.deltaY;
+ last_wheel_event->event.wheelTicksX += wheel_event.wheelTicksX;
+ last_wheel_event->event.wheelTicksY += wheel_event.wheelTicksY;
+ last_wheel_event->event.accelerationRatioX =
+ GetAccelerationRatio(last_wheel_event->event.deltaX, unaccelerated_x);
+ last_wheel_event->event.accelerationRatioY =
+ GetAccelerationRatio(last_wheel_event->event.deltaY, unaccelerated_y);
+ DCHECK_GE(wheel_event.timeStampSeconds,
+ last_wheel_event->event.timeStampSeconds);
+ last_wheel_event->event.timeStampSeconds = wheel_event.timeStampSeconds;
+ last_wheel_event->latency.MergeWith(latency_info);
+ }
+ return;
+ }
+ mouse_wheel_pending_ = true;
+ current_wheel_event_ = wheel_event;
+
+ HISTOGRAM_COUNTS_100("MPArch.RWH_WheelQueueSize",
+ coalesced_mouse_wheel_events_.size());
+
+ ForwardInputEvent(wheel_event, sizeof(WebMouseWheelEvent), latency_info,
+ false);
}
void RenderWidgetHostImpl::ForwardGestureEvent(
@@ -1033,8 +1130,7 @@ void RenderWidgetHostImpl::ForwardGestureEventWithLatencyInfo(
const WebKit::WebGestureEvent& gesture_event,
const ui::LatencyInfo& ui_latency) {
TRACE_EVENT0("input", "RenderWidgetHostImpl::ForwardGestureEvent");
- // Early out if necessary, prior to performing latency logic.
- if (IgnoreInputEvents())
+ if (ignore_input_events_ || process_->IgnoreInputEvents())
return;
ui::LatencyInfo latency_info = CreateRWHLatencyInfoIfNotExist(&ui_latency);
@@ -1061,24 +1157,152 @@ void RenderWidgetHostImpl::ForwardGestureEventWithLatencyInfo(
}
}
- GestureEventWithLatencyInfo gesture_with_latency(gesture_event, latency_info);
- input_router_->SendGestureEvent(gesture_with_latency);
+ if (!IsInOverscrollGesture() &&
+ !gesture_event_filter_->ShouldForward(
+ GestureEventWithLatencyInfo(gesture_event, latency_info))) {
+ if (overscroll_controller_.get())
+ overscroll_controller_->DiscardingGestureEvent(gesture_event);
+ return;
+ }
+
+ ForwardInputEvent(gesture_event, sizeof(WebGestureEvent),
+ latency_info, false);
}
-void RenderWidgetHostImpl::ForwardTouchEventWithLatencyInfo(
- const WebKit::WebTouchEvent& touch_event,
- const ui::LatencyInfo& ui_latency) {
+// Forwards MouseEvent without passing it through
+// TouchpadTapSuppressionController.
+void RenderWidgetHostImpl::ForwardMouseEventImmediately(
+ const MouseEventWithLatencyInfo& mouse_event) {
+ TRACE_EVENT2("input",
+ "RenderWidgetHostImpl::ForwardMouseEventImmediately",
+ "x", mouse_event.event.x, "y", mouse_event.event.y);
+ if (ignore_input_events_ || process_->IgnoreInputEvents())
+ return;
+
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kSimulateTouchScreenWithMouse)) {
+ SimulateTouchGestureWithMouse(mouse_event.event);
+ return;
+ }
+
+ // Avoid spamming the renderer with mouse move events. It is important
+ // to note that WM_MOUSEMOVE events are anyways synthetic, but since our
+ // thread is able to rapidly consume WM_MOUSEMOVE events, we may get way
+ // more WM_MOUSEMOVE events than we wish to send to the renderer.
+ if (mouse_event.event.type == WebInputEvent::MouseMove) {
+ if (mouse_move_pending_) {
+ if (!next_mouse_move_) {
+ next_mouse_move_.reset(new MouseEventWithLatencyInfo(mouse_event));
+ } else {
+ // Accumulate movement deltas.
+ int x = next_mouse_move_->event.movementX;
+ int y = next_mouse_move_->event.movementY;
+ next_mouse_move_->event = mouse_event.event;
+ next_mouse_move_->event.movementX += x;
+ next_mouse_move_->event.movementY += y;
+ next_mouse_move_->latency.MergeWith(mouse_event.latency);
+ }
+ return;
+ }
+ mouse_move_pending_ = true;
+ } else if (mouse_event.event.type == WebInputEvent::MouseDown) {
+ OnUserGesture();
+ }
+
+ ForwardInputEvent(mouse_event.event, sizeof(WebMouseEvent),
+ mouse_event.latency, false);
+}
+
+void RenderWidgetHostImpl::ForwardTouchEventImmediately(
+ const TouchEventWithLatencyInfo& touch_event) {
TRACE_EVENT0("input", "RenderWidgetHostImpl::ForwardTouchEvent");
- ui::LatencyInfo latency_info = CreateRWHLatencyInfoIfNotExist(&ui_latency);
- TouchEventWithLatencyInfo touch_with_latency(touch_event, latency_info);
- input_router_->SendTouchEvent(touch_with_latency);
+ if (ignore_input_events_ || process_->IgnoreInputEvents())
+ return;
+
+ ForwardInputEvent(touch_event.event, sizeof(WebKit::WebTouchEvent),
+ touch_event.latency, false);
+}
+
+void RenderWidgetHostImpl::ForwardGestureEventImmediately(
+ const GestureEventWithLatencyInfo& gesture_event) {
+ if (ignore_input_events_ || process_->IgnoreInputEvents())
+ return;
+ ForwardInputEvent(gesture_event.event, sizeof(WebGestureEvent),
+ gesture_event.latency, false);
}
void RenderWidgetHostImpl::ForwardKeyboardEvent(
const NativeWebKeyboardEvent& key_event) {
TRACE_EVENT0("input", "RenderWidgetHostImpl::ForwardKeyboardEvent");
- input_router_->SendKeyboardEvent(key_event,
- CreateRWHLatencyInfoIfNotExist(NULL));
+ if (ignore_input_events_ || process_->IgnoreInputEvents())
+ return;
+
+ // First, let keypress listeners take a shot at handling the event. If a
+ // listener handles the event, it should not be propagated to the renderer.
+ if (KeyPressListenersHandleEvent(key_event)) {
+ // Some keypresses that are accepted by the listener might have follow up
+ // char events, which should be ignored.
+ if (key_event.type == WebKeyboardEvent::RawKeyDown)
+ suppress_next_char_events_ = true;
+ return;
+ }
+
+ if (key_event.type == WebKeyboardEvent::Char &&
+ (key_event.windowsKeyCode == ui::VKEY_RETURN ||
+ key_event.windowsKeyCode == ui::VKEY_SPACE)) {
+ OnUserGesture();
+ }
+
+ // Double check the type to make sure caller hasn't sent us nonsense that
+ // will mess up our key queue.
+ if (WebInputEvent::isKeyboardEventType(key_event.type)) {
+ if (suppress_next_char_events_) {
+ // If preceding RawKeyDown event was handled by the browser, then we need
+ // suppress all Char events generated by it. Please note that, one
+ // RawKeyDown event may generate multiple Char events, so we can't reset
+ // |suppress_next_char_events_| until we get a KeyUp or a RawKeyDown.
+ if (key_event.type == WebKeyboardEvent::Char)
+ return;
+ // We get a KeyUp or a RawKeyDown event.
+ suppress_next_char_events_ = false;
+ }
+
+ bool is_keyboard_shortcut = false;
+ // Only pre-handle the key event if it's not handled by the input method.
+ if (delegate_ && !key_event.skip_in_browser) {
+ // We need to set |suppress_next_char_events_| to true if
+ // PreHandleKeyboardEvent() returns true, but |this| may already be
+ // destroyed at that time. So set |suppress_next_char_events_| true here,
+ // then revert it afterwards when necessary.
+ if (key_event.type == WebKeyboardEvent::RawKeyDown)
+ suppress_next_char_events_ = true;
+
+ // Tab switching/closing accelerators aren't sent to the renderer to avoid
+ // a hung/malicious renderer from interfering.
+ if (delegate_->PreHandleKeyboardEvent(key_event, &is_keyboard_shortcut))
+ return;
+
+ if (key_event.type == WebKeyboardEvent::RawKeyDown)
+ suppress_next_char_events_ = false;
+ }
+
+ // Don't add this key to the queue if we have no way to send the message...
+ if (!process_->HasConnection())
+ return;
+
+ // Put all WebKeyboardEvent objects in a queue since we can't trust the
+ // renderer and we need to give something to the HandleKeyboardEvent
+ // handler.
+ key_queue_.push_back(key_event);
+ HISTOGRAM_COUNTS_100("Renderer.KeyboardQueueSize", key_queue_.size());
+
+ gesture_event_filter_->FlingHasBeenHalted();
+
+ // Only forward the non-native portions of our event.
+ ForwardInputEvent(key_event, sizeof(WebKeyboardEvent),
+ CreateRWHLatencyInfoIfNotExist(NULL),
+ is_keyboard_shortcut);
+ }
}
void RenderWidgetHostImpl::SendCursorVisibilityState(bool is_visible) {
@@ -1111,6 +1335,111 @@ ui::LatencyInfo RenderWidgetHostImpl::CreateRWHLatencyInfoIfNotExist(
return info;
}
+void RenderWidgetHostImpl::SendInputEvent(const WebInputEvent& input_event,
+ int event_size,
+ const ui::LatencyInfo& latency_info,
+ bool is_keyboard_shortcut) {
+ DCHECK(latency_info.FindLatency(ui::INPUT_EVENT_LATENCY_RWH_COMPONENT,
+ GetLatencyComponentId(),
+ NULL));
+ input_event_start_time_ = TimeTicks::Now();
+ Send(new InputMsg_HandleInputEvent(
+ routing_id_, &input_event, latency_info, is_keyboard_shortcut));
+ increment_in_flight_event_count();
+}
+
+void RenderWidgetHostImpl::ForwardInputEvent(
+ const WebInputEvent& input_event, int event_size,
+ const ui::LatencyInfo& latency_info, bool is_keyboard_shortcut) {
+ TRACE_EVENT0("input", "RenderWidgetHostImpl::ForwardInputEvent");
+
+ if (!process_->HasConnection())
+ return;
+
+ DCHECK(!process_->IgnoreInputEvents());
+
+ if (overscroll_controller_.get() &&
+ !overscroll_controller_->WillDispatchEvent(input_event, latency_info)) {
+ if (input_event.type == WebKit::WebInputEvent::MouseMove) {
+ // Since this mouse-move event has been consumed, there will be no ACKs.
+ // So reset the state here so that future mouse-move events do reach the
+ // renderer.
+ mouse_move_pending_ = false;
+ } else if (input_event.type == WebKit::WebInputEvent::MouseWheel) {
+ // Reset the wheel-event state when appropriate.
+ mouse_wheel_pending_ = false;
+ } else if (WebInputEvent::isGestureEventType(input_event.type) &&
+ gesture_event_filter_->HasQueuedGestureEvents()) {
+ // If the gesture-event filter has queued gesture events, that implies it
+ // is awaiting an ack for the event. Since the event is being consumed by
+ // the over scroll here, it is never sent to the renderer, and so it won't
+ // receive any ACKs. So send the ACK to the gesture event filter
+ // immediately, and mark it as having been processed.
+ gesture_event_filter_->ProcessGestureAck(true, input_event.type);
+ } else if (WebInputEvent::isTouchEventType(input_event.type)) {
+ // During an overscroll gesture initiated by touch-scrolling, the
+ // touch-events do not reset or contribute to the overscroll gesture.
+ // However, the touch-events are not sent to the renderer. So send and ACK
+ // to the touch-event queue immediately. Mark the event as not processed,
+ // to make sure that the touch-scroll gesture that initiated the
+ // overscroll is updated properly.
+ touch_event_queue_->ProcessTouchAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ }
+ return;
+ }
+
+ // Transmit any pending wheel events on a non-wheel event. This ensures that
+ // the renderer receives the final PhaseEnded wheel event, which is necessary
+ // to terminate rubber-banding, for example.
+ if (input_event.type != WebInputEvent::MouseWheel) {
+ for (size_t i = 0; i < coalesced_mouse_wheel_events_.size(); ++i) {
+ SendInputEvent(coalesced_mouse_wheel_events_[i].event,
+ sizeof(WebMouseWheelEvent),
+ coalesced_mouse_wheel_events_[i].latency,
+ false);
+ }
+ coalesced_mouse_wheel_events_.clear();
+ }
+
+ if (view_) {
+ // Perform optional, synchronous event handling, sending ACK messages for
+ // processed events, or proceeding as usual.
+ InputEventAckState filter_ack = view_->FilterInputEvent(input_event);
+ switch (filter_ack) {
+ // Send the ACK and early exit.
+ case INPUT_EVENT_ACK_STATE_CONSUMED:
+ case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS:
+ next_mouse_move_.reset();
+ OnInputEventAck(input_event.type, filter_ack);
+ // WARNING: |this| may be deleted at this point.
+ return;
+
+ // Proceed as normal.
+ case INPUT_EVENT_ACK_STATE_UNKNOWN:
+ case INPUT_EVENT_ACK_STATE_NOT_CONSUMED:
+ default:
+ break;
+ };
+ }
+
+ SendInputEvent(input_event, event_size, latency_info, is_keyboard_shortcut);
+
+ // Any input event cancels a pending mouse move event. Note that
+ // |next_mouse_move_| possibly owns |input_event|, so don't use |input_event|
+ // after this line.
+ next_mouse_move_.reset();
+
+ StartHangMonitorTimeout(
+ TimeDelta::FromMilliseconds(hung_renderer_delay_ms_));
+}
+
+void RenderWidgetHostImpl::ForwardTouchEventWithLatencyInfo(
+ const WebKit::WebTouchEvent& touch_event,
+ const ui::LatencyInfo& ui_latency) {
+ ui::LatencyInfo latency_info = CreateRWHLatencyInfoIfNotExist(&ui_latency);
+ TouchEventWithLatencyInfo touch_with_latency(touch_event, latency_info);
+ touch_event_queue_->QueueEvent(touch_with_latency);
+}
void RenderWidgetHostImpl::AddKeyboardListener(KeyboardListener* listener) {
keyboard_listeners_.AddObserver(listener);
@@ -1133,7 +1462,9 @@ void RenderWidgetHostImpl::GetWebScreenInfo(WebKit::WebScreenInfo* result) {
const NativeWebKeyboardEvent*
RenderWidgetHostImpl::GetLastKeyboardEvent() const {
- return input_router_->GetLastKeyboardEvent();
+ if (key_queue_.empty())
+ return NULL;
+ return &key_queue_.front();
}
void RenderWidgetHostImpl::NotifyScreenInfoChanged() {
@@ -1191,13 +1522,31 @@ void RenderWidgetHostImpl::RendererExited(base::TerminationStatus status,
waiting_for_screen_rects_ack_ = false;
- // Reset to ensure that input routing works with a new renderer.
- input_router_.reset(new ImmediateInputRouter(process_, this, routing_id_));
+ // Must reset these to ensure that mouse move/wheel events work with a new
+ // renderer.
+ mouse_move_pending_ = false;
+ next_mouse_move_.reset();
+ mouse_wheel_pending_ = false;
+ coalesced_mouse_wheel_events_.clear();
+
+ // Must reset these to ensure that SelectRange works with a new renderer.
+ select_range_pending_ = false;
+ next_selection_range_.reset();
+
+ // Must reset these to ensure that MoveCaret works with a new renderer.
+ move_caret_pending_ = false;
+ next_move_caret_.reset();
+
+ touch_event_queue_->Reset();
+
+ // Must reset these to ensure that gesture events work with a new renderer.
+ gesture_event_filter_->Reset();
if (overscroll_controller_)
overscroll_controller_->Reset();
- // Must reset these to ensure that keyboard events work with a new renderer.
+ // Must reset these to ensure that keyboard events work with a new renderer.
+ key_queue_.clear();
suppress_next_char_events_ = false;
// Reset some fields in preparation for recovering from a crash.
@@ -1653,6 +2002,56 @@ void RenderWidgetHostImpl::DidUpdateBackingStore(
UMA_HISTOGRAM_TIMES("MPArch.RWH_TotalPaintTime", delta);
}
+void RenderWidgetHostImpl::OnInputEventAck(
+ WebInputEvent::Type event_type, InputEventAckState ack_result) {
+ TRACE_EVENT0("input", "RenderWidgetHostImpl::OnInputEventAck");
+ bool processed = (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED);
+
+ // Log the time delta for processing an input event.
+ TimeDelta delta = TimeTicks::Now() - input_event_start_time_;
+ UMA_HISTOGRAM_TIMES("MPArch.RWH_InputEventDelta", delta);
+
+ // Cancel pending hung renderer checks since the renderer is responsive.
+ if (decrement_in_flight_event_count() == 0)
+ StopHangMonitorTimeout();
+
+ int type = static_cast<int>(event_type);
+ if (type < WebInputEvent::Undefined) {
+ RecordAction(UserMetricsAction("BadMessageTerminate_RWH2"));
+ process_->ReceivedBadMessage();
+ } else if (type == WebInputEvent::MouseMove) {
+ mouse_move_pending_ = false;
+
+ // now, we can send the next mouse move event
+ if (next_mouse_move_) {
+ DCHECK(next_mouse_move_->event.type == WebInputEvent::MouseMove);
+ ForwardMouseEventWithLatencyInfo(*next_mouse_move_);
+ }
+ } else if (WebInputEvent::isKeyboardEventType(type)) {
+ ProcessKeyboardEventAck(type, processed);
+ } else if (type == WebInputEvent::MouseWheel) {
+ ProcessWheelAck(processed);
+ } else if (WebInputEvent::isTouchEventType(type)) {
+ ProcessTouchAck(ack_result);
+ } else if (WebInputEvent::isGestureEventType(type)) {
+ ProcessGestureAck(processed, type);
+ }
+
+ // WARNING: |this| may be deleted at this point.
+
+ // This is used only for testing, and the other end does not use the
+ // source object. On linux, specifying
+ // Source<RenderWidgetHost> results in a very strange
+ // runtime error in the epilogue of the enclosing
+ // (OnInputEventAck) method, but not on other platforms; using
+ // 'void' instead is just as safe (since NotificationSource
+ // is not actually typesafe) and avoids this error.
+ NotificationService::current()->Notify(
+ NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_INPUT_EVENT_ACK,
+ Source<void>(this),
+ Details<int>(&type));
+}
+
void RenderWidgetHostImpl::OnBeginSmoothScroll(
const ViewHostMsg_BeginSmoothScroll_Params& params) {
if (!view_)
@@ -1660,6 +2059,59 @@ void RenderWidgetHostImpl::OnBeginSmoothScroll(
smooth_scroll_gesture_controller_.BeginSmoothScroll(view_, params);
}
+void RenderWidgetHostImpl::OnSelectRangeAck() {
+ select_range_pending_ = false;
+ if (next_selection_range_) {
+ scoped_ptr<SelectionRange> next(next_selection_range_.Pass());
+ SelectRange(next->start, next->end);
+ }
+}
+
+void RenderWidgetHostImpl::OnMsgMoveCaretAck() {
+ move_caret_pending_ = false;
+ if (next_move_caret_) {
+ scoped_ptr<gfx::Point> next(next_move_caret_.Pass());
+ MoveCaret(*next);
+ }
+}
+
+void RenderWidgetHostImpl::ProcessWheelAck(bool processed) {
+ mouse_wheel_pending_ = false;
+
+ if (overscroll_controller_)
+ overscroll_controller_->ReceivedEventACK(current_wheel_event_, processed);
+
+ // Process the unhandled wheel event here before calling
+ // ForwardWheelEventWithLatencyInfo() since it will mutate
+ // current_wheel_event_.
+ if (!processed && !is_hidden_ && view_)
+ view_->UnhandledWheelEvent(current_wheel_event_);
+
+ // Now send the next (coalesced) mouse wheel event.
+ if (!coalesced_mouse_wheel_events_.empty()) {
+ MouseWheelEventWithLatencyInfo next_wheel_event =
+ coalesced_mouse_wheel_events_.front();
+ coalesced_mouse_wheel_events_.pop_front();
+ ForwardWheelEventWithLatencyInfo(next_wheel_event.event,
+ next_wheel_event.latency);
+ }
+}
+
+void RenderWidgetHostImpl::ProcessGestureAck(bool processed, int type) {
+ if (overscroll_controller_) {
+ overscroll_controller_->ReceivedEventACK(
+ gesture_event_filter_->GetGestureEventAwaitingAck(), processed);
+ }
+ gesture_event_filter_->ProcessGestureAck(processed, type);
+
+ if (view_)
+ view_->GestureEventAck(type);
+}
+
+void RenderWidgetHostImpl::ProcessTouchAck(InputEventAckState ack_result) {
+ touch_event_queue_->ProcessTouchAck(ack_result);
+}
+
void RenderWidgetHostImpl::OnFocus() {
// Only RenderViewHost can deal with that message.
RecordAction(UserMetricsAction("BadMessageTerminate_RWH4"));
@@ -1672,6 +2124,18 @@ void RenderWidgetHostImpl::OnBlur() {
GetProcess()->ReceivedBadMessage();
}
+void RenderWidgetHostImpl::OnHasTouchEventHandlers(bool has_handlers) {
+ if (has_touch_handler_ == has_handlers)
+ return;
+ has_touch_handler_ = has_handlers;
+ if (!has_touch_handler_)
+ touch_event_queue_->FlushQueue();
+#if defined(OS_ANDROID)
+ if (view_)
+ view_->HasTouchEventHandlers(has_touch_handler_);
+#endif
+}
+
void RenderWidgetHostImpl::OnSetCursor(const WebCursor& cursor) {
if (!view_) {
return;
@@ -1881,263 +2345,51 @@ bool RenderWidgetHostImpl::KeyPressListenersHandleEvent(
return false;
}
-InputEventAckState RenderWidgetHostImpl::FilterInputEvent(
- const WebKit::WebInputEvent& event, const ui::LatencyInfo& latency_info) {
- if (overscroll_controller() &&
- !overscroll_controller()->WillDispatchEvent(event, latency_info)) {
- return INPUT_EVENT_ACK_STATE_UNKNOWN;
- }
-
- return view_ ? view_->FilterInputEvent(event)
- : INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
-}
-
-void RenderWidgetHostImpl::IncrementInFlightEventCount() {
- StartHangMonitorTimeout(
- TimeDelta::FromMilliseconds(hung_renderer_delay_ms_));
- increment_in_flight_event_count();
-}
-
-void RenderWidgetHostImpl::DecrementInFlightEventCount() {
- DCHECK(in_flight_event_count_ >= 0);
- // Cancel pending hung renderer checks since the renderer is responsive.
- if (decrement_in_flight_event_count() <= 0)
- StopHangMonitorTimeout();
-}
-
-void RenderWidgetHostImpl::OnHasTouchEventHandlers(bool has_handlers) {
- if (has_touch_handler_ == has_handlers)
- return;
- has_touch_handler_ = has_handlers;
-#if defined(OS_ANDROID)
- if (view_)
- view_->HasTouchEventHandlers(has_touch_handler_);
-#endif
-}
-
-bool RenderWidgetHostImpl::OnSendKeyboardEvent(
- const NativeWebKeyboardEvent& key_event,
- const ui::LatencyInfo& latency_info,
- bool* is_shortcut) {
- if (IgnoreInputEvents())
- return false;
+void RenderWidgetHostImpl::ProcessKeyboardEventAck(int type, bool processed) {
+ if (key_queue_.empty()) {
+ LOG(ERROR) << "Got a KeyEvent back from the renderer but we "
+ << "don't seem to have sent it to the renderer!";
+ } else if (key_queue_.front().type != type) {
+ LOG(ERROR) << "We seem to have a different key type sent from "
+ << "the renderer. (" << key_queue_.front().type << " vs. "
+ << type << "). Ignoring event.";
- if (!process_->HasConnection())
- return false;
-
- // First, let keypress listeners take a shot at handling the event. If a
- // listener handles the event, it should not be propagated to the renderer.
- if (KeyPressListenersHandleEvent(key_event)) {
- // Some keypresses that are accepted by the listener might have follow up
- // char events, which should be ignored.
- if (key_event.type == WebKeyboardEvent::RawKeyDown)
- suppress_next_char_events_ = true;
- return false;
- }
-
- if (key_event.type == WebKeyboardEvent::Char &&
- (key_event.windowsKeyCode == ui::VKEY_RETURN ||
- key_event.windowsKeyCode == ui::VKEY_SPACE)) {
- OnUserGesture();
- }
-
- // Double check the type to make sure caller hasn't sent us nonsense that
- // will mess up our key queue.
- if (!WebInputEvent::isKeyboardEventType(key_event.type))
- return false;
-
- if (suppress_next_char_events_) {
- // If preceding RawKeyDown event was handled by the browser, then we need
- // suppress all Char events generated by it. Please note that, one
- // RawKeyDown event may generate multiple Char events, so we can't reset
- // |suppress_next_char_events_| until we get a KeyUp or a RawKeyDown.
- if (key_event.type == WebKeyboardEvent::Char)
- return false;
- // We get a KeyUp or a RawKeyDown event.
+ // Something must be wrong. Clear the |key_queue_| and
+ // |suppress_next_char_events_| so that we can resume from the error.
+ key_queue_.clear();
suppress_next_char_events_ = false;
- }
-
- // Only pre-handle the key event if it's not handled by the input method.
- if (delegate_ && !key_event.skip_in_browser) {
- // We need to set |suppress_next_char_events_| to true if
- // PreHandleKeyboardEvent() returns true, but |this| may already be
- // destroyed at that time. So set |suppress_next_char_events_| true here,
- // then revert it afterwards when necessary.
- if (key_event.type == WebKeyboardEvent::RawKeyDown)
- suppress_next_char_events_ = true;
-
- // Tab switching/closing accelerators aren't sent to the renderer to avoid
- // a hung/malicious renderer from interfering.
- if (delegate_->PreHandleKeyboardEvent(key_event, is_shortcut))
- return false;
-
- if (key_event.type == WebKeyboardEvent::RawKeyDown)
- suppress_next_char_events_ = false;
- }
-
- return true;
-}
-
-bool RenderWidgetHostImpl::OnSendWheelEvent(
- const MouseWheelEventWithLatencyInfo& wheel_event) {
- if (IgnoreInputEvents())
- return false;
-
- if (delegate_->PreHandleWheelEvent(wheel_event.event))
- return false;
-
- return true;
-}
-
-bool RenderWidgetHostImpl::OnSendMouseEvent(
- const MouseEventWithLatencyInfo& mouse_event) {
- if (IgnoreInputEvents())
- return false;
-
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kSimulateTouchScreenWithMouse)) {
- SimulateTouchGestureWithMouse(mouse_event.event);
- return false;
- }
-
- return true;
-}
-
-bool RenderWidgetHostImpl::OnSendTouchEvent(
- const TouchEventWithLatencyInfo& touch_event) {
- return !IgnoreInputEvents();
-}
-
-bool RenderWidgetHostImpl::OnSendGestureEvent(
- const GestureEventWithLatencyInfo& gesture_event) {
- if (IgnoreInputEvents())
- return false;
-
- if (!IsInOverscrollGesture() &&
- !input_router_->ShouldForwardGestureEvent(gesture_event)) {
- if (overscroll_controller_.get())
- overscroll_controller_->DiscardingGestureEvent(gesture_event.event);
- return false;
- }
-
- return true;
-}
-
-bool RenderWidgetHostImpl::OnSendMouseEventImmediately(
- const MouseEventWithLatencyInfo& mouse_event) {
- TRACE_EVENT_INSTANT0("input",
- "RenderWidgetHostImpl::OnSendMouseEventImmediately",
- TRACE_EVENT_SCOPE_THREAD);
- if (IgnoreInputEvents())
- return false;
-
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kSimulateTouchScreenWithMouse)) {
- SimulateTouchGestureWithMouse(mouse_event.event);
- return false;
- }
-
- if (mouse_event.event.type == WebInputEvent::MouseDown)
- OnUserGesture();
-
- return true;
-}
-
-bool RenderWidgetHostImpl::OnSendTouchEventImmediately(
- const TouchEventWithLatencyInfo& touch_event) {
- TRACE_EVENT_INSTANT0("input",
- "RenderWidgetHostImpl::OnSendTouchEventImmediately",
- TRACE_EVENT_SCOPE_THREAD);
- return !IgnoreInputEvents();
-}
-
-bool RenderWidgetHostImpl::OnSendGestureEventImmediately(
- const GestureEventWithLatencyInfo& gesture_event) {
- TRACE_EVENT_INSTANT0("input",
- "RenderWidgetHostImpl::OnSendGestureEventImmediately",
- TRACE_EVENT_SCOPE_THREAD);
- return !IgnoreInputEvents();
-}
+ } else {
+ NativeWebKeyboardEvent front_item = key_queue_.front();
+ key_queue_.pop_front();
-void RenderWidgetHostImpl::OnKeyboardEventAck(
- const NativeWebKeyboardEvent& event,
- InputEventAckState ack_result) {
#if defined(OS_MACOSX)
- if (!is_hidden() && view_ && view_->PostProcessEventForPluginIme(event))
- return;
+ if (!is_hidden_ && view_->PostProcessEventForPluginIme(front_item))
+ return;
#endif
- // We only send unprocessed key event upwards if we are not hidden,
- // because the user has moved away from us and no longer expect any effect
- // of this key event.
- const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result);
- if (delegate_ && !processed && !is_hidden() && !event.skip_in_browser) {
- delegate_->HandleKeyboardEvent(event);
-
- // WARNING: This RenderWidgetHostImpl can be deallocated at this point
- // (i.e. in the case of Ctrl+W, where the call to
- // HandleKeyboardEvent destroys this RenderWidgetHostImpl).
- }
-}
-
-void RenderWidgetHostImpl::OnWheelEventAck(
- const WebKit::WebMouseWheelEvent& wheel_event,
- InputEventAckState ack_result) {
- const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result);
- if (overscroll_controller_)
- overscroll_controller_->ReceivedEventACK(wheel_event, processed);
-
- if (!processed && !is_hidden() && view_)
- view_->UnhandledWheelEvent(wheel_event);
-}
-
-void RenderWidgetHostImpl::OnGestureEventAck(
- const WebKit::WebGestureEvent& event,
- InputEventAckState ack_result) {
- const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result);
- if (overscroll_controller_)
- overscroll_controller_->ReceivedEventACK(event, processed);
+ // We only send unprocessed key event upwards if we are not hidden,
+ // because the user has moved away from us and no longer expect any effect
+ // of this key event.
+ if (delegate_ && !processed && !is_hidden_ && !front_item.skip_in_browser) {
+ delegate_->HandleKeyboardEvent(front_item);
- if (view_)
- view_->GestureEventAck(event.type);
-}
-
-void RenderWidgetHostImpl::OnTouchEventAck(
- const TouchEventWithLatencyInfo& event,
- InputEventAckState ack_result) {
- ComputeTouchLatency(event.latency);
- if (view_)
- view_->ProcessAckedTouchEvent(event, ack_result);
-}
-
-void RenderWidgetHostImpl::OnUnexpectedEventAck(bool bad_message) {
- if (bad_message) {
- RecordAction(UserMetricsAction("BadMessageTerminate_RWH2"));
- process_->ReceivedBadMessage();
+ // WARNING: This RenderWidgetHostImpl can be deallocated at this point
+ // (i.e. in the case of Ctrl+W, where the call to
+ // HandleKeyboardEvent destroys this RenderWidgetHostImpl).
+ }
}
-
- suppress_next_char_events_ = false;
}
const gfx::Vector2d& RenderWidgetHostImpl::GetLastScrollOffset() const {
return last_scroll_offset_;
}
-bool RenderWidgetHostImpl::IgnoreInputEvents() const {
- return ignore_input_events_ || process_->IgnoreInputEvents();
-}
-
bool RenderWidgetHostImpl::ShouldForwardTouchEvent() const {
- return input_router_->ShouldForwardTouchEvent();
-}
-
-bool RenderWidgetHostImpl::ShouldForwardGestureEvent(
- const GestureEventWithLatencyInfo& gesture_event) const {
- return input_router_->ShouldForwardGestureEvent(gesture_event);
-}
-
-bool RenderWidgetHostImpl::HasQueuedGestureEvents() const {
- return input_router_->HasQueuedGestureEvents();
+ // Always send a touch event if the renderer has a touch-event handler. It is
+ // possible that a renderer stops listening to touch-events while there are
+ // still events in the touch-queue. In such cases, the new events should still
+ // get into the queue.
+ return has_touch_handler_ || !touch_event_queue_->empty();
}
void RenderWidgetHostImpl::StartUserGesture() {
@@ -2159,7 +2411,7 @@ void RenderWidgetHostImpl::SetEditCommandsForNextKeyEvent(
void RenderWidgetHostImpl::SetAccessibilityMode(AccessibilityMode mode) {
accessibility_mode_ = mode;
- Send(new ViewMsg_SetAccessibilityMode(GetRoutingID(), mode));
+ Send(new ViewMsg_SetAccessibilityMode(routing_id_, mode));
}
void RenderWidgetHostImpl::AccessibilityDoDefaultAction(int object_id) {
@@ -2217,10 +2469,26 @@ void RenderWidgetHostImpl::ScrollFocusedEditableNodeIntoRect(
void RenderWidgetHostImpl::SelectRange(const gfx::Point& start,
const gfx::Point& end) {
+ if (select_range_pending_) {
+ if (!next_selection_range_) {
+ next_selection_range_.reset(new SelectionRange());
+ }
+ next_selection_range_->start = start;
+ next_selection_range_->end = end;
+ return;
+ }
+
+ select_range_pending_ = true;
Send(new InputMsg_SelectRange(GetRoutingID(), start, end));
}
void RenderWidgetHostImpl::MoveCaret(const gfx::Point& point) {
+ if (move_caret_pending_) {
+ next_move_caret_.reset(new gfx::Point(point));
+ return;
+ }
+
+ move_caret_pending_ = true;
Send(new InputMsg_MoveCaret(GetRoutingID(), point));
}
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index 752c7c0..c848aa1 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -23,7 +23,6 @@
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
-#include "content/browser/renderer_host/input/input_router_client.h"
#include "content/browser/renderer_host/smooth_scroll_gesture_controller.h"
#include "content/common/browser_rendering_stats.h"
#include "content/common/view_message_enums.h"
@@ -73,18 +72,18 @@ class WebLayer;
namespace content {
class BackingStore;
-class InputRouter;
+class GestureEventFilter;
class MockRenderWidgetHost;
class OverscrollController;
class RenderWidgetHostDelegate;
class RenderWidgetHostViewPort;
class SmoothScrollGestureController;
+class TouchEventQueue;
struct EditCommand;
// This implements the RenderWidgetHost interface that is exposed to
// embedders of content, and adds things only visible to content.
class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
- public InputRouterClient,
public IPC::Listener {
public:
// routing_id can be MSG_ROUTING_NONE, in which case the next available
@@ -281,13 +280,17 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
void ForwardGestureEventWithLatencyInfo(
const WebKit::WebGestureEvent& gesture_event,
const ui::LatencyInfo& ui_latency);
- void ForwardTouchEventWithLatencyInfo(
+ virtual void ForwardTouchEventWithLatencyInfo(
const WebKit::WebTouchEvent& touch_event,
const ui::LatencyInfo& ui_latency);
- void ForwardMouseEventWithLatencyInfo(
+
+ // Forwards the given event immediately to the renderer.
+ void ForwardMouseEventImmediately(
const MouseEventWithLatencyInfo& mouse_event);
- void ForwardWheelEventWithLatencyInfo(
- const MouseWheelEventWithLatencyInfo& wheel_event);
+ void ForwardTouchEventImmediately(
+ const TouchEventWithLatencyInfo& touch_event);
+ void ForwardGestureEventImmediately(
+ const GestureEventWithLatencyInfo& gesture_event);
void CancelUpdateTextDirection();
@@ -352,15 +355,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
return input_method_active_;
}
- // Whether forwarded WebInputEvents should be ignored. True if either
- // |ignore_input_events_| or |process_->IgnoreInputEvents()| is true.
- bool IgnoreInputEvents() const;
-
- // Event queries delegated to the |input_router_|.
bool ShouldForwardTouchEvent() const;
- bool ShouldForwardGestureEvent(
- const GestureEventWithLatencyInfo& gesture_event) const;
- bool HasQueuedGestureEvents() const;
bool has_touch_handler() const { return has_touch_handler_; }
@@ -494,7 +489,11 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
// Update the renderer's cache of the screen rect of the view and window.
void SendScreenRects();
- OverscrollController* overscroll_controller() const {
+ GestureEventFilter* gesture_event_filter() {
+ return gesture_event_filter_.get();
+ }
+
+ OverscrollController* overscroll_controller() {
return overscroll_controller_.get();
}
@@ -527,6 +526,24 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
protected:
virtual RenderWidgetHostImpl* AsRenderWidgetHostImpl() OVERRIDE;
+ // Transmits the given input event. This is an internal helper for
+ // |ForwardInputEvent()| and should not be used directly from elsewhere.
+ void SendInputEvent(const WebKit::WebInputEvent& input_event,
+ int event_size, const ui::LatencyInfo& latency_info,
+ bool is_keyboard_shortcut);
+
+ // Internal implementation of the public Forward*Event() methods.
+ void ForwardInputEvent(const WebKit::WebInputEvent& input_event,
+ int event_size, const ui::LatencyInfo& latency_info,
+ bool is_keyboard_shortcut);
+
+ // Internal forwarding implementations that take a LatencyInfo.
+ virtual void ForwardMouseEventWithLatencyInfo(
+ const MouseEventWithLatencyInfo& mouse_event);
+ virtual void ForwardWheelEventWithLatencyInfo(
+ const WebKit::WebMouseWheelEvent& wheel_event,
+ const ui::LatencyInfo& latency_info);
+
// Create a LatencyInfo struct with INPUT_EVENT_LATENCY_RWH_COMPONENT
// component if it is not already in |original|. And if |original| is
// not NULL, it is also merged into the resulting LatencyInfo.
@@ -641,10 +658,15 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
gfx::Vector2dF current_fling_velocity);
void OnUpdateRect(const ViewHostMsg_UpdateRect_Params& params);
void OnUpdateIsDelayed();
+ void OnInputEventAck(WebKit::WebInputEvent::Type event_type,
+ InputEventAckState ack_result);
void OnBeginSmoothScroll(
const ViewHostMsg_BeginSmoothScroll_Params& params);
+ void OnSelectRangeAck();
+ void OnMsgMoveCaretAck();
virtual void OnFocus();
virtual void OnBlur();
+ void OnHasTouchEventHandlers(bool has_handlers);
void OnSetCursor(const WebCursor& cursor);
void OnTextInputTypeChanged(ui::TextInputType type,
bool can_compose_inline,
@@ -699,43 +721,26 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
// widgets that don't have focus to still handle key presses.
bool KeyPressListenersHandleEvent(const NativeWebKeyboardEvent& event);
- // InputRouterClient
- virtual InputEventAckState FilterInputEvent(
- const WebKit::WebInputEvent& event,
- const ui::LatencyInfo& latency_info) OVERRIDE;
- virtual void IncrementInFlightEventCount() OVERRIDE;
- virtual void DecrementInFlightEventCount() OVERRIDE;
- virtual void OnHasTouchEventHandlers(bool has_handlers) OVERRIDE;
- virtual bool OnSendKeyboardEvent(
- const NativeWebKeyboardEvent& key_event,
- const ui::LatencyInfo& latency_info,
- bool* is_shortcut) OVERRIDE;
- virtual bool OnSendWheelEvent(
- const MouseWheelEventWithLatencyInfo& wheel_event) OVERRIDE;
- virtual bool OnSendMouseEvent(
- const MouseEventWithLatencyInfo& mouse_event) OVERRIDE;
- virtual bool OnSendTouchEvent(
- const TouchEventWithLatencyInfo& touch_event) OVERRIDE;
- virtual bool OnSendGestureEvent(
- const GestureEventWithLatencyInfo& gesture_event) OVERRIDE;
- virtual bool OnSendMouseEventImmediately(
- const MouseEventWithLatencyInfo& mouse_event) OVERRIDE;
- virtual bool OnSendTouchEventImmediately(
- const TouchEventWithLatencyInfo& touch_event) OVERRIDE;
- virtual bool OnSendGestureEventImmediately(
- const GestureEventWithLatencyInfo& gesture_event) OVERRIDE;
- virtual void OnKeyboardEventAck(const NativeWebKeyboardEvent& event,
- InputEventAckState ack_result) OVERRIDE;
- virtual void OnWheelEventAck(const WebKit::WebMouseWheelEvent& event,
- InputEventAckState ack_result) OVERRIDE;
- virtual void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
- InputEventAckState ack_result) OVERRIDE;
- virtual void OnGestureEventAck(const WebKit::WebGestureEvent& event,
- InputEventAckState ack_result) OVERRIDE;
- virtual void OnUnexpectedEventAck(bool bad_message) OVERRIDE;
+ // Called by OnInputEventAck() to process a keyboard event ack message.
+ void ProcessKeyboardEventAck(int type, bool processed);
+
+ // Called by OnInputEventAck() to process a wheel event ack message.
+ // This could result in a task being posted to allow additional wheel
+ // input messages to be coalesced.
+ void ProcessWheelAck(bool processed);
+
+ // Called by OnInputEventAck() to process a gesture event ack message.
+ // This validates the gesture for suppression of touchpad taps and sends one
+ // previously queued coalesced gesture if it exists.
+ void ProcessGestureAck(bool processed, int type);
void SimulateTouchGestureWithMouse(const WebKit::WebMouseEvent& mouse_event);
+ // Called on OnInputEventAck() to process a touch event ack message.
+ // This can result in a gesture event being generated and sent back to the
+ // renderer.
+ void ProcessTouchAck(InputEventAckState ack_result);
+
// Called when there is a new auto resize (using a post to avoid a stack
// which may get in recursive loops).
void DelayedAutoResized();
@@ -813,8 +818,50 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
gfx::Rect last_view_screen_rect_;
gfx::Rect last_window_screen_rect_;
+ // True if a mouse move event was sent to the render view and we are waiting
+ // for a corresponding InputHostMsg_HandleInputEvent_ACK message.
+ bool mouse_move_pending_;
+
+ // The next mouse move event to send (only non-null while mouse_move_pending_
+ // is true).
+ scoped_ptr<MouseEventWithLatencyInfo> next_mouse_move_;
+
+ // (Similar to |mouse_move_pending_|.) True if a mouse wheel event was sent
+ // and we are waiting for a corresponding ack.
+ bool mouse_wheel_pending_;
+ WebKit::WebMouseWheelEvent current_wheel_event_;
+
+ typedef std::deque<MouseWheelEventWithLatencyInfo> WheelEventQueue;
+
+ // (Similar to |next_mouse_move_|.) The next mouse wheel events to send.
+ // Unlike mouse moves, mouse wheel events received while one is pending are
+ // coalesced (by accumulating deltas) if they match the previous event in
+ // modifiers. On the Mac, in particular, mouse wheel events are received at a
+ // high rate; not waiting for the ack results in jankiness, and using the same
+ // mechanism as for mouse moves (just dropping old events when multiple ones
+ // would be queued) results in very slow scrolling.
+ WheelEventQueue coalesced_mouse_wheel_events_;
+
AccessibilityMode accessibility_mode_;
+ // (Similar to |mouse_move_pending_|.) True while waiting for SelectRange_ACK.
+ bool select_range_pending_;
+
+ // (Similar to |next_mouse_move_|.) The next SelectRange to send, if any.
+ struct SelectionRange {
+ gfx::Point start, end;
+ };
+ scoped_ptr<SelectionRange> next_selection_range_;
+
+ // (Similar to |mouse_move_pending_|.) True while waiting for MoveCaret_ACK.
+ bool move_caret_pending_;
+
+ // (Similar to |next_mouse_move_|.) The next MoveCaret to send, if any.
+ scoped_ptr<gfx::Point> next_move_caret_;
+
+ // The time when an input event was sent to the RenderWidget.
+ base::TimeTicks input_event_start_time_;
+
// Keyboard event listeners.
ObserverList<KeyboardListener> keyboard_listeners_;
@@ -851,6 +898,14 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
// operation to finish.
base::TimeTicks repaint_start_time_;
+ // Queue of keyboard events that we need to track.
+ typedef std::deque<NativeWebKeyboardEvent> KeyQueue;
+
+ // A queue of keyboard events. We can't trust data from the renderer so we
+ // stuff key events into a queue and pop them out on ACK, feeding our copy
+ // back to whatever unhandled handler instead of the returned version.
+ KeyQueue key_queue_;
+
// Set to true if we shouldn't send input events from the render widget.
bool ignore_input_events_;
@@ -895,10 +950,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
base::WeakPtrFactory<RenderWidgetHostImpl> weak_factory_;
SmoothScrollGestureController smooth_scroll_gesture_controller_;
-
- // Receives and handles all input events.
- scoped_ptr<InputRouter> input_router_;
-
+ scoped_ptr<TouchEventQueue> touch_event_queue_;
+ scoped_ptr<GestureEventFilter> gesture_event_filter_;
scoped_ptr<OverscrollController> overscroll_controller_;
#if defined(OS_WIN)
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc
index 9911354..9109c30 100644
--- a/content/browser/renderer_host/render_widget_host_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -9,7 +9,6 @@
#include "content/browser/browser_thread_impl.h"
#include "content/browser/renderer_host/backing_store.h"
#include "content/browser/renderer_host/gesture_event_filter.h"
-#include "content/browser/renderer_host/input/immediate_input_router.h"
#include "content/browser/renderer_host/overscroll_controller.h"
#include "content/browser/renderer_host/overscroll_controller_delegate.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
@@ -114,8 +113,6 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
int routing_id)
: RenderWidgetHostImpl(delegate, process, routing_id),
unresponsive_timer_fired_(false) {
- immediate_input_router_ =
- static_cast<ImmediateInputRouter*>(input_router_.get());
}
// Allow poking at a few private members.
@@ -125,7 +122,9 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
using RenderWidgetHostImpl::last_requested_size_;
using RenderWidgetHostImpl::is_hidden_;
using RenderWidgetHostImpl::resize_ack_pending_;
- using RenderWidgetHostImpl::input_router_;
+ using RenderWidgetHostImpl::gesture_event_filter_;
+ using RenderWidgetHostImpl::touch_event_queue_;
+ using RenderWidgetHostImpl::overscroll_controller_;
bool unresponsive_timer_fired() const {
return unresponsive_timer_fired_;
@@ -136,40 +135,40 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
}
unsigned GestureEventLastQueueEventSize() {
- return gesture_event_filter()->coalesced_gesture_events_.size();
+ return gesture_event_filter_->coalesced_gesture_events_.size();
}
WebGestureEvent GestureEventSecondFromLastQueueEvent() {
- return gesture_event_filter()->coalesced_gesture_events_.at(
+ return gesture_event_filter_->coalesced_gesture_events_.at(
GestureEventLastQueueEventSize() - 2).event;
}
WebGestureEvent GestureEventLastQueueEvent() {
- return gesture_event_filter()->coalesced_gesture_events_.back().event;
+ return gesture_event_filter_->coalesced_gesture_events_.back().event;
}
unsigned GestureEventDebouncingQueueSize() {
- return gesture_event_filter()->debouncing_deferral_queue_.size();
+ return gesture_event_filter_->debouncing_deferral_queue_.size();
}
WebGestureEvent GestureEventQueueEventAt(int i) {
- return gesture_event_filter()->coalesced_gesture_events_.at(i).event;
+ return gesture_event_filter_->coalesced_gesture_events_.at(i).event;
}
bool shouldDeferTapDownEvents() {
- return gesture_event_filter()->maximum_tap_gap_time_ms_ != 0;
+ return gesture_event_filter_->maximum_tap_gap_time_ms_ != 0;
}
bool ScrollingInProgress() {
- return gesture_event_filter()->scrolling_in_progress_;
+ return gesture_event_filter_->scrolling_in_progress_;
}
bool FlingInProgress() {
- return gesture_event_filter()->fling_in_progress_;
+ return gesture_event_filter_->fling_in_progress_;
}
bool WillIgnoreNextACK() {
- return gesture_event_filter()->ignore_next_ack_;
+ return gesture_event_filter_->ignore_next_ack_;
}
void SetupForOverscrollControllerTest() {
@@ -179,15 +178,15 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
}
void set_maximum_tap_gap_time_ms(int delay_ms) {
- gesture_event_filter()->maximum_tap_gap_time_ms_ = delay_ms;
+ gesture_event_filter_->maximum_tap_gap_time_ms_ = delay_ms;
}
void set_debounce_interval_time_ms(int delay_ms) {
- gesture_event_filter()->debounce_interval_time_ms_ = delay_ms;
+ gesture_event_filter_->debounce_interval_time_ms_ = delay_ms;
}
size_t TouchEventQueueSize() {
- return touch_event_queue()->GetQueueSize();
+ return touch_event_queue_->GetQueueSize();
}
bool ScrollStateIsContentScrolling() const {
@@ -207,7 +206,7 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
}
const WebTouchEvent& latest_event() const {
- return touch_event_queue()->GetLatestEvent().event;
+ return touch_event_queue_->GetLatestEvent().event;
}
OverscrollMode overscroll_mode() const {
@@ -231,18 +230,9 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
unresponsive_timer_fired_ = true;
}
- TouchEventQueue* touch_event_queue() const {
- return immediate_input_router_->touch_event_queue();
- }
-
- GestureEventFilter* gesture_event_filter() const {
- return immediate_input_router_->gesture_event_filter();
- }
-
private:
bool unresponsive_timer_fired_;
- ImmediateInputRouter* immediate_input_router_;
scoped_ptr<TestOverscrollDelegate> overscroll_delegate_;
DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHost);
diff --git a/content/browser/renderer_host/touch_event_queue.cc b/content/browser/renderer_host/touch_event_queue.cc
index 70804e3..5f69c41 100644
--- a/content/browser/renderer_host/touch_event_queue.cc
+++ b/content/browser/renderer_host/touch_event_queue.cc
@@ -7,6 +7,9 @@
#include "base/auto_reset.h"
#include "base/debug/trace_event.h"
#include "base/stl_util.h"
+#include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/public/browser/render_widget_host_view.h"
+#include "content/port/browser/render_widget_host_view_port.h"
namespace content {
@@ -15,8 +18,8 @@ typedef std::vector<TouchEventWithLatencyInfo> WebTouchEventWithLatencyList;
// This class represents a single coalesced touch event. However, it also keeps
// track of all the original touch-events that were coalesced into a single
// event. The coalesced event is forwarded to the renderer, while the original
-// touch-events are sent to the Client (on ACK for the coalesced event) so that
-// the Client receives the event with their original timestamp.
+// touch-events are sent to the View (on ACK for the coalesced event) so that
+// the View receives the event with their original timestamp.
class CoalescedWebTouchEvent {
public:
explicit CoalescedWebTouchEvent(const TouchEventWithLatencyInfo& event)
@@ -41,8 +44,6 @@ class CoalescedWebTouchEvent {
event_with_latency.event.modifiers &&
coalesced_event_.event.touchesLength ==
event_with_latency.event.touchesLength) {
- TRACE_EVENT_INSTANT0(
- "input", "TouchEventQueue::MoveCoalesced", TRACE_EVENT_SCOPE_THREAD);
events_.push_back(event_with_latency);
// The WebTouchPoints include absolute position information. So it is
// sufficient to simply replace the previous event with the new event.
@@ -89,10 +90,9 @@ class CoalescedWebTouchEvent {
DISALLOW_COPY_AND_ASSIGN(CoalescedWebTouchEvent);
};
-TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client)
- : client_(client),
+TouchEventQueue::TouchEventQueue(RenderWidgetHostImpl* host)
+ : render_widget_host_(host),
dispatching_touch_ack_(false) {
- DCHECK(client);
}
TouchEventQueue::~TouchEventQueue() {
@@ -108,9 +108,9 @@ void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) {
// immediately.
touch_queue_.push_back(new CoalescedWebTouchEvent(event));
if (ShouldForwardToRenderer(event.event))
- client_->SendTouchEventImmediately(event);
+ render_widget_host_->ForwardTouchEventImmediately(event);
else
- PopTouchEventWithAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ PopTouchEventToView(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
return;
}
@@ -149,25 +149,30 @@ void TouchEventQueue::ProcessTouchAck(InputEventAckState ack_result) {
}
}
- PopTouchEventWithAck(ack_result);
+ PopTouchEventToView(ack_result);
// If there are queued touch events, then try to forward them to the renderer
- // immediately, or ACK the events back to the client if appropriate.
+ // immediately, or ACK the events back to the view if appropriate.
while (!touch_queue_.empty()) {
const TouchEventWithLatencyInfo& touch =
touch_queue_.front()->coalesced_event();
if (ShouldForwardToRenderer(touch.event)) {
- client_->SendTouchEventImmediately(touch);
+ render_widget_host_->ForwardTouchEventImmediately(touch);
break;
}
- PopTouchEventWithAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ PopTouchEventToView(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
}
}
void TouchEventQueue::FlushQueue() {
DCHECK(!dispatching_touch_ack_);
while (!touch_queue_.empty())
- PopTouchEventWithAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ PopTouchEventToView(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+}
+
+void TouchEventQueue::Reset() {
+ if (!touch_queue_.empty())
+ STLDeleteElements(&touch_queue_);
}
size_t TouchEventQueue::GetQueueSize() const {
@@ -178,7 +183,7 @@ const TouchEventWithLatencyInfo& TouchEventQueue::GetLatestEvent() const {
return touch_queue_.back()->coalesced_event();
}
-void TouchEventQueue::PopTouchEventWithAck(InputEventAckState ack_result) {
+void TouchEventQueue::PopTouchEventToView(InputEventAckState ack_result) {
if (touch_queue_.empty())
return;
scoped_ptr<CoalescedWebTouchEvent> acked_event(touch_queue_.front());
@@ -188,13 +193,16 @@ void TouchEventQueue::PopTouchEventWithAck(InputEventAckState ack_result) {
// to the renderer, or touch-events being queued.
base::AutoReset<bool> dispatching_touch_ack(&dispatching_touch_ack_, true);
+ RenderWidgetHostViewPort* view = RenderWidgetHostViewPort::FromRWHV(
+ render_widget_host_->GetView());
for (WebTouchEventWithLatencyList::const_iterator iter = acked_event->begin(),
end = acked_event->end();
iter != end; ++iter) {
ui::LatencyInfo* latency = const_cast<ui::LatencyInfo*>(&(iter->latency));
latency->AddLatencyNumber(
ui::INPUT_EVENT_LATENCY_ACKED_COMPONENT, 0, 0);
- client_->OnTouchEventAck((*iter), ack_result);
+ render_widget_host_->ComputeTouchLatency(*latency);
+ view->ProcessAckedTouchEvent((*iter), ack_result);
}
}
diff --git a/content/browser/renderer_host/touch_event_queue.h b/content/browser/renderer_host/touch_event_queue.h
index 09783a8..8149ebf 100644
--- a/content/browser/renderer_host/touch_event_queue.h
+++ b/content/browser/renderer_host/touch_event_queue.h
@@ -17,27 +17,13 @@
namespace content {
class CoalescedWebTouchEvent;
-
-// Interface with which TouchEventQueue can forward touch events, and dispatch
-// touch event responses.
-class TouchEventQueueClient {
- public:
- virtual ~TouchEventQueueClient() {}
-
- virtual void SendTouchEventImmediately(
- const TouchEventWithLatencyInfo& event) = 0;
-
- virtual void OnTouchEventAck(
- const TouchEventWithLatencyInfo& event,
- InputEventAckState ack_result) = 0;
-};
+class MockRenderWidgetHost;
+class RenderWidgetHostImpl;
// A queue for throttling and coalescing touch-events.
class TouchEventQueue {
public:
-
- // The |client| must outlive the TouchEventQueue.
- explicit TouchEventQueue(TouchEventQueueClient* client);
+ explicit TouchEventQueue(RenderWidgetHostImpl* host);
virtual ~TouchEventQueue();
// Adds an event to the queue. The event may be coalesced with previously
@@ -55,6 +41,10 @@ class TouchEventQueue {
// events being sent to the renderer.
void FlushQueue();
+ // Resets all internal state. This does not trigger any touch or gesture
+ // events to be sent.
+ void Reset();
+
// Returns whether the event-queue is empty.
bool empty() const WARN_UNUSED_RESULT {
return touch_queue_.empty();
@@ -67,13 +57,13 @@ class TouchEventQueue {
CONTENT_EXPORT const TouchEventWithLatencyInfo& GetLatestEvent() const;
// Pops the touch-event from the top of the queue and sends it to the
- // TouchEventQueueClient. This reduces the size of the queue by one.
- void PopTouchEventWithAck(InputEventAckState ack_result);
+ // RenderWidgetHostView. This reduces the size of the queue by one.
+ void PopTouchEventToView(InputEventAckState ack_result);
bool ShouldForwardToRenderer(const WebKit::WebTouchEvent& event) const;
- // Handles touch event forwarding and ack'ed event dispatch.
- TouchEventQueueClient* client_;
+ // The RenderWidgetHost that owns this event-queue.
+ RenderWidgetHostImpl* render_widget_host_;
typedef std::deque<CoalescedWebTouchEvent*> TouchQueue;
TouchQueue touch_queue_;
diff --git a/content/browser/renderer_host/touchpad_tap_suppression_controller.cc b/content/browser/renderer_host/touchpad_tap_suppression_controller.cc
index e69b640..0e8ee71 100644
--- a/content/browser/renderer_host/touchpad_tap_suppression_controller.cc
+++ b/content/browser/renderer_host/touchpad_tap_suppression_controller.cc
@@ -13,8 +13,8 @@
namespace content {
TouchpadTapSuppressionController::TouchpadTapSuppressionController(
- InputRouter* /*input_router*/)
- : input_router_(NULL) {}
+ RenderWidgetHostImpl* /*rwhv*/)
+ : render_widget_host_(NULL) {}
TouchpadTapSuppressionController::~TouchpadTapSuppressionController() {}
diff --git a/content/browser/renderer_host/touchpad_tap_suppression_controller.h b/content/browser/renderer_host/touchpad_tap_suppression_controller.h
index e78f5f1..d2cd3cc 100644
--- a/content/browser/renderer_host/touchpad_tap_suppression_controller.h
+++ b/content/browser/renderer_host/touchpad_tap_suppression_controller.h
@@ -12,15 +12,14 @@
namespace content {
-class InputRouter;
+class RenderWidgetHostImpl;
class TapSuppressionController;
// Controls the suppression of touchpad taps immediately following the dispatch
// of a GestureFlingCancel event.
class TouchpadTapSuppressionController : public TapSuppressionControllerClient {
public:
- // The |input_router| must outlive the TouchpadTapSupressionController.
- explicit TouchpadTapSuppressionController(InputRouter* input_router);
+ explicit TouchpadTapSuppressionController(RenderWidgetHostImpl* rwhv);
virtual ~TouchpadTapSuppressionController();
// Should be called on arrival of GestureFlingCancel events.
@@ -49,7 +48,7 @@ class TouchpadTapSuppressionController : public TapSuppressionControllerClient {
virtual void ForwardStashedTapDownForDeferral() OVERRIDE;
virtual void ForwardStashedTapDownSkipDeferral() OVERRIDE;
- InputRouter* input_router_;
+ RenderWidgetHostImpl* render_widget_host_;
MouseEventWithLatencyInfo stashed_mouse_down_;
// The core controller of tap suppression.
diff --git a/content/browser/renderer_host/touchpad_tap_suppression_controller_aura.cc b/content/browser/renderer_host/touchpad_tap_suppression_controller_aura.cc
index 940dc2b..a9ef442 100644
--- a/content/browser/renderer_host/touchpad_tap_suppression_controller_aura.cc
+++ b/content/browser/renderer_host/touchpad_tap_suppression_controller_aura.cc
@@ -4,7 +4,7 @@
#include "content/browser/renderer_host/touchpad_tap_suppression_controller.h"
-#include "content/browser/renderer_host/input/input_router.h"
+#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/tap_suppression_controller.h"
#include "content/browser/renderer_host/tap_suppression_controller_client.h"
#include "ui/base/gestures/gesture_configuration.h"
@@ -12,8 +12,8 @@
namespace content {
TouchpadTapSuppressionController::TouchpadTapSuppressionController(
- InputRouter* input_router)
- : input_router_(input_router),
+ RenderWidgetHostImpl* rwhv)
+ : render_widget_host_(rwhv),
controller_(new TapSuppressionController(this)) {
}
@@ -53,13 +53,13 @@ void TouchpadTapSuppressionController::DropStashedTapDown() {
void TouchpadTapSuppressionController::ForwardStashedTapDownForDeferral() {
// Mouse downs are not handled by gesture event filter; so, they are
// immediately forwarded to the renderer.
- input_router_->SendMouseEventImmediately(stashed_mouse_down_);
+ render_widget_host_->ForwardMouseEventImmediately(stashed_mouse_down_);
}
void TouchpadTapSuppressionController::ForwardStashedTapDownSkipDeferral() {
// Mouse downs are not handled by gesture event filter; so, they are
// immediately forwarded to the renderer.
- input_router_->SendMouseEventImmediately(stashed_mouse_down_);
+ render_widget_host_->ForwardMouseEventImmediately(stashed_mouse_down_);
}
} // namespace content
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index ac9f5e9..f81c863 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -771,10 +771,6 @@
'browser/renderer_host/image_transport_factory_android.h',
'browser/renderer_host/ime_adapter_android.cc',
'browser/renderer_host/ime_adapter_android.h',
- 'browser/renderer_host/input/immediate_input_router.cc',
- 'browser/renderer_host/input/immediate_input_router.h',
- 'browser/renderer_host/input/input_router.h',
- 'browser/renderer_host/input/input_router_client.h',
'browser/renderer_host/java/java_bound_object.cc',
'browser/renderer_host/java/java_bound_object.h',
'browser/renderer_host/java/java_bridge_channel_host.cc',