Bug 1308627 - Ensure that two-fingered pans scroll the page even if the span between the fingers doesn't change. r?botond
MozReview-Commit-ID: 5jeqVtoIAO6
--- a/gfx/layers/apz/src/GestureEventListener.cpp
+++ b/gfx/layers/apz/src/GestureEventListener.cpp
@@ -23,20 +23,20 @@ namespace layers {
/**
* Maximum time for a touch on the screen and corresponding lift of the finger
* to be considered a tap. This also applies to double taps, except that it is
* used twice.
*/
static const uint32_t MAX_TAP_TIME = 300;
/**
- * Amount of change in span needed to take us from the GESTURE_WAITING_PINCH
- * state to the GESTURE_PINCH state. This is measured as a change in distance
- * between the fingers used to compute the span ratio. Note that it is a
- * distance, not a displacement.
+ * Amount of span or focus change needed to take us from the GESTURE_WAITING_PINCH
+ * state to the GESTURE_PINCH state. This is measured as either a change in distance
+ * between the fingers used to compute the span ratio, or the a change in
+ * position of the focus point between the two fingers.
*/
static const float PINCH_START_THRESHOLD = 35.0f;
static bool sLongTapEnabled = true;
ParentLayerPoint GetCurrentFocus(const MultiTouchInput& aEvent)
{
const ParentLayerPoint& firstTouch = aEvent.mTouches[0].mLocalScreenPoint;
@@ -61,16 +61,17 @@ TapGestureInput CreateTapEvent(const Mul
aTouch.modifiers);
}
GestureEventListener::GestureEventListener(AsyncPanZoomController* aAsyncPanZoomController)
: mAsyncPanZoomController(aAsyncPanZoomController),
mState(GESTURE_NONE),
mSpanChange(0.0f),
mPreviousSpan(0.0f),
+ mFocusChange(0.0f),
mLastTouchInput(MultiTouchInput::MULTITOUCH_START, 0, TimeStamp(), 0),
mLastTapInput(MultiTouchInput::MULTITOUCH_START, 0, TimeStamp(), 0),
mLongTapTimeoutTask(nullptr),
mMaxTapTimeoutTask(nullptr)
{
}
GestureEventListener::~GestureEventListener()
@@ -265,36 +266,40 @@ nsEventStatus GestureEventListener::Hand
case GESTURE_MULTI_TOUCH_DOWN: {
if (mLastTouchInput.mTouches.Length() < 2) {
NS_WARNING("Wrong input: less than 2 moving points in GESTURE_MULTI_TOUCH_DOWN state");
break;
}
ParentLayerCoord currentSpan = GetCurrentSpan(mLastTouchInput);
+ ParentLayerPoint currentFocus = GetCurrentFocus(mLastTouchInput);
mSpanChange += fabsf(currentSpan - mPreviousSpan);
- if (mSpanChange > PINCH_START_THRESHOLD) {
+ mFocusChange += (currentFocus - mPreviousFocus).Length();
+ if (mSpanChange > PINCH_START_THRESHOLD ||
+ mFocusChange > PINCH_START_THRESHOLD) {
SetState(GESTURE_PINCH);
PinchGestureInput pinchEvent(PinchGestureInput::PINCHGESTURE_START,
mLastTouchInput.mTime,
mLastTouchInput.mTimeStamp,
- GetCurrentFocus(mLastTouchInput),
+ currentFocus,
currentSpan,
currentSpan,
mLastTouchInput.modifiers);
rv = mAsyncPanZoomController->HandleGestureEvent(pinchEvent);
} else {
// Prevent APZC::OnTouchMove from processing a move event when two
// touches are active
rv = nsEventStatus_eConsumeNoDefault;
}
mPreviousSpan = currentSpan;
+ mPreviousFocus = currentFocus;
break;
}
case GESTURE_PINCH: {
if (mLastTouchInput.mTouches.Length() < 2) {
NS_WARNING("Wrong input: less than 2 moving points in GESTURE_PINCH state");
// Prevent APZC::OnTouchMove() from handling this wrong input
rv = nsEventStatus_eConsumeNoDefault;
@@ -477,18 +482,20 @@ void GestureEventListener::TriggerSingle
void GestureEventListener::SetState(GestureState aState)
{
mState = aState;
if (mState == GESTURE_NONE) {
mSpanChange = 0.0f;
mPreviousSpan = 0.0f;
+ mFocusChange = 0.0f;
} else if (mState == GESTURE_MULTI_TOUCH_DOWN) {
mPreviousSpan = GetCurrentSpan(mLastTouchInput);
+ mPreviousFocus = GetCurrentFocus(mLastTouchInput);
}
}
void GestureEventListener::CancelLongTapTimeoutTask()
{
if (mState == GESTURE_SECOND_SINGLE_TOUCH_DOWN) {
// being in this state means the task has been canceled already
return;
--- a/gfx/layers/apz/src/GestureEventListener.h
+++ b/gfx/layers/apz/src/GestureEventListener.h
@@ -174,16 +174,20 @@ private:
ParentLayerCoord mSpanChange;
/**
* Previous span calculated for the purposes of setting inside a
* PinchGestureInput.
*/
ParentLayerCoord mPreviousSpan;
+ /* Properties similar to mSpanChange and mPreviousSpan, but for the focus */
+ ParentLayerCoord mFocusChange;
+ ParentLayerPoint mPreviousFocus;
+
/**
* Cached copy of the last touch input.
*/
MultiTouchInput mLastTouchInput;
/**
* Cached copy of the last tap gesture input.
* In the situation when we have a tap followed by a pinch we lose info