| Index: content/browser/renderer_host/input/gesture_event_filter.cc
|
| diff --git a/content/browser/renderer_host/input/gesture_event_filter.cc b/content/browser/renderer_host/input/gesture_event_filter.cc
|
| deleted file mode 100644
|
| index 62fcb9c34fc20f2fefd547b4c3eafde17eb7ff14..0000000000000000000000000000000000000000
|
| --- a/content/browser/renderer_host/input/gesture_event_filter.cc
|
| +++ /dev/null
|
| @@ -1,392 +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/gesture_event_filter.h"
|
| -
|
| -#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/input/touchpad_tap_suppression_controller.h"
|
| -#include "content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h"
|
| -#include "content/public/common/content_switches.h"
|
| -
|
| -using WebKit::WebGestureEvent;
|
| -using WebKit::WebInputEvent;
|
| -
|
| -namespace content {
|
| -namespace {
|
| -
|
| -// Default debouncing interval duration: if a scroll is in progress, non-scroll
|
| -// events during this interval are deferred to either its end or discarded on
|
| -// receipt of another GestureScrollUpdate.
|
| -static const int kDebouncingIntervalTimeMs = 30;
|
| -
|
| -} // namespace
|
| -
|
| -GestureEventFilter::GestureEventFilter(
|
| - GestureEventFilterClient* client,
|
| - TouchpadTapSuppressionControllerClient* touchpad_client)
|
| - : client_(client),
|
| - fling_in_progress_(false),
|
| - scrolling_in_progress_(false),
|
| - ignore_next_ack_(false),
|
| - combined_scroll_pinch_(gfx::Transform()),
|
| - touchpad_tap_suppression_controller_(
|
| - new TouchpadTapSuppressionController(touchpad_client)),
|
| - touchscreen_tap_suppression_controller_(
|
| - new TouchscreenTapSuppressionController(this)),
|
| - debounce_interval_time_ms_(kDebouncingIntervalTimeMs) {
|
| - DCHECK(client);
|
| - DCHECK(touchpad_tap_suppression_controller_);
|
| -}
|
| -
|
| -GestureEventFilter::~GestureEventFilter() { }
|
| -
|
| -bool GestureEventFilter::ShouldDiscardFlingCancelEvent(
|
| - const GestureEventWithLatencyInfo& gesture_event) const {
|
| - if (coalesced_gesture_events_.empty() && fling_in_progress_)
|
| - return false;
|
| - GestureEventQueue::const_reverse_iterator it =
|
| - coalesced_gesture_events_.rbegin();
|
| - while (it != coalesced_gesture_events_.rend()) {
|
| - if (it->event.type == WebInputEvent::GestureFlingStart)
|
| - return false;
|
| - if (it->event.type == WebInputEvent::GestureFlingCancel)
|
| - return true;
|
| - it++;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -bool GestureEventFilter::ShouldForwardForBounceReduction(
|
| - const GestureEventWithLatencyInfo& gesture_event) {
|
| - if (debounce_interval_time_ms_ == 0)
|
| - return true;
|
| - switch (gesture_event.event.type) {
|
| - case WebInputEvent::GestureScrollUpdate:
|
| - if (!scrolling_in_progress_) {
|
| - debounce_deferring_timer_.Start(
|
| - FROM_HERE,
|
| - base::TimeDelta::FromMilliseconds(debounce_interval_time_ms_),
|
| - this,
|
| - &GestureEventFilter::SendScrollEndingEventsNow);
|
| - } else {
|
| - // Extend the bounce interval.
|
| - debounce_deferring_timer_.Reset();
|
| - }
|
| - scrolling_in_progress_ = true;
|
| - debouncing_deferral_queue_.clear();
|
| - return true;
|
| - case WebInputEvent::GesturePinchBegin:
|
| - case WebInputEvent::GesturePinchEnd:
|
| - case WebInputEvent::GesturePinchUpdate:
|
| - // TODO(rjkroege): Debounce pinch (http://crbug.com/147647)
|
| - return true;
|
| - default:
|
| - if (scrolling_in_progress_) {
|
| - debouncing_deferral_queue_.push_back(gesture_event);
|
| - return false;
|
| - }
|
| - return true;
|
| - }
|
| -
|
| - NOTREACHED();
|
| - return false;
|
| -}
|
| -
|
| -// NOTE: The filters are applied successively. This simplifies the change.
|
| -bool GestureEventFilter::ShouldForward(
|
| - const GestureEventWithLatencyInfo& gesture_event) {
|
| - return ShouldForwardForZeroVelocityFlingStart(gesture_event) &&
|
| - ShouldForwardForBounceReduction(gesture_event) &&
|
| - ShouldForwardForGFCFiltering(gesture_event) &&
|
| - ShouldForwardForTapSuppression(gesture_event) &&
|
| - ShouldForwardForCoalescing(gesture_event);
|
| -}
|
| -
|
| -bool GestureEventFilter::ShouldForwardForZeroVelocityFlingStart(
|
| - const GestureEventWithLatencyInfo& gesture_event) const {
|
| - return gesture_event.event.type != WebInputEvent::GestureFlingStart ||
|
| - gesture_event.event.sourceDevice != WebGestureEvent::Touchpad ||
|
| - gesture_event.event.data.flingStart.velocityX != 0 ||
|
| - gesture_event.event.data.flingStart.velocityY != 0;
|
| -}
|
| -
|
| -bool GestureEventFilter::ShouldForwardForGFCFiltering(
|
| - const GestureEventWithLatencyInfo& gesture_event) const {
|
| - return gesture_event.event.type != WebInputEvent::GestureFlingCancel ||
|
| - !ShouldDiscardFlingCancelEvent(gesture_event);
|
| -}
|
| -
|
| -bool GestureEventFilter::ShouldForwardForTapSuppression(
|
| - const GestureEventWithLatencyInfo& gesture_event) {
|
| - switch (gesture_event.event.type) {
|
| - case WebInputEvent::GestureFlingCancel:
|
| - if (gesture_event.event.sourceDevice == WebGestureEvent::Touchscreen)
|
| - touchscreen_tap_suppression_controller_->GestureFlingCancel();
|
| - else
|
| - touchpad_tap_suppression_controller_->GestureFlingCancel();
|
| - return true;
|
| - case WebInputEvent::GestureTapDown:
|
| - return !touchscreen_tap_suppression_controller_->
|
| - ShouldDeferGestureTapDown(gesture_event);
|
| - case WebInputEvent::GestureTapCancel:
|
| - return !touchscreen_tap_suppression_controller_->
|
| - ShouldSuppressGestureTapCancel();
|
| - case WebInputEvent::GestureTap:
|
| - case WebInputEvent::GestureTapUnconfirmed:
|
| - return !touchscreen_tap_suppression_controller_->
|
| - ShouldSuppressGestureTap();
|
| - default:
|
| - return true;
|
| - }
|
| - NOTREACHED();
|
| - return false;
|
| -}
|
| -
|
| -bool GestureEventFilter::ShouldForwardForCoalescing(
|
| - const GestureEventWithLatencyInfo& gesture_event) {
|
| - switch (gesture_event.event.type) {
|
| - case WebInputEvent::GestureFlingCancel:
|
| - fling_in_progress_ = false;
|
| - break;
|
| - case WebInputEvent::GestureFlingStart:
|
| - fling_in_progress_ = true;
|
| - break;
|
| - case WebInputEvent::GesturePinchUpdate:
|
| - case WebInputEvent::GestureScrollUpdate:
|
| - MergeOrInsertScrollAndPinchEvent(gesture_event);
|
| - return ShouldHandleEventNow();
|
| - default:
|
| - break;
|
| - }
|
| - EnqueueEvent(gesture_event);
|
| -
|
| - // Ensure that if the added event ignores its ack, it is fired and
|
| - // removed from |coalesced_gesture_events_|.
|
| - SendEventsIgnoringAck();
|
| - return ShouldHandleEventNow();
|
| -}
|
| -
|
| -void GestureEventFilter::ProcessGestureAck(InputEventAckState ack_result,
|
| - WebInputEvent::Type type,
|
| - const ui::LatencyInfo& latency) {
|
| - if (ShouldIgnoreAckForGestureType(type))
|
| - return;
|
| -
|
| - if (coalesced_gesture_events_.empty()) {
|
| - DLOG(ERROR) << "Received unexpected ACK for event type " << type;
|
| - return;
|
| - }
|
| - DCHECK_EQ(coalesced_gesture_events_.front().event.type, type);
|
| -
|
| - // Ack'ing an event may enqueue additional gesture events. By ack'ing the
|
| - // event before the forwarding of queued events below, such additional events
|
| - // can be coalesced with existing queued events prior to dispatch.
|
| - GestureEventWithLatencyInfo event_with_latency = GetGestureEventAwaitingAck();
|
| - event_with_latency.latency.AddNewLatencyFrom(latency);
|
| - client_->OnGestureEventAck(event_with_latency, ack_result);
|
| -
|
| - const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result);
|
| - if (type == WebInputEvent::GestureFlingCancel) {
|
| - if (coalesced_gesture_events_.front().event.sourceDevice ==
|
| - WebGestureEvent::Touchscreen)
|
| - touchscreen_tap_suppression_controller_->GestureFlingCancelAck(processed);
|
| - else
|
| - touchpad_tap_suppression_controller_->GestureFlingCancelAck(processed);
|
| - }
|
| - coalesced_gesture_events_.pop_front();
|
| - // If the event which was just ACKed was blocking events ignoring ack, fire
|
| - // those events now.
|
| - SendEventsIgnoringAck();
|
| - if (ignore_next_ack_) {
|
| - ignore_next_ack_ = false;
|
| - } else if (!coalesced_gesture_events_.empty()) {
|
| - const GestureEventWithLatencyInfo& next_gesture_event =
|
| - coalesced_gesture_events_.front();
|
| - client_->SendGestureEventImmediately(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) {
|
| - const GestureEventWithLatencyInfo& second_gesture_event =
|
| - coalesced_gesture_events_[1];
|
| - if (next_gesture_event.event.type ==
|
| - WebInputEvent::GestureScrollUpdate &&
|
| - second_gesture_event.event.type ==
|
| - WebInputEvent::GesturePinchUpdate) {
|
| - client_->SendGestureEventImmediately(second_gesture_event);
|
| - ignore_next_ack_ = true;
|
| - }
|
| - }
|
| - }
|
| -}
|
| -
|
| -TouchpadTapSuppressionController*
|
| - GestureEventFilter::GetTouchpadTapSuppressionController() {
|
| - return touchpad_tap_suppression_controller_.get();
|
| -}
|
| -
|
| -bool GestureEventFilter::HasQueuedGestureEvents() const {
|
| - return !coalesced_gesture_events_.empty();
|
| -}
|
| -
|
| -const GestureEventWithLatencyInfo&
|
| -GestureEventFilter::GetGestureEventAwaitingAck() const {
|
| - DCHECK(!coalesced_gesture_events_.empty());
|
| - if (!ignore_next_ack_)
|
| - return coalesced_gesture_events_.front();
|
| - else
|
| - return coalesced_gesture_events_.at(1);
|
| -}
|
| -
|
| -void GestureEventFilter::FlingHasBeenHalted() {
|
| - fling_in_progress_ = false;
|
| -}
|
| -
|
| -bool GestureEventFilter::ShouldHandleEventNow() const {
|
| - return coalesced_gesture_events_.size() == 1;
|
| -}
|
| -
|
| -void GestureEventFilter::ForwardGestureEvent(
|
| - const GestureEventWithLatencyInfo& gesture_event) {
|
| - if (ShouldForwardForCoalescing(gesture_event))
|
| - client_->SendGestureEventImmediately(gesture_event);
|
| -}
|
| -
|
| -void GestureEventFilter::SendScrollEndingEventsNow() {
|
| - scrolling_in_progress_ = false;
|
| - for (GestureEventQueue::const_iterator it =
|
| - debouncing_deferral_queue_.begin();
|
| - it != debouncing_deferral_queue_.end(); it++) {
|
| - if (ShouldForwardForGFCFiltering(*it) &&
|
| - ShouldForwardForTapSuppression(*it) &&
|
| - ShouldForwardForCoalescing(*it)) {
|
| - client_->SendGestureEventImmediately(*it);
|
| - }
|
| - }
|
| - debouncing_deferral_queue_.clear();
|
| -}
|
| -
|
| -void GestureEventFilter::MergeOrInsertScrollAndPinchEvent(
|
| - const GestureEventWithLatencyInfo& gesture_event) {
|
| - if (coalesced_gesture_events_.size() <= 1) {
|
| - EnqueueEvent(gesture_event);
|
| - return;
|
| - }
|
| - GestureEventWithLatencyInfo* last_event = &coalesced_gesture_events_.back();
|
| - if (last_event->CanCoalesceWith(gesture_event)) {
|
| - last_event->CoalesceWith(gesture_event);
|
| - if (!combined_scroll_pinch_.IsIdentity()) {
|
| - combined_scroll_pinch_.ConcatTransform(
|
| - GetTransformForEvent(gesture_event));
|
| - }
|
| - return;
|
| - }
|
| - if (coalesced_gesture_events_.size() == 2 ||
|
| - (coalesced_gesture_events_.size() == 3 && ignore_next_ack_) ||
|
| - !ShouldTryMerging(gesture_event, *last_event)) {
|
| - EnqueueEvent(gesture_event);
|
| - return;
|
| - }
|
| - GestureEventWithLatencyInfo scroll_event;
|
| - GestureEventWithLatencyInfo pinch_event;
|
| - scroll_event.event.modifiers |= gesture_event.event.modifiers;
|
| - scroll_event.event.timeStampSeconds = gesture_event.event.timeStampSeconds;
|
| - scroll_event.latency = gesture_event.latency;
|
| - scroll_event.latency.MergeWith(last_event->latency);
|
| - pinch_event = scroll_event;
|
| - scroll_event.event.type = WebInputEvent::GestureScrollUpdate;
|
| - pinch_event.event.type = WebInputEvent::GesturePinchUpdate;
|
| - pinch_event.event.x = gesture_event.event.type ==
|
| - WebInputEvent::GesturePinchUpdate ?
|
| - gesture_event.event.x : last_event->event.x;
|
| - pinch_event.event.y = gesture_event.event.type ==
|
| - WebInputEvent::GesturePinchUpdate ?
|
| - gesture_event.event.y : last_event->event.y;
|
| -
|
| - combined_scroll_pinch_.ConcatTransform(GetTransformForEvent(gesture_event));
|
| - GestureEventWithLatencyInfo* second_last_event = &coalesced_gesture_events_
|
| - [coalesced_gesture_events_.size() - 2];
|
| - if (ShouldTryMerging(gesture_event, *second_last_event)) {
|
| - scroll_event.latency.MergeWith(second_last_event->latency);
|
| - pinch_event.latency.MergeWith(second_last_event->latency);
|
| - coalesced_gesture_events_.pop_back();
|
| - } else {
|
| - DCHECK(combined_scroll_pinch_ == GetTransformForEvent(gesture_event));
|
| - combined_scroll_pinch_.
|
| - PreconcatTransform(GetTransformForEvent(*last_event));
|
| - }
|
| - coalesced_gesture_events_.pop_back();
|
| - float combined_scale =
|
| - SkMScalarToFloat(combined_scroll_pinch_.matrix().get(0, 0));
|
| - float combined_scroll_pinch_x =
|
| - SkMScalarToFloat(combined_scroll_pinch_.matrix().get(0, 3));
|
| - float combined_scroll_pinch_y =
|
| - SkMScalarToFloat(combined_scroll_pinch_.matrix().get(1, 3));
|
| - scroll_event.event.data.scrollUpdate.deltaX =
|
| - (combined_scroll_pinch_x + pinch_event.event.x) / combined_scale -
|
| - pinch_event.event.x;
|
| - scroll_event.event.data.scrollUpdate.deltaY =
|
| - (combined_scroll_pinch_y + pinch_event.event.y) / combined_scale -
|
| - pinch_event.event.y;
|
| - coalesced_gesture_events_.push_back(scroll_event);
|
| - pinch_event.event.data.pinchUpdate.scale = combined_scale;
|
| - coalesced_gesture_events_.push_back(pinch_event);
|
| -}
|
| -
|
| -bool GestureEventFilter::ShouldTryMerging(
|
| - const GestureEventWithLatencyInfo& new_event,
|
| - const GestureEventWithLatencyInfo& event_in_queue) const {
|
| - DLOG_IF(WARNING,
|
| - new_event.event.timeStampSeconds <
|
| - event_in_queue.event.timeStampSeconds)
|
| - << "Event time not monotonic?\n";
|
| - return (event_in_queue.event.type == WebInputEvent::GestureScrollUpdate ||
|
| - event_in_queue.event.type == WebInputEvent::GesturePinchUpdate) &&
|
| - event_in_queue.event.modifiers == new_event.event.modifiers;
|
| -}
|
| -
|
| -gfx::Transform GestureEventFilter::GetTransformForEvent(
|
| - const GestureEventWithLatencyInfo& gesture_event) const {
|
| - gfx::Transform gesture_transform = gfx::Transform();
|
| - if (gesture_event.event.type == WebInputEvent::GestureScrollUpdate) {
|
| - gesture_transform.Translate(gesture_event.event.data.scrollUpdate.deltaX,
|
| - gesture_event.event.data.scrollUpdate.deltaY);
|
| - } else if (gesture_event.event.type == WebInputEvent::GesturePinchUpdate) {
|
| - float scale = gesture_event.event.data.pinchUpdate.scale;
|
| - gesture_transform.Translate(-gesture_event.event.x, -gesture_event.event.y);
|
| - gesture_transform.Scale(scale,scale);
|
| - gesture_transform.Translate(gesture_event.event.x, gesture_event.event.y);
|
| - }
|
| - return gesture_transform;
|
| -}
|
| -
|
| -void GestureEventFilter::SendEventsIgnoringAck() {
|
| - GestureEventWithLatencyInfo gesture_event;
|
| - while (!coalesced_gesture_events_.empty()) {
|
| - gesture_event = coalesced_gesture_events_.front();
|
| - if (!GestureEventFilter::ShouldIgnoreAckForGestureType(
|
| - gesture_event.event.type)) {
|
| - return;
|
| - }
|
| - coalesced_gesture_events_.pop_front();
|
| - client_->SendGestureEventImmediately(gesture_event);
|
| - }
|
| -}
|
| -
|
| -bool GestureEventFilter::ShouldIgnoreAckForGestureType(
|
| - WebInputEvent::Type type) {
|
| - return type == WebInputEvent::GestureTapDown ||
|
| - type == WebInputEvent::GestureShowPress;
|
| -}
|
| -
|
| -void GestureEventFilter::EnqueueEvent(
|
| - const GestureEventWithLatencyInfo& gesture_event) {
|
| - coalesced_gesture_events_.push_back(gesture_event);
|
| - // Scroll and pinch events contributing to |combined_scroll_pinch_| will be
|
| - // manually added to the queue in |MergeOrInsertScrollAndPinchEvent()|.
|
| - combined_scroll_pinch_ = gfx::Transform();
|
| -}
|
| -
|
| -} // namespace content
|
|
|