Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1377)

Unified Diff: content/browser/renderer_host/gesture_event_filter.cc

Issue 12087140: Suppress touchscreen tap immediately after a GestureFlingCancel (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Allowed GFC Ack in NOTHING state + Resolved a link error on win Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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
index e5fc3edce90e0dcd6ab37758bb9594e8c946b7c8..02ed0c31cfdceae33470d2c4be1a953caeaee534 100644
--- a/content/browser/renderer_host/gesture_event_filter.cc
+++ b/content/browser/renderer_host/gesture_event_filter.cc
@@ -8,6 +8,7 @@
#include "base/string_number_conversions.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"
using WebKit::WebGestureEvent;
@@ -55,7 +56,7 @@ static int GetTapDownDeferralTimeMs() {
switches::kTapDownDeferralTimeMs);
return tap_down_deferral_time_window;
}
-} // namespace
+} // namespace
GestureEventFilter::GestureEventFilter(RenderWidgetHostImpl* rwhv)
: render_widget_host_(rwhv),
@@ -63,7 +64,10 @@ GestureEventFilter::GestureEventFilter(RenderWidgetHostImpl* rwhv)
scrolling_in_progress_(false),
ignore_next_ack_(false),
combined_scroll_pinch_(gfx::Transform()),
- tap_suppression_controller_(new TouchpadTapSuppressionController(rwhv)),
+ touchpad_tap_suppression_controller_(
+ new TouchpadTapSuppressionController(rwhv)),
+ touchscreen_tap_suppression_controller_(
+ new TouchscreenTapSuppressionController(this)),
maximum_tap_gap_time_ms_(GetTapDownDeferralTimeMs()),
debounce_interval_time_ms_(kDebouncingIntervalTimeMs) {
}
@@ -88,13 +92,16 @@ bool GestureEventFilter::ShouldDiscardFlingCancelEvent(
bool GestureEventFilter::ShouldForwardForBounceReduction(
const WebGestureEvent& gesture_event) {
+ if (debounce_interval_time_ms_ == 0)
+ return true;
switch (gesture_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);
+ 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();
@@ -121,38 +128,63 @@ bool GestureEventFilter::ShouldForwardForBounceReduction(
// NOTE: The filters are applied successively. This simplifies the change.
bool GestureEventFilter::ShouldForward(const WebGestureEvent& gesture_event) {
- // Discard a zero-velocity fling start from the trackpad.
- if (gesture_event.type == WebInputEvent::GestureFlingStart &&
- gesture_event.sourceDevice == WebGestureEvent::Touchpad &&
- gesture_event.data.flingStart.velocityX == 0 &&
- gesture_event.data.flingStart.velocityY == 0) {
- return false;
- }
+ return ShouldForwardForZeroVelocityFlingStart(gesture_event) &&
+ ShouldForwardForBounceReduction(gesture_event) &&
+ ShouldForwardForGFCFiltering(gesture_event) &&
+ ShouldForwardForTapSuppression(gesture_event) &&
+ ShouldForwardForTapDeferral(gesture_event) &&
+ ShouldForwardForCoalescing(gesture_event);
+}
+
+bool GestureEventFilter::ShouldForwardForZeroVelocityFlingStart(
+ const WebGestureEvent& gesture_event) {
+ return gesture_event.type != WebInputEvent::GestureFlingStart ||
+ gesture_event.sourceDevice != WebGestureEvent::Touchpad ||
+ gesture_event.data.flingStart.velocityX != 0 ||
+ gesture_event.data.flingStart.velocityY != 0;
+}
- if (debounce_interval_time_ms_ == 0 ||
- ShouldForwardForBounceReduction(gesture_event))
- return ShouldForwardForTapDeferral(gesture_event);
+bool GestureEventFilter::ShouldForwardForGFCFiltering(
+ const WebGestureEvent& gesture_event) {
+ return gesture_event.type != WebInputEvent::GestureFlingCancel ||
+ !ShouldDiscardFlingCancelEvent(gesture_event);
+}
+
+bool GestureEventFilter::ShouldForwardForTapSuppression(
+ const WebGestureEvent& gesture_event) {
+ switch (gesture_event.type) {
+ case WebInputEvent::GestureFlingCancel:
+ if (gesture_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:
+ return !touchscreen_tap_suppression_controller_->
+ ShouldSuppressGestureTap();
+ default:
+ return true;
+ }
+ NOTREACHED();
return false;
}
-// TODO(rjkroege): separate touchpad and touchscreen events.
bool GestureEventFilter::ShouldForwardForTapDeferral(
const WebGestureEvent& gesture_event) {
switch (gesture_event.type) {
- case WebInputEvent::GestureFlingCancel:
- if (!ShouldDiscardFlingCancelEvent(gesture_event)) {
- coalesced_gesture_events_.push_back(gesture_event);
- fling_in_progress_ = false;
- tap_suppression_controller_->GestureFlingCancel();
- return ShouldHandleEventNow();
- }
- return false;
case WebInputEvent::GestureTapDown:
// GestureTapDown is always paired with either a Tap, or TapCancel, so it
// should be impossible to have more than one outstanding at a time.
DCHECK_EQ(deferred_tap_down_event_.type, WebInputEvent::Undefined);
deferred_tap_down_event_ = gesture_event;
- send_gtd_timer_.Start(FROM_HERE,
+ send_gtd_timer_.Start(
+ FROM_HERE,
base::TimeDelta::FromMilliseconds(maximum_tap_gap_time_ms_),
this,
&GestureEventFilter::SendGestureTapDownNow);
@@ -161,8 +193,7 @@ bool GestureEventFilter::ShouldForwardForTapDeferral(
if (deferred_tap_down_event_.type == WebInputEvent::Undefined) {
// The TapDown has already been put in the queue, must send the
// corresponding TapCancel as well.
- coalesced_gesture_events_.push_back(gesture_event);
- return ShouldHandleEventNow();
+ return true;
}
// Cancelling a deferred TapDown, just drop them on the floor.
send_gtd_timer_.Stop();
@@ -171,35 +202,42 @@ bool GestureEventFilter::ShouldForwardForTapDeferral(
case WebInputEvent::GestureTap:
send_gtd_timer_.Stop();
if (deferred_tap_down_event_.type != WebInputEvent::Undefined) {
- coalesced_gesture_events_.push_back(deferred_tap_down_event_);
- if (ShouldHandleEventNow())
- render_widget_host_->ForwardGestureEventImmediately(
- deferred_tap_down_event_);
+ ForwardGestureEventSkipDeferral(deferred_tap_down_event_);
deferred_tap_down_event_.type = WebInputEvent::Undefined;
- coalesced_gesture_events_.push_back(gesture_event);
- return false;
}
- coalesced_gesture_events_.push_back(gesture_event);
- return ShouldHandleEventNow();
+ return true;
case WebInputEvent::GestureFlingStart:
- fling_in_progress_ = true;
case WebInputEvent::GestureScrollBegin:
case WebInputEvent::GesturePinchBegin:
send_gtd_timer_.Stop();
deferred_tap_down_event_.type = WebInputEvent::Undefined;
- coalesced_gesture_events_.push_back(gesture_event);
- return ShouldHandleEventNow();
+ return true;
+ default:
+ return true;
+ }
+
+ NOTREACHED();
+ return true;
+}
+
+bool GestureEventFilter::ShouldForwardForCoalescing(
+ const WebGestureEvent& gesture_event) {
+ switch (gesture_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:
- coalesced_gesture_events_.push_back(gesture_event);
- return ShouldHandleEventNow();
+ break;
}
-
- NOTREACHED();
- return false;
+ coalesced_gesture_events_.push_back(gesture_event);
+ return ShouldHandleEventNow();
}
void GestureEventFilter::Reset() {
@@ -221,10 +259,17 @@ void GestureEventFilter::ProcessGestureAck(bool processed, int type) {
return;
}
DCHECK_EQ(coalesced_gesture_events_.front().type, type);
+ if (type == WebInputEvent::GestureFlingCancel) {
+ if (coalesced_gesture_events_.front().sourceDevice ==
+ WebGestureEvent::Touchscreen)
+ touchscreen_tap_suppression_controller_->GestureFlingCancelAck(processed);
+ else
+ touchpad_tap_suppression_controller_->GestureFlingCancelAck(processed);
+ }
coalesced_gesture_events_.pop_front();
- if (type == WebInputEvent::GestureFlingCancel)
- tap_suppression_controller_->GestureFlingCancelAck(processed);
- if (!coalesced_gesture_events_.empty() && !ignore_next_ack_) {
+ if (ignore_next_ack_) {
+ ignore_next_ack_ = false;
+ } else if (!coalesced_gesture_events_.empty()) {
const WebGestureEvent& next_gesture_event =
coalesced_gesture_events_.front();
render_widget_host_->ForwardGestureEventImmediately(next_gesture_event);
@@ -241,13 +286,12 @@ void GestureEventFilter::ProcessGestureAck(bool processed, int type) {
combined_scroll_pinch_ = gfx::Transform();
}
}
- } else if (ignore_next_ack_)
- ignore_next_ack_ = false;
+ }
}
TouchpadTapSuppressionController*
- GestureEventFilter::GetTapSuppressionController() {
- return tap_suppression_controller_.get();
+ GestureEventFilter::GetTouchpadTapSuppressionController() {
+ return touchpad_tap_suppression_controller_.get();
}
bool GestureEventFilter::HasQueuedGestureEvents() const {
@@ -271,16 +315,24 @@ bool GestureEventFilter::ShouldHandleEventNow() {
return coalesced_gesture_events_.size() == 1;
}
+void GestureEventFilter::ForwardGestureEventForDeferral(
+ const WebGestureEvent& gesture_event) {
+ if (ShouldForwardForTapDeferral(gesture_event))
+ ForwardGestureEventSkipDeferral(gesture_event);
+}
+
+void GestureEventFilter::ForwardGestureEventSkipDeferral(
+ const WebGestureEvent& gesture_event) {
+ if (ShouldForwardForCoalescing(gesture_event))
+ render_widget_host_->ForwardGestureEventImmediately(gesture_event);
+}
+
void GestureEventFilter::SendGestureTapDownNow() {
// We must not have already sent the deferred TapDown (if we did, we would
// have stopped the timer, which prevents this task from running - even if
// it's time had already elapsed).
DCHECK_EQ(deferred_tap_down_event_.type, WebInputEvent::GestureTapDown);
- coalesced_gesture_events_.push_back(deferred_tap_down_event_);
- if (ShouldHandleEventNow()) {
- render_widget_host_->ForwardGestureEventImmediately(
- deferred_tap_down_event_);
- }
+ ForwardGestureEventSkipDeferral(deferred_tap_down_event_);
deferred_tap_down_event_.type = WebInputEvent::Undefined;
}
@@ -289,7 +341,10 @@ void GestureEventFilter::SendScrollEndingEventsNow() {
for (GestureEventQueue::iterator it =
debouncing_deferral_queue_.begin();
it != debouncing_deferral_queue_.end(); it++) {
- if (ShouldForwardForTapDeferral(*it)) {
+ if (ShouldForwardForGFCFiltering(*it) &&
+ ShouldForwardForTapSuppression(*it) &&
+ ShouldForwardForTapDeferral(*it) &&
+ ShouldForwardForCoalescing(*it)) {
render_widget_host_->ForwardGestureEventImmediately(*it);
}
}
@@ -303,18 +358,18 @@ void GestureEventFilter::MergeOrInsertScrollAndPinchEvent(
return;
}
WebGestureEvent* last_event = &coalesced_gesture_events_.back();
- if (coalesced_gesture_events_.size() > 1 &&
- gesture_event.type == WebInputEvent::GestureScrollUpdate &&
- last_event->type == WebInputEvent::GestureScrollUpdate &&
- last_event->modifiers == gesture_event.modifiers) {
+ if (gesture_event.type == WebInputEvent::GestureScrollUpdate &&
+ last_event->type == WebInputEvent::GestureScrollUpdate &&
+ last_event->modifiers == gesture_event.modifiers) {
last_event->data.scrollUpdate.deltaX +=
gesture_event.data.scrollUpdate.deltaX;
last_event->data.scrollUpdate.deltaY +=
gesture_event.data.scrollUpdate.deltaY;
return;
- } else if (coalesced_gesture_events_.size() < 3 ||
+ }
+ if (coalesced_gesture_events_.size() == 2 ||
(coalesced_gesture_events_.size() == 3 && ignore_next_ack_) ||
- !ShouldTryMerging(gesture_event,*last_event)) {
+ !ShouldTryMerging(gesture_event, *last_event)) {
coalesced_gesture_events_.push_back(gesture_event);
return;
}
@@ -378,4 +433,4 @@ gfx::Transform GestureEventFilter::GetTransformForEvent(
}
return gesture_transform;
}
-} // namespace content
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698