diff --git a/gfx/layers/ipc/AsyncPanZoomController.cpp b/gfx/layers/ipc/AsyncPanZoomController.cpp index 6d5c3fd40215..f927c949e31d 100644 --- a/gfx/layers/ipc/AsyncPanZoomController.cpp +++ b/gfx/layers/ipc/AsyncPanZoomController.cpp @@ -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(); diff --git a/gfx/layers/ipc/AsyncPanZoomController.h b/gfx/layers/ipc/AsyncPanZoomController.h index efe65c4e4d49..f8b4ea4953c6 100644 --- a/gfx/layers/ipc/AsyncPanZoomController.h +++ b/gfx/layers/ipc/AsyncPanZoomController.h @@ -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 diff --git a/gfx/layers/ipc/GestureEventListener.cpp b/gfx/layers/ipc/GestureEventListener.cpp index e3a338934222..3bc50b1f51e8 100644 --- a/gfx/layers/ipc/GestureEventListener.cpp +++ b/gfx/layers/ipc/GestureEventListener.cpp @@ -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++) { diff --git a/gfx/layers/ipc/GestureEventListener.h b/gfx/layers/ipc/GestureEventListener.h index e715e2020760..f1fced0f046d 100644 --- a/gfx/layers/ipc/GestureEventListener.h +++ b/gfx/layers/ipc/GestureEventListener.h @@ -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; }; }