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

Unified Diff: ui/events/gesture_detection/gesture_detector.cc

Issue 1358263002: [Android] Support double-tap selection (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix contextual search Created 5 years, 3 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
« no previous file with comments | « ui/events/gesture_detection/gesture_detector.h ('k') | ui/events/gesture_detection/gesture_listeners.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/events/gesture_detection/gesture_detector.cc
diff --git a/ui/events/gesture_detection/gesture_detector.cc b/ui/events/gesture_detection/gesture_detector.cc
index 7ea0a3e0c7204a1ac259a46647e9067871df6030..ec5e5ae86884fd8f70e6b98244d1eabda553affa 100644
--- a/ui/events/gesture_detection/gesture_detector.cc
+++ b/ui/events/gesture_detection/gesture_detector.cc
@@ -55,8 +55,8 @@ GestureDetector::Config::Config()
two_finger_tap_enabled(false),
two_finger_tap_max_separation(300),
two_finger_tap_timeout(base::TimeDelta::FromMilliseconds(700)),
- velocity_tracker_strategy(VelocityTracker::Strategy::STRATEGY_DEFAULT) {
-}
+ single_tap_repeat_interval(1),
+ velocity_tracker_strategy(VelocityTracker::Strategy::STRATEGY_DEFAULT) {}
GestureDetector::Config::~Config() {}
@@ -129,6 +129,9 @@ GestureDetector::GestureDetector(
always_in_bigger_tap_region_(false),
two_finger_tap_allowed_for_gesture_(false),
is_double_tapping_(false),
+ is_down_candidate_for_repeated_single_tap_(false),
+ current_single_tap_repeat_count_(0),
+ single_tap_repeat_interval_(1),
last_focus_x_(0),
last_focus_y_(0),
down_focus_x_(0),
@@ -234,14 +237,16 @@ bool GestureDetector::OnTouchEvent(const MotionEvent& ev) {
two_finger_tap_allowed_for_gesture_ = false;
} break;
- case MotionEvent::ACTION_DOWN:
+ case MotionEvent::ACTION_DOWN: {
+ bool is_repeated_tap =
+ current_down_event_ && previous_up_event_ &&
+ IsRepeatedTap(*current_down_event_, *previous_up_event_, ev);
if (double_tap_listener_) {
+ is_down_candidate_for_repeated_single_tap_ = false;
bool had_tap_message = timeout_handler_->HasTimeout(TAP);
if (had_tap_message)
timeout_handler_->StopTimeout(TAP);
- if (current_down_event_ && previous_up_event_ && had_tap_message &&
- IsConsideredDoubleTap(
- *current_down_event_, *previous_up_event_, ev)) {
+ if (is_repeated_tap && had_tap_message) {
// This is a second tap.
is_double_tapping_ = true;
// Give a callback with the first tap of the double-tap.
@@ -253,6 +258,8 @@ bool GestureDetector::OnTouchEvent(const MotionEvent& ev) {
DCHECK(double_tap_timeout_ > base::TimeDelta());
timeout_handler_->StartTimeout(TAP);
}
+ } else {
+ is_down_candidate_for_repeated_single_tap_ = is_repeated_tap;
}
down_focus_x_ = last_focus_x_ = focus_x;
@@ -273,7 +280,7 @@ bool GestureDetector::OnTouchEvent(const MotionEvent& ev) {
if (longpress_enabled_)
timeout_handler_->StartTimeout(LONG_PRESS);
handled |= listener_->OnDown(ev);
- break;
+ } break;
case MotionEvent::ACTION_MOVE:
{
@@ -343,12 +350,20 @@ bool GestureDetector::OnTouchEvent(const MotionEvent& ev) {
DCHECK(double_tap_listener_);
handled |= double_tap_listener_->OnDoubleTapEvent(ev);
} else if (always_in_tap_region_) {
- handled = listener_->OnSingleTapUp(ev);
+ if (is_down_candidate_for_repeated_single_tap_) {
+ current_single_tap_repeat_count_ =
+ (1 + current_single_tap_repeat_count_) %
+ single_tap_repeat_interval_;
+ } else {
+ current_single_tap_repeat_count_ = 0;
+ }
+ handled = listener_->OnSingleTapUp(
+ ev, 1 + current_single_tap_repeat_count_);
if (defer_confirm_single_tap_ && double_tap_listener_ != NULL) {
double_tap_listener_->OnSingleTapConfirmed(ev);
}
} else {
-
+ current_single_tap_repeat_count_ = 0;
// A fling must travel the minimum tap distance.
const int pointer_id = ev.GetPointerId(0);
velocity_tracker_.ComputeCurrentVelocity(1000, max_fling_velocity_);
@@ -428,6 +443,9 @@ void GestureDetector::Init(const Config& config) {
two_finger_tap_distance_square_ = config.two_finger_tap_max_separation *
config.two_finger_tap_max_separation;
two_finger_tap_timeout_ = config.two_finger_tap_timeout;
+
+ DCHECK_GE(config.single_tap_repeat_interval, 1);
+ single_tap_repeat_interval_ = config.single_tap_repeat_interval;
}
void GestureDetector::OnShowPressTimeout() {
@@ -463,18 +481,25 @@ void GestureDetector::CancelTaps() {
always_in_tap_region_ = false;
always_in_bigger_tap_region_ = false;
defer_confirm_single_tap_ = false;
+ is_down_candidate_for_repeated_single_tap_ = false;
+ current_single_tap_repeat_count_ = 0;
}
-bool GestureDetector::IsConsideredDoubleTap(
- const MotionEvent& first_down,
- const MotionEvent& first_up,
- const MotionEvent& second_down) const {
+bool GestureDetector::IsRepeatedTap(const MotionEvent& first_down,
+ const MotionEvent& first_up,
+ const MotionEvent& second_down) const {
if (!always_in_bigger_tap_region_)
return false;
const base::TimeDelta delta_time =
second_down.GetEventTime() - first_up.GetEventTime();
- if (delta_time < double_tap_min_time_ || delta_time > double_tap_timeout_)
+ if (delta_time > double_tap_timeout_)
+ return false;
+
+ // Only use the min time when in double-tap detection mode. For repeated
+ // single taps the risk of accidental repeat detection (e.g., from fingernail
+ // interference) is minimal.
+ if (double_tap_listener_ && delta_time < double_tap_min_time_)
return false;
const float delta_x = first_down.GetX() - second_down.GetX();
« no previous file with comments | « ui/events/gesture_detection/gesture_detector.h ('k') | ui/events/gesture_detection/gesture_listeners.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698