7070import android .util .EventLog ;
7171import android .util .Log ;
7272import android .view .Display ;
73- import android .view .GestureDetector ;
74- import android .view .GestureDetector .SimpleOnGestureListener ;
7573import android .view .Gravity ;
7674import android .view .HapticFeedbackConstants ;
7775import android .view .HardwareCanvas ;
@@ -801,51 +799,6 @@ protected void measureContent() {
801799 }
802800 }
803801
804- private class TextScrollListener extends SimpleOnGestureListener {
805- @ Override
806- public boolean onFling (MotionEvent e1 , MotionEvent e2 ,
807- float velocityX , float velocityY ) {
808- int maxScrollX = mEditTextContent .width () -
809- mEditTextBounds .width ();
810- int maxScrollY = mEditTextContent .height () -
811- mEditTextBounds .height ();
812-
813- int contentVelocityX = viewToContentDimension ((int )-velocityX );
814- int contentVelocityY = viewToContentDimension ((int )-velocityY );
815- mEditTextScroller .fling (-mEditTextContent .left ,
816- -mEditTextContent .top ,
817- contentVelocityX , contentVelocityY ,
818- 0 , maxScrollX , 0 , maxScrollY );
819- return true ;
820- }
821-
822- @ Override
823- public boolean onScroll (MotionEvent e1 , MotionEvent e2 ,
824- float distanceX , float distanceY ) {
825- // Scrollable edit text. Scroll it.
826- int newScrollX = deltaToTextScroll (
827- -mEditTextContent .left , mEditTextContent .width (),
828- mEditTextBounds .width (),
829- (int ) distanceX );
830- int newScrollY = deltaToTextScroll (
831- -mEditTextContent .top , mEditTextContent .height (),
832- mEditTextBounds .height (),
833- (int ) distanceY );
834- scrollEditText (newScrollX , newScrollY );
835- return true ;
836- }
837-
838- private int deltaToTextScroll (int oldScroll , int contentSize ,
839- int boundsSize , int delta ) {
840- int newScroll = oldScroll +
841- viewToContentDimension (delta );
842- int maxScroll = contentSize - boundsSize ;
843- newScroll = Math .min (maxScroll , newScroll );
844- newScroll = Math .max (0 , newScroll );
845- return newScroll ;
846- }
847- }
848-
849802 // The listener to capture global layout change event.
850803 private InnerGlobalLayoutListener mGlobalLayoutListener = null ;
851804
@@ -874,7 +827,6 @@ private int deltaToTextScroll(int oldScroll, int contentSize,
874827 private int mFieldPointer ;
875828 private PastePopupWindow mPasteWindow ;
876829 private AutoCompletePopup mAutoCompletePopup ;
877- private GestureDetector mGestureDetector ;
878830 Rect mEditTextBounds = new Rect ();
879831 Rect mEditTextContent = new Rect ();
880832 int mEditTextLayerId ;
@@ -1016,6 +968,7 @@ public void onTrimMemory(int level) {
1016968 private static final int TOUCH_DONE_MODE = 7 ;
1017969 private static final int TOUCH_PINCH_DRAG = 8 ;
1018970 private static final int TOUCH_DRAG_LAYER_MODE = 9 ;
971+ private static final int TOUCH_DRAG_TEXT_MODE = 10 ;
1019972
1020973 // Whether to forward the touch events to WebCore
1021974 // Can only be set by WebKit via JNI.
@@ -1493,7 +1446,6 @@ public void init(Map<String, Object> javaScriptInterfaces, boolean privateBrowsi
14931446 }
14941447
14951448 mAutoFillData = new WebViewCore .AutoFillData ();
1496- mGestureDetector = new GestureDetector (mContext , new TextScrollListener ());
14971449 mEditTextScroller = new Scroller (context );
14981450 }
14991451
@@ -3383,6 +3335,10 @@ public void onOverScrolled(int scrollX, int scrollY, boolean clampedX,
33833335 boolean clampedY ) {
33843336 // Special-case layer scrolling so that we do not trigger normal scroll
33853337 // updating.
3338+ if (mTouchMode == TOUCH_DRAG_TEXT_MODE ) {
3339+ scrollEditText (scrollX , scrollY );
3340+ return ;
3341+ }
33863342 if (mTouchMode == TOUCH_DRAG_LAYER_MODE ) {
33873343 scrollLayerTo (scrollX , scrollY );
33883344 return ;
@@ -3855,6 +3811,12 @@ public void computeScroll() {
38553811 rangeY = mScrollingLayerRect .bottom ;
38563812 // No overscrolling for layers.
38573813 overflingDistance = 0 ;
3814+ } else if (mTouchMode == TOUCH_DRAG_TEXT_MODE ) {
3815+ oldX = getTextScrollX ();
3816+ oldY = getTextScrollY ();
3817+ rangeX = getMaxTextScrollX ();
3818+ rangeY = getMaxTextScrollY ();
3819+ overflingDistance = 0 ;
38583820 }
38593821
38603822 mWebViewPrivate .overScrollBy (x - oldX , y - oldY , oldX , oldY ,
@@ -3865,12 +3827,14 @@ public void computeScroll() {
38653827 mOverScrollGlow .absorbGlow (x , y , oldX , oldY , rangeX , rangeY );
38663828 }
38673829 } else {
3868- if (mTouchMode != TOUCH_DRAG_LAYER_MODE ) {
3869- setScrollXRaw (x );
3870- setScrollYRaw (y );
3871- } else {
3830+ if (mTouchMode == TOUCH_DRAG_LAYER_MODE ) {
38723831 // Update the layer position instead of WebView.
38733832 scrollLayerTo (x , y );
3833+ } else if (mTouchMode == TOUCH_DRAG_TEXT_MODE ) {
3834+ scrollEditText (x , y );
3835+ } else {
3836+ setScrollXRaw (x );
3837+ setScrollYRaw (y );
38743838 }
38753839 abortAnimation ();
38763840 nativeSetIsScrolling (false );
@@ -6156,7 +6120,6 @@ public void run() {
61566120 startTouch (x , y , eventTime );
61576121 if (mIsEditingText ) {
61586122 mTouchInEditText = mEditTextBounds .contains (contentX , contentY );
6159- mGestureDetector .onTouchEvent (ev );
61606123 }
61616124 break ;
61626125 }
@@ -6189,13 +6152,6 @@ public void run() {
61896152 invalidate ();
61906153 }
61916154 break ;
6192- } else if (mConfirmMove && mTouchInEditText ) {
6193- ViewParent parent = mWebView .getParent ();
6194- if (parent != null ) {
6195- parent .requestDisallowInterceptTouchEvent (true );
6196- }
6197- mGestureDetector .onTouchEvent (ev );
6198- break ;
61996155 }
62006156
62016157 // pass the touch events from UI thread to WebCore thread
@@ -6243,7 +6199,8 @@ public void run() {
62436199 }
62446200
62456201 if (mTouchMode != TOUCH_DRAG_MODE &&
6246- mTouchMode != TOUCH_DRAG_LAYER_MODE ) {
6202+ mTouchMode != TOUCH_DRAG_LAYER_MODE &&
6203+ mTouchMode != TOUCH_DRAG_TEXT_MODE ) {
62476204
62486205 if (!mConfirmMove ) {
62496206 break ;
@@ -6326,9 +6283,6 @@ public void run() {
63266283 deltaX = 0 ;
63276284 }
63286285 }
6329- mLastTouchX = x ;
6330- mLastTouchY = y ;
6331-
63326286 if (deltaX * deltaX + deltaY * deltaY > mTouchSlopSquare ) {
63336287 mHeldMotionless = MOTIONLESS_FALSE ;
63346288 nativeSetIsScrolling (true );
@@ -6339,13 +6293,24 @@ public void run() {
63396293 }
63406294
63416295 mLastTouchTime = eventTime ;
6296+ boolean allDrag = doDrag (deltaX , deltaY );
6297+ if (allDrag ) {
6298+ mLastTouchX = x ;
6299+ mLastTouchY = y ;
6300+ } else {
6301+ int contentDeltaX = (int )Math .floor (deltaX * mZoomManager .getInvScale ());
6302+ int roundedDeltaX = contentToViewDimension (contentDeltaX );
6303+ int contentDeltaY = (int )Math .floor (deltaY * mZoomManager .getInvScale ());
6304+ int roundedDeltaY = contentToViewDimension (contentDeltaY );
6305+ mLastTouchX -= roundedDeltaX ;
6306+ mLastTouchY -= roundedDeltaY ;
6307+ }
63426308 }
63436309
6344- doDrag (deltaX , deltaY );
6345-
63466310 // Turn off scrollbars when dragging a layer.
63476311 if (keepScrollBarsVisible &&
6348- mTouchMode != TOUCH_DRAG_LAYER_MODE ) {
6312+ mTouchMode != TOUCH_DRAG_LAYER_MODE &&
6313+ mTouchMode != TOUCH_DRAG_TEXT_MODE ) {
63496314 if (mHeldMotionless != MOTIONLESS_TRUE ) {
63506315 mHeldMotionless = MOTIONLESS_TRUE ;
63516316 invalidate ();
@@ -6366,11 +6331,6 @@ public void run() {
63666331 break ;
63676332 }
63686333 case MotionEvent .ACTION_UP : {
6369- mGestureDetector .onTouchEvent (ev );
6370- if (mTouchInEditText && mConfirmMove ) {
6371- stopTouch ();
6372- break ; // We've been scrolling the edit text.
6373- }
63746334 if (!mConfirmMove && mIsEditingText && mSelectionStarted &&
63756335 mIsCaretSelection ) {
63766336 showPasteWindow ();
@@ -6484,6 +6444,7 @@ public void run() {
64846444 }
64856445 case TOUCH_DRAG_MODE :
64866446 case TOUCH_DRAG_LAYER_MODE :
6447+ case TOUCH_DRAG_TEXT_MODE :
64876448 mPrivateHandler .removeMessages (DRAG_HELD_MOTIONLESS );
64886449 mPrivateHandler .removeMessages (AWAKEN_SCROLL_BARS );
64896450 // if the user waits a while w/o moving before the
@@ -6680,20 +6641,31 @@ private void startDrag() {
66806641 }
66816642 }
66826643
6683- private void doDrag (int deltaX , int deltaY ) {
6644+ private boolean doDrag (int deltaX , int deltaY ) {
6645+ boolean allDrag = true ;
66846646 if ((deltaX | deltaY ) != 0 ) {
66856647 int oldX = getScrollX ();
66866648 int oldY = getScrollY ();
66876649 int rangeX = computeMaxScrollX ();
66886650 int rangeY = computeMaxScrollY ();
6689- // Check for the original scrolling layer in case we change
6690- // directions. mTouchMode might be TOUCH_DRAG_MODE if we have
6691- // reached the edge of a layer but mScrollingLayer will be non-zero
6692- // if we initiated the drag on a layer.
6693- if (mCurrentScrollingLayerId != 0 ) {
6694- final int contentX = viewToContentDimension (deltaX );
6695- final int contentY = viewToContentDimension (deltaY );
6696-
6651+ final int contentX = (int )Math .floor (deltaX * mZoomManager .getInvScale ());
6652+ final int contentY = (int )Math .floor (deltaY * mZoomManager .getInvScale ());
6653+
6654+ // Assume page scrolling and change below if we're wrong
6655+ mTouchMode = TOUCH_DRAG_MODE ;
6656+
6657+ // Check special scrolling before going to main page scrolling.
6658+ if (mIsEditingText && mTouchInEditText && canTextScroll (deltaX , deltaY )) {
6659+ // Edit text scrolling
6660+ oldX = getTextScrollX ();
6661+ rangeX = getMaxTextScrollX ();
6662+ deltaX = contentX ;
6663+ oldY = getTextScrollY ();
6664+ rangeY = getMaxTextScrollY ();
6665+ deltaY = contentY ;
6666+ mTouchMode = TOUCH_DRAG_TEXT_MODE ;
6667+ allDrag = false ;
6668+ } else if (mCurrentScrollingLayerId != 0 ) {
66976669 // Check the scrolling bounds to see if we will actually do any
66986670 // scrolling. The rectangle is in document coordinates.
66996671 final int maxX = mScrollingLayerRect .right ;
@@ -6713,12 +6685,7 @@ private void doDrag(int deltaX, int deltaY) {
67136685 oldY = mScrollingLayerRect .top ;
67146686 rangeX = maxX ;
67156687 rangeY = maxY ;
6716- } else {
6717- // Scroll the main page if we are not going to scroll the
6718- // layer. This does not reset mScrollingLayer in case the
6719- // user changes directions and the layer can scroll the
6720- // other way.
6721- mTouchMode = TOUCH_DRAG_MODE ;
6688+ allDrag = false ;
67226689 }
67236690 }
67246691
@@ -6734,11 +6701,13 @@ private void doDrag(int deltaX, int deltaY) {
67346701 }
67356702 }
67366703 mZoomManager .keepZoomPickerVisible ();
6704+ return allDrag ;
67376705 }
67386706
67396707 private void stopTouch () {
67406708 if (mScroller .isFinished () && !mSelectingText
6741- && (mTouchMode == TOUCH_DRAG_MODE || mTouchMode == TOUCH_DRAG_LAYER_MODE )) {
6709+ && (mTouchMode == TOUCH_DRAG_MODE
6710+ || mTouchMode == TOUCH_DRAG_LAYER_MODE )) {
67426711 WebViewCore .resumePriority ();
67436712 WebViewCore .resumeUpdatePicture (mWebViewCore );
67446713 nativeSetIsScrolling (false );
@@ -7132,6 +7101,13 @@ private void doFling() {
71327101 maxY = mScrollingLayerRect .bottom ;
71337102 // No overscrolling for layers.
71347103 overscrollDistance = overflingDistance = 0 ;
7104+ } else if (mTouchMode == TOUCH_DRAG_TEXT_MODE ) {
7105+ scrollX = getTextScrollX ();
7106+ scrollY = getTextScrollY ();
7107+ maxX = getMaxTextScrollX ();
7108+ maxY = getMaxTextScrollY ();
7109+ // No overscrolling for edit text.
7110+ overscrollDistance = overflingDistance = 0 ;
71357111 }
71367112
71377113 if (mSnapScrollMode != SNAP_NONE ) {
@@ -7211,7 +7187,7 @@ private void doFling() {
72117187 final int time = mScroller .getDuration ();
72127188
72137189 // Suppress scrollbars for layer scrolling.
7214- if (mTouchMode != TOUCH_DRAG_LAYER_MODE ) {
7190+ if (mTouchMode != TOUCH_DRAG_LAYER_MODE && mTouchMode != TOUCH_DRAG_TEXT_MODE ) {
72157191 mWebViewPrivate .awakenScrollBars (time );
72167192 }
72177193
@@ -7569,6 +7545,36 @@ public synchronized WebViewCore getWebViewCore() {
75697545 return mWebViewCore ;
75707546 }
75717547
7548+ private boolean canTextScroll (int directionX , int directionY ) {
7549+ int scrollX = getTextScrollX ();
7550+ int scrollY = getTextScrollY ();
7551+ int maxScrollX = getMaxTextScrollX ();
7552+ int maxScrollY = getMaxTextScrollY ();
7553+ boolean canScrollX = (directionX > 0 )
7554+ ? (scrollX < maxScrollX )
7555+ : (scrollX > 0 );
7556+ boolean canScrollY = (directionY > 0 )
7557+ ? (scrollY < maxScrollY )
7558+ : (scrollY > 0 );
7559+ return canScrollX || canScrollY ;
7560+ }
7561+
7562+ private int getTextScrollX () {
7563+ return -mEditTextContent .left ;
7564+ }
7565+
7566+ private int getTextScrollY () {
7567+ return -mEditTextContent .top ;
7568+ }
7569+
7570+ private int getMaxTextScrollX () {
7571+ return Math .max (0 , mEditTextContent .width () - mEditTextBounds .width ());
7572+ }
7573+
7574+ private int getMaxTextScrollY () {
7575+ return Math .max (0 , mEditTextContent .height () - mEditTextBounds .height ());
7576+ }
7577+
75727578 /**
75737579 * Used only by TouchEventQueue to store pending touch events.
75747580 */
@@ -8888,8 +8894,7 @@ private void computeEditTextScroll() {
88888894
88898895 private void scrollEditText (int scrollX , int scrollY ) {
88908896 // Scrollable edit text. Scroll it.
8891- float maxScrollX = (float )(mEditTextContent .width () -
8892- mEditTextBounds .width ());
8897+ float maxScrollX = getMaxTextScrollX ();
88938898 float scrollPercentX = ((float )scrollX )/maxScrollX ;
88948899 mEditTextContent .offsetTo (-scrollX , -scrollY );
88958900 mWebViewCore .sendMessageAtFrontOfQueue (EventHub .SCROLL_TEXT_INPUT , 0 ,
0 commit comments