| Index: content/browser/renderer_host/input/tap_suppression_controller.cc
|
| diff --git a/content/browser/renderer_host/input/tap_suppression_controller.cc b/content/browser/renderer_host/input/tap_suppression_controller.cc
|
| index 78b3a076d6d40b1b0db7f2c18cdb58fbb0c4f55a..008feb237193c41e4fd8d36902d520605ad93b31 100644
|
| --- a/content/browser/renderer_host/input/tap_suppression_controller.cc
|
| +++ b/content/browser/renderer_host/input/tap_suppression_controller.cc
|
| @@ -7,13 +7,27 @@
|
| #include "base/logging.h"
|
| #include "base/trace_event/trace_event.h"
|
| #include "content/browser/renderer_host/input/tap_suppression_controller_client.h"
|
| +#include "ui/events/gesture_detection/gesture_configuration.h"
|
|
|
| namespace content {
|
|
|
| +// The tapDownTimer is used to avoid waiting for an arbitrarily late fling
|
| +// cancel ack. While the timer is running, if a fling cancel ack with
|
| +// |Processed = false| arrives, all stashed gesture events get forwarded. If
|
| +// the timer expires, the controller forwards stashed GestureTapDown only, and
|
| +// drops the rest of the stashed events. The timer delay should be large enough
|
| +// for a GestureLongPress to get stashed and forwarded if needed. It's still
|
| +// possible for a GestureLongPress to arrive after the timer expiration. In
|
| +// this case, it will be suppressed if the controller is in SUPPRESSING_TAPS
|
| +// state.
|
| +
|
| TapSuppressionController::Config::Config()
|
| : enabled(false),
|
| - max_cancel_to_down_time(base::TimeDelta::FromMilliseconds(180)),
|
| - max_tap_gap_time(base::TimeDelta::FromMilliseconds(500)) {
|
| + max_cancel_to_down_time(base::TimeDelta::FromMilliseconds(180)) {
|
| + ui::GestureConfiguration* gesture_config =
|
| + ui::GestureConfiguration::GetInstance();
|
| + max_tap_gap_time = base::TimeDelta::FromMilliseconds(
|
| + gesture_config->long_press_time_in_ms() + 50);
|
| }
|
|
|
| TapSuppressionController::TapSuppressionController(
|
| @@ -34,6 +48,7 @@ void TapSuppressionController::GestureFlingCancel() {
|
| case NOTHING:
|
| case GFC_IN_PROGRESS:
|
| case LAST_CANCEL_STOPPED_FLING:
|
| + case SUPPRESSING_TAPS:
|
| state_ = GFC_IN_PROGRESS;
|
| break;
|
| case TAP_DOWN_STASHED:
|
| @@ -46,6 +61,7 @@ void TapSuppressionController::GestureFlingCancelAck(bool processed) {
|
| switch (state_) {
|
| case DISABLED:
|
| case NOTHING:
|
| + case SUPPRESSING_TAPS:
|
| break;
|
| case GFC_IN_PROGRESS:
|
| if (processed)
|
| @@ -57,7 +73,9 @@ void TapSuppressionController::GestureFlingCancelAck(bool processed) {
|
| TRACE_EVENT0("browser",
|
| "TapSuppressionController::GestureFlingCancelAck");
|
| StopTapDownTimer();
|
| - client_->ForwardStashedTapDown();
|
| + // If the fling cancel is not processed, forward all stashed
|
| + // gesture events.
|
| + client_->ForwardStashedGestureEvents();
|
| state_ = NOTHING;
|
| } // Else waiting for the timer to release the stashed tap down.
|
| break;
|
| @@ -89,6 +107,10 @@ bool TapSuppressionController::ShouldDeferTapDown() {
|
| state_ = NOTHING;
|
| return false;
|
| }
|
| + // Stop suppressing tap end events.
|
| + case SUPPRESSING_TAPS:
|
| + state_ = NOTHING;
|
| + return false;
|
| }
|
| NOTREACHED() << "Invalid state";
|
| return false;
|
| @@ -101,12 +123,17 @@ bool TapSuppressionController::ShouldSuppressTapEnd() {
|
| case GFC_IN_PROGRESS:
|
| return false;
|
| case TAP_DOWN_STASHED:
|
| - state_ = NOTHING;
|
| + // A tap cancel happens before long tap and two finger tap events. To
|
| + // drop the latter events as well as the tap cancel, change the state
|
| + // to "SUPPRESSING_TAPS" when the stashed tap down is dropped.
|
| + state_ = SUPPRESSING_TAPS;
|
| StopTapDownTimer();
|
| client_->DropStashedTapDown();
|
| return true;
|
| case LAST_CANCEL_STOPPED_FLING:
|
| NOTREACHED() << "Invalid tap end on LAST_CANCEL_STOPPED_FLING state";
|
| + case SUPPRESSING_TAPS:
|
| + return true;
|
| }
|
| return false;
|
| }
|
| @@ -128,6 +155,7 @@ void TapSuppressionController::TapDownTimerExpired() {
|
| switch (state_) {
|
| case DISABLED:
|
| case NOTHING:
|
| + case SUPPRESSING_TAPS:
|
| NOTREACHED() << "Timer fired on invalid state.";
|
| break;
|
| case GFC_IN_PROGRESS:
|
| @@ -138,8 +166,10 @@ void TapSuppressionController::TapDownTimerExpired() {
|
| case TAP_DOWN_STASHED:
|
| TRACE_EVENT0("browser",
|
| "TapSuppressionController::TapDownTimerExpired");
|
| + // When the timer expires, only forward the stashed tap down event, and
|
| + // drop other stashed gesture events (show press or long press).
|
| client_->ForwardStashedTapDown();
|
| - state_ = NOTHING;
|
| + state_ = SUPPRESSING_TAPS;
|
| break;
|
| }
|
| }
|
|
|