| Index: content/browser/renderer_host/gesture_event_filter.cc
|
| diff --git a/content/browser/renderer_host/gesture_event_filter.cc b/content/browser/renderer_host/gesture_event_filter.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..cf99f45e2414649584611a36ae9f672f511f30e6
|
| --- /dev/null
|
| +++ b/content/browser/renderer_host/gesture_event_filter.cc
|
| @@ -0,0 +1,111 @@
|
| +// Copyright (c) 2012 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/gesture_event_filter.h"
|
| +
|
| +#include "content/browser/renderer_host/render_widget_host_impl.h"
|
| +#include "content/browser/renderer_host/tap_suppression_controller.h"
|
| +
|
| +namespace content {
|
| +namespace {
|
| +// Returns |true| if two gesture events should be coalesced.
|
| +bool ShouldCoalesceGestureEvents(const WebKit::WebGestureEvent& last_event,
|
| + const WebKit::WebGestureEvent& new_event) {
|
| + return new_event.type == WebInputEvent::GestureScrollUpdate &&
|
| + last_event.type == new_event.type &&
|
| + last_event.modifiers == new_event.modifiers;
|
| +}
|
| +} // namespace
|
| +
|
| +GestureEventFilter::GestureEventFilter(RenderWidgetHostImpl* rwhv)
|
| + : render_widget_host_(rwhv),
|
| + fling_in_progress_(false),
|
| + gesture_event_pending_(false),
|
| + tap_suppression_controller_(new TapSuppressionController(rwhv)) {
|
| +}
|
| +
|
| +GestureEventFilter::~GestureEventFilter() { }
|
| +
|
| +bool GestureEventFilter::ShouldDiscardFlingCancelEvent(
|
| + const WebKit::WebGestureEvent& gesture_event) {
|
| + DCHECK(gesture_event.type == WebInputEvent::GestureFlingCancel);
|
| + if (coalesced_gesture_events_.empty() && fling_in_progress_)
|
| + return false;
|
| + GestureEventQueue::reverse_iterator it =
|
| + coalesced_gesture_events_.rbegin();
|
| + while (it != coalesced_gesture_events_.rend()) {
|
| + if (it->type == WebInputEvent::GestureFlingStart)
|
| + return false;
|
| + if (it->type == WebInputEvent::GestureFlingCancel)
|
| + return true;
|
| + it++;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +bool GestureEventFilter::ShouldForward(const WebGestureEvent& gesture_event) {
|
| + if (gesture_event.type == WebInputEvent::GestureFlingCancel) {
|
| + if (ShouldDiscardFlingCancelEvent(gesture_event))
|
| + return false;
|
| + fling_in_progress_ = false;
|
| + }
|
| +
|
| + if (gesture_event_pending_) {
|
| + if (coalesced_gesture_events_.empty() ||
|
| + !ShouldCoalesceGestureEvents(coalesced_gesture_events_.back(),
|
| + gesture_event)) {
|
| + coalesced_gesture_events_.push_back(gesture_event);
|
| + } else {
|
| + WebGestureEvent* last_gesture_event =
|
| + &coalesced_gesture_events_.back();
|
| + last_gesture_event->deltaX += gesture_event.deltaX;
|
| + last_gesture_event->deltaY += gesture_event.deltaY;
|
| + DCHECK_GE(gesture_event.timeStampSeconds,
|
| + last_gesture_event->timeStampSeconds);
|
| + last_gesture_event->timeStampSeconds = gesture_event.timeStampSeconds;
|
| + }
|
| + return false;
|
| + }
|
| + gesture_event_pending_ = true;
|
| +
|
| + if (gesture_event.type == WebInputEvent::GestureFlingCancel) {
|
| + tap_suppression_controller_->GestureFlingCancel(
|
| + gesture_event.timeStampSeconds);
|
| + } else if (gesture_event.type == WebInputEvent::GestureFlingStart) {
|
| + fling_in_progress_ = true;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +void GestureEventFilter::Reset() {
|
| + fling_in_progress_ = false;
|
| + coalesced_gesture_events_.clear();
|
| + gesture_event_pending_ = false;
|
| +}
|
| +
|
| +void GestureEventFilter::ProcessGestureAck(bool processed, int type) {
|
| + if (type == WebInputEvent::GestureFlingCancel)
|
| + tap_suppression_controller_->GestureFlingCancelAck(processed);
|
| +
|
| + gesture_event_pending_ = false;
|
| +
|
| + // Now send the next (coalesced) gesture event.
|
| + if (!coalesced_gesture_events_.empty()) {
|
| + WebGestureEvent next_gesture_event =
|
| + coalesced_gesture_events_.front();
|
| + coalesced_gesture_events_.pop_front();
|
| + render_widget_host_->ForwardGestureEvent(next_gesture_event);
|
| + }
|
| +}
|
| +
|
| +TapSuppressionController* GestureEventFilter::GetTapSuppressionController() {
|
| + return tap_suppression_controller_.get();
|
| +}
|
| +
|
| +void GestureEventFilter::FlingHasBeenHalted() {
|
| + fling_in_progress_ = false;
|
| +}
|
| +
|
| +} // namespace content
|
|
|