| Index: content/browser/renderer_host/input/immediate_input_router.cc
|
| diff --git a/content/browser/renderer_host/input/immediate_input_router.cc b/content/browser/renderer_host/input/immediate_input_router.cc
|
| index 06bbc950e1d798a648fac65502f6c1c57365badc..31876bde5e022ce15a48ed80af25957db152174c 100644
|
| --- a/content/browser/renderer_host/input/immediate_input_router.cc
|
| +++ b/content/browser/renderer_host/input/immediate_input_router.cc
|
| @@ -70,8 +70,73 @@ const char* GetEventAckName(InputEventAckState ack_result) {
|
| return "";
|
| }
|
|
|
| +bool BrowserSideFlingEnabled() {
|
| + return CommandLine::ForCurrentProcess()->HasSwitch(
|
| + switches::kEnableBrowserSideFling);
|
| +}
|
| +
|
| } // namespace
|
|
|
| +// A helper class that based on the value of the |kEnableBrowserSideFling| flag
|
| +// does event filtering using either |BaseGestureEventFilter| or
|
| +// |GestureEventFilter|.
|
| +class ImmediateInputRouter::EventFilteringHelper {
|
| + public:
|
| + // |router| must outlive us.
|
| + explicit EventFilteringHelper(ImmediateInputRouter* router) {
|
| + if (BrowserSideFlingEnabled())
|
| + gesture_event_filter_.reset(new BaseGestureEventFilter(router));
|
| + else
|
| + gesture_event_filter_.reset(new GestureEventFilter(router, router));
|
| + }
|
| + virtual ~EventFilteringHelper() {}
|
| +
|
| + bool ShouldDeferMouseDown(const MouseEventWithLatencyInfo& mouse_event) {
|
| + if (BrowserSideFlingEnabled())
|
| + return false;
|
| +
|
| + return static_cast<GestureEventFilter*>(gesture_event_filter_.get())->
|
| + GetTouchpadTapSuppressionController()->ShouldDeferMouseDown(
|
| + mouse_event);
|
| + }
|
| +
|
| + bool ShouldDeferMouseUp(const MouseEventWithLatencyInfo& mouse_event) {
|
| + if (BrowserSideFlingEnabled())
|
| + return false;
|
| +
|
| + return static_cast<GestureEventFilter*>(gesture_event_filter_.get())->
|
| + GetTouchpadTapSuppressionController()->ShouldSuppressMouseUp();
|
| + }
|
| +
|
| + void FlingHasBeenHalted() {
|
| + if (BrowserSideFlingEnabled())
|
| + return;
|
| +
|
| + static_cast<GestureEventFilter*>(gesture_event_filter_.get())->
|
| + FlingHasBeenHalted();
|
| + }
|
| +
|
| + bool ShouldForwardGesture(const GestureEventWithLatencyInfo& gesture_event) {
|
| + return gesture_event_filter_->ShouldForward(gesture_event);
|
| + }
|
| +
|
| + bool HasQueuedGestureEvents() {
|
| + return gesture_event_filter_->HasQueuedGestureEvents();
|
| + }
|
| +
|
| + void ProcessGestureAck(InputEventAckState ack_result,
|
| + blink::WebInputEvent::Type type,
|
| + const ui::LatencyInfo& latency) {
|
| + gesture_event_filter_->ProcessGestureAck(ack_result, type, latency);
|
| + }
|
| +
|
| + private:
|
| + friend class ImmediateInputRouter;
|
| + scoped_ptr<BaseGestureEventFilter> gesture_event_filter_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(EventFilteringHelper);
|
| +};
|
| +
|
| ImmediateInputRouter::ImmediateInputRouter(IPC::Sender* sender,
|
| InputRouterClient* client,
|
| InputAckHandler* ack_handler,
|
| @@ -87,7 +152,8 @@ ImmediateInputRouter::ImmediateInputRouter(IPC::Sender* sender,
|
| has_touch_handler_(false),
|
| current_ack_source_(ACK_SOURCE_NONE),
|
| touch_event_queue_(new TouchEventQueue(this)),
|
| - gesture_event_filter_(new GestureEventFilter(this, this)) {
|
| + flinger_(new Flinger(this)),
|
| + event_filter_(new EventFilteringHelper(this)) {
|
| DCHECK(sender);
|
| DCHECK(client);
|
| DCHECK(ack_handler);
|
| @@ -126,13 +192,14 @@ void ImmediateInputRouter::SendMouseEvent(
|
| return;
|
| }
|
|
|
| + if (BrowserSideFlingEnabled() && flinger_->HandleMouseEvent(mouse_event))
|
| + return;
|
| +
|
| if (mouse_event.event.type == WebInputEvent::MouseDown &&
|
| - gesture_event_filter_->GetTouchpadTapSuppressionController()->
|
| - ShouldDeferMouseDown(mouse_event))
|
| + event_filter_->ShouldDeferMouseDown(mouse_event))
|
| return;
|
| if (mouse_event.event.type == WebInputEvent::MouseUp &&
|
| - gesture_event_filter_->GetTouchpadTapSuppressionController()->
|
| - ShouldSuppressMouseUp())
|
| + event_filter_->ShouldDeferMouseUp(mouse_event))
|
| return;
|
|
|
| SendMouseEventImmediately(mouse_event);
|
| @@ -140,6 +207,9 @@ void ImmediateInputRouter::SendMouseEvent(
|
|
|
| void ImmediateInputRouter::SendWheelEvent(
|
| const MouseWheelEventWithLatencyInfo& wheel_event) {
|
| + if (BrowserSideFlingEnabled() && flinger_->HandleWheelEvent(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
|
| @@ -166,13 +236,16 @@ void ImmediateInputRouter::SendKeyboardEvent(
|
| const NativeWebKeyboardEvent& key_event,
|
| const ui::LatencyInfo& latency_info,
|
| bool is_keyboard_shortcut) {
|
| + if (BrowserSideFlingEnabled() && flinger_->HandleKeyboardEvent())
|
| + 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();
|
| + event_filter_->FlingHasBeenHalted();
|
|
|
| // Only forward the non-native portions of our event.
|
| FilterAndSendWebInputEvent(key_event, latency_info, is_keyboard_shortcut);
|
| @@ -182,8 +255,11 @@ void ImmediateInputRouter::SendGestureEvent(
|
| const GestureEventWithLatencyInfo& gesture_event) {
|
| HandleGestureScroll(gesture_event);
|
|
|
| + if (BrowserSideFlingEnabled() && flinger_->HandleGestureEvent(gesture_event))
|
| + return;
|
| +
|
| if (!IsInOverscrollGesture() &&
|
| - !gesture_event_filter_->ShouldForward(gesture_event)) {
|
| + !event_filter_->ShouldForwardGesture(gesture_event)) {
|
| OverscrollController* controller = client_->GetOverscrollController();
|
| if (controller)
|
| controller->DiscardingGestureEvent(gesture_event.event);
|
| @@ -277,6 +353,25 @@ void ImmediateInputRouter::OnGestureEventAck(
|
| ack_handler_->OnGestureEventAck(event, ack_result);
|
| }
|
|
|
| +void ImmediateInputRouter::SendEventForFling(
|
| + const blink::WebInputEvent& event) {
|
| + ui::LatencyInfo latency_info;
|
| + if (Send(new InputMsg_HandleInputEvent(
|
| + routing_id(), &event, latency_info, false)))
|
| + in_process_messages_sources_.push(MESSAGE_SOURCE_FLING);
|
| +}
|
| +
|
| +void ImmediateInputRouter::FlingFinished(
|
| + blink::WebGestureEvent::SourceDevice source) {
|
| + if (source == blink::WebGestureEvent::Touchscreen) {
|
| + ui::LatencyInfo latency_info;
|
| + blink::WebGestureEvent synthetic_gesture;
|
| + synthetic_gesture.type = blink::WebInputEvent::GestureScrollEnd;
|
| + synthetic_gesture.sourceDevice = blink::WebGestureEvent::Touchscreen;
|
| + OfferToRenderer(synthetic_gesture, latency_info, false);
|
| + }
|
| +}
|
| +
|
| bool ImmediateInputRouter::SendSelectRange(scoped_ptr<IPC::Message> message) {
|
| DCHECK(message->type() == InputMsg_SelectRange::ID);
|
| if (select_range_pending_) {
|
| @@ -358,7 +453,7 @@ bool ImmediateInputRouter::OfferToOverscrollController(
|
| const blink::WebGestureEvent& gesture_event =
|
| static_cast<const blink::WebGestureEvent&>(input_event);
|
| // An ACK is expected for the event, so mark it as consumed.
|
| - consumed = !gesture_event_filter_->ShouldForward(
|
| + consumed = !event_filter_->ShouldForwardGesture(
|
| GestureEventWithLatencyInfo(gesture_event, latency_info));
|
| }
|
|
|
| @@ -408,6 +503,7 @@ bool ImmediateInputRouter::OfferToRenderer(const WebInputEvent& input_event,
|
| input_event_start_time_ = TimeTicks::Now();
|
| if (Send(new InputMsg_HandleInputEvent(
|
| routing_id(), &input_event, latency_info, is_keyboard_shortcut))) {
|
| + in_process_messages_sources_.push(MESSAGE_SOURCE_REGULAR);
|
| client_->IncrementInFlightEventCount();
|
| return true;
|
| }
|
| @@ -422,6 +518,13 @@ void ImmediateInputRouter::OnInputEventAck(
|
| TimeDelta delta = TimeTicks::Now() - input_event_start_time_;
|
| UMA_HISTOGRAM_TIMES("MPArch.IIR_InputEventDelta", delta);
|
|
|
| + InputMessageSource source = in_process_messages_sources_.front();
|
| + in_process_messages_sources_.pop();
|
| + if (source == MESSAGE_SOURCE_FLING) {
|
| + flinger_->ProcessEventAck(event_type, ack_result, latency_info);
|
| + return;
|
| + }
|
| +
|
| client_->DecrementInFlightEventCount();
|
|
|
| ProcessInputEventAck(event_type, ack_result, latency_info, RENDERER);
|
| @@ -560,12 +663,12 @@ void ImmediateInputRouter::ProcessGestureAck(WebInputEvent::Type type,
|
| // If |ack_result| originated from the overscroll controller, only
|
| // feed |gesture_event_filter_| the ack if it was expecting one.
|
| if (current_ack_source_ == OVERSCROLL_CONTROLLER &&
|
| - !gesture_event_filter_->HasQueuedGestureEvents()) {
|
| + !event_filter_->HasQueuedGestureEvents()) {
|
| return;
|
| }
|
|
|
| // |gesture_event_filter_| will forward to OnGestureEventAck when appropriate.
|
| - gesture_event_filter_->ProcessGestureAck(ack_result, type, latency);
|
| + event_filter_->ProcessGestureAck(ack_result, type, latency);
|
| }
|
|
|
| void ImmediateInputRouter::ProcessTouchAck(
|
| @@ -681,4 +784,8 @@ bool ImmediateInputRouter::IsInOverscrollGesture() const {
|
| return controller && controller->overscroll_mode() != OVERSCROLL_NONE;
|
| }
|
|
|
| +BaseGestureEventFilter* ImmediateInputRouter::gesture_event_filter() {
|
| + return event_filter_->gesture_event_filter_.get();
|
| +}
|
| +
|
| } // namespace content
|
|
|