Index: content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java |
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java |
index 5589d358acd542d7b04e3a5bd85200a060d37fe7..e89d4ae9596bd9659420448c56c63d64633e43c0 100644 |
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java |
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewGestureHandler.java |
@@ -189,6 +189,14 @@ class ContentViewGestureHandler implements LongPressDelegate { |
// action after a double tap. |
private long mLastDoubleTapTimeMs; |
+ // Coordinates of the start of a touch sequence offered to native (i.e. the touchdown). |
+ private float mTouchDownToNativeX; |
+ private float mTouchDownToNativeY; |
+ |
+ // True iff a (potential) touchmove offered to native has exceeded the touch slop distance |
+ // OR it had multiple pointers. |
+ private boolean mTouchMoveToNativeConfirmed; |
+ |
static final int GESTURE_SHOW_PRESSED_STATE = 0; |
static final int GESTURE_DOUBLE_TAP = 1; |
static final int GESTURE_SINGLE_TAP_UP = 2; |
@@ -513,8 +521,7 @@ class ContentViewGestureHandler implements LongPressDelegate { |
// Begin double tap drag zoom mode if the move distance is |
// further than the threshold. |
- if (distanceX * distanceX + distanceY * distanceY > |
- mScaledTouchSlopSquare) { |
+ if (isDistanceGreaterThanTouchSlop(distanceX, distanceY)) { |
sendTapCancelIfNecessary(e); |
mExtraParamBundleScrollStart.putInt(DELTA_HINT_X, |
(int) -distanceX); |
@@ -587,9 +594,7 @@ class ContentViewGestureHandler implements LongPressDelegate { |
* @return true if the distance is too long to be considered a single tap |
*/ |
private boolean isDistanceBetweenDownAndUpTooLong(float x, float y) { |
- double deltaX = mLastRawX - x; |
- double deltaY = mLastRawY - y; |
- return deltaX * deltaX + deltaY * deltaY > mScaledTouchSlopSquare; |
+ return isDistanceGreaterThanTouchSlop(mLastRawX - x, mLastRawY - y); |
} |
}; |
mListener = listener; |
@@ -847,6 +852,8 @@ class ContentViewGestureHandler implements LongPressDelegate { |
mZoomManager.processTouchEvent(me); |
me.recycle(); |
mLongPressDetector.cancelLongPress(); |
+ if (mCurrentDownEvent != null) recycleEvent(mCurrentDownEvent); |
+ mCurrentDownEvent = null; |
} |
/** |
@@ -927,21 +934,29 @@ class ContentViewGestureHandler implements LongPressDelegate { |
// should always be offered to Javascript (when there is any touch handler). |
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { |
mTouchHandlingState = HAS_TOUCH_HANDLER; |
- if (mCurrentDownEvent != null) recycleEvent(mCurrentDownEvent); |
- mCurrentDownEvent = null; |
+ mTouchMoveToNativeConfirmed = false; |
+ mTouchDownToNativeX = event.getX(); |
+ mTouchDownToNativeY = event.getY(); |
} |
- mLongPressDetector.onOfferTouchEventToJavaScript(event); |
- |
if (mTouchHandlingState == NO_TOUCH_HANDLER_FOR_GESTURE) return EVENT_NOT_FORWARDED; |
if (event.getActionMasked() == MotionEvent.ACTION_MOVE) { |
- // If javascript has not yet prevent-defaulted the touch sequence, |
- // only send move events if the move has exceeded the slop threshold. |
- boolean moveEventConfirmed = |
- mLongPressDetector.confirmOfferMoveEventToJavaScript(event); |
+ if (!mTouchMoveToNativeConfirmed) { |
+ if (event.getPointerCount() > 1) { |
+ mTouchMoveToNativeConfirmed = true; |
+ } else { |
+ final float distanceX = event.getX() - mTouchDownToNativeX; |
+ final float distanceY = event.getY() - mTouchDownToNativeY; |
+ if (isDistanceGreaterThanTouchSlop(distanceX, distanceY)) { |
+ mTouchMoveToNativeConfirmed = true; |
+ } |
+ } |
+ } |
+ // If javascript has not yet prevent-defaulted the touch sequence, only send move events |
+ // if the move has exceeded the slop threshold OR there are multiple pointers. |
if (mTouchHandlingState != JAVASCRIPT_CONSUMING_GESTURE |
- && !moveEventConfirmed) { |
+ && !mTouchMoveToNativeConfirmed) { |
return EVENT_DROPPED; |
} |
} |
@@ -958,27 +973,14 @@ class ContentViewGestureHandler implements LongPressDelegate { |
} |
private boolean processTouchEvent(MotionEvent event) { |
- boolean handled = false; |
- // The last "finger up" is an end to scrolling but may not be |
- // an end to movement (e.g. fling scroll). We do not tell |
- // native code to end scrolling until we are sure we did not |
- // fling. |
- boolean possiblyEndMovement = false; |
- // "Last finger raised" could be an end to movement. However, |
- // give the mSimpleTouchDetector a chance to continue |
- // scrolling with a fling. |
- if (event.getAction() == MotionEvent.ACTION_UP |
- || event.getAction() == MotionEvent.ACTION_CANCEL) { |
- if (mTouchScrolling) { |
- possiblyEndMovement = true; |
- } |
- } |
+ final boolean wasTouchScrolling = mTouchScrolling; |
mLongPressDetector.cancelLongPressIfNeeded(event); |
mLongPressDetector.startLongPressTimerIfNeeded(event); |
// Use the framework's GestureDetector to detect pans and zooms not already |
// handled by the WebKit touch events gesture manager. |
+ boolean handled = false; |
if (canHandle(event)) { |
handled |= mGestureDetector.onTouchEvent(event); |
if (event.getAction() == MotionEvent.ACTION_DOWN) { |
@@ -988,8 +990,16 @@ class ContentViewGestureHandler implements LongPressDelegate { |
handled |= mZoomManager.processTouchEvent(event); |
- if (possiblyEndMovement && !handled) { |
- endTouchScrollIfNecessary(event.getEventTime(), true); |
+ if (event.getAction() == MotionEvent.ACTION_UP |
+ || event.getAction() == MotionEvent.ACTION_CANCEL) { |
+ if (mCurrentDownEvent != null) recycleEvent(mCurrentDownEvent); |
+ mCurrentDownEvent = null; |
+ |
+ // "Last finger raised" could be an end to movement, but it should |
+ // only terminate scrolling if the event did not cause a fling. |
+ if (wasTouchScrolling && !handled) { |
+ endTouchScrollIfNecessary(event.getEventTime(), true); |
+ } |
} |
return handled; |
@@ -1230,7 +1240,6 @@ class ContentViewGestureHandler implements LongPressDelegate { |
} else { |
mGestureDetector.setOnDoubleTapListener(mDoubleTapListener); |
} |
- |
} |
private void reportDoubleTap() { |
@@ -1274,4 +1283,8 @@ class ContentViewGestureHandler implements LongPressDelegate { |
mLastDoubleTapTimeMs = 0; |
} |
} |
+ |
+ private boolean isDistanceGreaterThanTouchSlop(float distanceX, float distanceY) { |
+ return distanceX * distanceX + distanceY * distanceY > mScaledTouchSlopSquare; |
+ } |
} |