Bug 1308627 - Ensure that two-fingered pans scroll the page even if the span between the fingers doesn't change. r=botond a=ritu
authorKartikaya Gupta <kgupta@mozilla.com>
Mon, 10 Oct 2016 19:46:54 -0400
changeset 358273 9a452e8fde0ffd76d25179f5d6165265444a2247
parent 358272 6031d730c46ae3b3db353a8d35c99e82117f6479
child 358274 f591aa1d3916eb87ed14cb78b8c07bdeca8fb1a7
push id1324
push usermtabara@mozilla.com
push dateMon, 16 Jan 2017 13:07:44 +0000
treeherdermozilla-release@a01c49833940 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond, ritu
bugs1308627
milestone51.0a2
Bug 1308627 - Ensure that two-fingered pans scroll the page even if the span between the fingers doesn't change. r=botond a=ritu MozReview-Commit-ID: 5jeqVtoIAO6 --HG-- extra : rebase_source : f332c2a5d3e6d78c60460baf099116f02b8e04e2
gfx/layers/apz/src/GestureEventListener.cpp
gfx/layers/apz/src/GestureEventListener.h
--- 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()
@@ -266,36 +267,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;
     }
 
     float 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;
@@ -475,18 +480,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:
   float mSpanChange;
 
   /**
    * Previous span calculated for the purposes of setting inside a
    * PinchGestureInput.
    */
   float 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