Bug 775463: Implement tolerance in double tap detection r=cjones

This commit is contained in:
Doug Sherk 2012-08-07 18:51:10 -07:00
parent b53b2122ba
commit 810c6c6743
4 changed files with 38 additions and 8 deletions

View File

@ -24,6 +24,8 @@ using namespace mozilla::css;
namespace mozilla {
namespace layers {
const float AsyncPanZoomController::TOUCH_START_TOLERANCE = 1.0f/16.0f;
static const float EPSILON = 0.0001;
/**
@ -275,8 +277,8 @@ nsEventStatus AsyncPanZoomController::OnTouchMove(const MultiTouchInput& aEvent)
return nsEventStatus_eIgnore;
case TOUCHING: {
float panThreshold = 1.0f/2.0f * mDPI;
UpdateWithTouchAtDevicePoint(aEvent);
float panThreshold = TOUCH_START_TOLERANCE * mDPI;
if (PanDistance() < panThreshold) {
return nsEventStatus_eIgnore;
}
@ -723,6 +725,10 @@ void AsyncPanZoomController::SetDPI(int aDPI) {
mDPI = aDPI;
}
int AsyncPanZoomController::GetDPI() {
return mDPI;
}
void AsyncPanZoomController::ScheduleComposite() {
if (mCompositorParent) {
mCompositorParent->ScheduleRenderOnCompositorThread();

View File

@ -57,6 +57,14 @@ public:
USE_GESTURE_DETECTOR
};
/**
* Constant describing the tolerance in distance we use, multiplied by the
* device DPI, before we start panning the screen. This is to prevent us from
* accidentally processing taps as touch moves, and from very short/accidental
* touches moving the screen.
*/
static const float TOUCH_START_TOLERANCE;
AsyncPanZoomController(GeckoContentController* aController,
GestureBehavior aGestures = DEFAULT_GESTURES);
~AsyncPanZoomController();
@ -179,6 +187,12 @@ public:
*/
void SetDPI(int aDPI);
/**
* Gets the DPI of the device for use outside the panning and zooming logic.
* It defaults to 72 if not set using SetDPI() at any point.
*/
int GetDPI();
protected:
/**
* Helper method for touches beginning. Sets everything up for panning and any

View File

@ -63,6 +63,7 @@ nsEventStatus GestureEventListener::HandleInputEvent(const InputData& aEvent)
size_t length = mTouches.Length();
if (length == 1) {
mTapStartTime = event.mTime;
mTouchStartPosition = event.mTouches[0].mScreenPoint;
if (mState == GESTURE_NONE) {
mState = GESTURE_WAITING_SINGLE_TAP;
}
@ -74,9 +75,14 @@ nsEventStatus GestureEventListener::HandleInputEvent(const InputData& aEvent)
break;
}
case MultiTouchInput::MULTITOUCH_MOVE: {
// If we move at all, just bail out of the tap. We need to change this so
// that there's some tolerance in the future.
HandleTapCancel(event);
// If we move too much, bail out of the tap.
nsIntPoint touch = (nsIntPoint&)event.mTouches[0].mScreenPoint;
if (mTouches.Length() == 1 &&
NS_hypot(mTouchStartPosition.x - touch.x, mTouchStartPosition.y - touch.y) >
mAsyncPanZoomController->GetDPI() * AsyncPanZoomController::TOUCH_START_TOLERANCE)
{
HandleTapCancel(event);
}
bool foundAlreadyExistingTouch = false;
for (size_t i = 0; i < mTouches.Length(); i++) {

View File

@ -1,7 +1,4 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=4 ts=8 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set sw=4 ts=8 et tw=80 : */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_layers_GestureEventListener_h
@ -170,6 +167,13 @@ protected:
* we can cancel it if a double tap actually comes in.
*/
CancelableTask *mDoubleTapTimeoutTask;
/**
* Position of the last touch starting. This is only valid during an attempt
* to determine if a touch is a tap. This means that it is used in both the
* "GESTURE_WAITING_SINGLE_TAP" and "GESTURE_WAITING_DOUBLE_TAP" states.
*/
nsIntPoint mTouchStartPosition;
};
}