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 ;
@@ -820,51 +818,6 @@ protected void measureContent() {
820818 }
821819 }
822820
823- private class TextScrollListener extends SimpleOnGestureListener {
824- @ Override
825- public boolean onFling (MotionEvent e1 , MotionEvent e2 ,
826- float velocityX , float velocityY ) {
827- int maxScrollX = mEditTextContent .width () -
828- mEditTextBounds .width ();
829- int maxScrollY = mEditTextContent .height () -
830- mEditTextBounds .height ();
831-
832- int contentVelocityX = viewToContentDimension ((int )-velocityX );
833- int contentVelocityY = viewToContentDimension ((int )-velocityY );
834- mEditTextScroller .fling (-mEditTextContent .left ,
835- -mEditTextContent .top ,
836- contentVelocityX , contentVelocityY ,
837- 0 , maxScrollX , 0 , maxScrollY );
838- return true ;
839- }
840-
841- @ Override
842- public boolean onScroll (MotionEvent e1 , MotionEvent e2 ,
843- float distanceX , float distanceY ) {
844- // Scrollable edit text. Scroll it.
845- int newScrollX = deltaToTextScroll (
846- -mEditTextContent .left , mEditTextContent .width (),
847- mEditTextBounds .width (),
848- (int ) distanceX );
849- int newScrollY = deltaToTextScroll (
850- -mEditTextContent .top , mEditTextContent .height (),
851- mEditTextBounds .height (),
852- (int ) distanceY );
853- scrollEditText (newScrollX , newScrollY );
854- return true ;
855- }
856-
857- private int deltaToTextScroll (int oldScroll , int contentSize ,
858- int boundsSize , int delta ) {
859- int newScroll = oldScroll +
860- viewToContentDimension (delta );
861- int maxScroll = contentSize - boundsSize ;
862- newScroll = Math .min (maxScroll , newScroll );
863- newScroll = Math .max (0 , newScroll );
864- return newScroll ;
865- }
866- }
867-
868821 // The listener to capture global layout change event.
869822 private InnerGlobalLayoutListener mGlobalLayoutListener = null ;
870823
@@ -893,7 +846,6 @@ private int deltaToTextScroll(int oldScroll, int contentSize,
893846 private int mFieldPointer ;
894847 private PastePopupWindow mPasteWindow ;
895848 private AutoCompletePopup mAutoCompletePopup ;
896- private GestureDetector mGestureDetector ;
897849 Rect mEditTextBounds = new Rect ();
898850 Rect mEditTextContent = new Rect ();
899851 int mEditTextLayerId ;
@@ -1037,6 +989,7 @@ public void onTrimMemory(int level) {
1037989 private static final int TOUCH_DONE_MODE = 7 ;
1038990 private static final int TOUCH_PINCH_DRAG = 8 ;
1039991 private static final int TOUCH_DRAG_LAYER_MODE = 9 ;
992+ private static final int TOUCH_DRAG_TEXT_MODE = 10 ;
1040993
1041994 // Whether to forward the touch events to WebCore
1042995 // Can only be set by WebKit via JNI.
@@ -1514,7 +1467,6 @@ public void init(Map<String, Object> javaScriptInterfaces, boolean privateBrowsi
15141467 }
15151468
15161469 mAutoFillData = new WebViewCore .AutoFillData ();
1517- mGestureDetector = new GestureDetector (mContext , new TextScrollListener ());
15181470 mEditTextScroller = new Scroller (context );
15191471 }
15201472
@@ -3404,6 +3356,10 @@ public void onOverScrolled(int scrollX, int scrollY, boolean clampedX,
34043356 boolean clampedY ) {
34053357 // Special-case layer scrolling so that we do not trigger normal scroll
34063358 // updating.
3359+ if (mTouchMode == TOUCH_DRAG_TEXT_MODE ) {
3360+ scrollEditText (scrollX , scrollY );
3361+ return ;
3362+ }
34073363 if (mTouchMode == TOUCH_DRAG_LAYER_MODE ) {
34083364 scrollLayerTo (scrollX , scrollY );
34093365 return ;
@@ -3876,6 +3832,12 @@ public void computeScroll() {
38763832 rangeY = mScrollingLayerRect .bottom ;
38773833 // No overscrolling for layers.
38783834 overflingDistance = 0 ;
3835+ } else if (mTouchMode == TOUCH_DRAG_TEXT_MODE ) {
3836+ oldX = getTextScrollX ();
3837+ oldY = getTextScrollY ();
3838+ rangeX = getMaxTextScrollX ();
3839+ rangeY = getMaxTextScrollY ();
3840+ overflingDistance = 0 ;
38793841 }
38803842
38813843 mWebViewPrivate .overScrollBy (x - oldX , y - oldY , oldX , oldY ,
@@ -3886,12 +3848,14 @@ public void computeScroll() {
38863848 mOverScrollGlow .absorbGlow (x , y , oldX , oldY , rangeX , rangeY );
38873849 }
38883850 } else {
3889- if (mTouchMode != TOUCH_DRAG_LAYER_MODE ) {
3890- setScrollXRaw (x );
3891- setScrollYRaw (y );
3892- } else {
3851+ if (mTouchMode == TOUCH_DRAG_LAYER_MODE ) {
38933852 // Update the layer position instead of WebView.
38943853 scrollLayerTo (x , y );
3854+ } else if (mTouchMode == TOUCH_DRAG_TEXT_MODE ) {
3855+ scrollEditText (x , y );
3856+ } else {
3857+ setScrollXRaw (x );
3858+ setScrollYRaw (y );
38953859 }
38963860 abortAnimation ();
38973861 nativeSetIsScrolling (false );
@@ -6177,7 +6141,6 @@ public void run() {
61776141 startTouch (x , y , eventTime );
61786142 if (mIsEditingText ) {
61796143 mTouchInEditText = mEditTextBounds .contains (contentX , contentY );
6180- mGestureDetector .onTouchEvent (ev );
61816144 }
61826145 break ;
61836146 }
@@ -6210,13 +6173,6 @@ public void run() {
62106173 invalidate ();
62116174 }
62126175 break ;
6213- } else if (mConfirmMove && mTouchInEditText ) {
6214- ViewParent parent = mWebView .getParent ();
6215- if (parent != null ) {
6216- parent .requestDisallowInterceptTouchEvent (true );
6217- }
6218- mGestureDetector .onTouchEvent (ev );
6219- break ;
62206176 }
62216177
62226178 // pass the touch events from UI thread to WebCore thread
@@ -6264,7 +6220,8 @@ public void run() {
62646220 }
62656221
62666222 if (mTouchMode != TOUCH_DRAG_MODE &&
6267- mTouchMode != TOUCH_DRAG_LAYER_MODE ) {
6223+ mTouchMode != TOUCH_DRAG_LAYER_MODE &&
6224+ mTouchMode != TOUCH_DRAG_TEXT_MODE ) {
62686225
62696226 if (!mConfirmMove ) {
62706227 break ;
@@ -6347,9 +6304,6 @@ public void run() {
63476304 deltaX = 0 ;
63486305 }
63496306 }
6350- mLastTouchX = x ;
6351- mLastTouchY = y ;
6352-
63536307 if (deltaX * deltaX + deltaY * deltaY > mTouchSlopSquare ) {
63546308 mHeldMotionless = MOTIONLESS_FALSE ;
63556309 nativeSetIsScrolling (true );
@@ -6360,13 +6314,24 @@ public void run() {
63606314 }
63616315
63626316 mLastTouchTime = eventTime ;
6317+ boolean allDrag = doDrag (deltaX , deltaY );
6318+ if (allDrag ) {
6319+ mLastTouchX = x ;
6320+ mLastTouchY = y ;
6321+ } else {
6322+ int contentDeltaX = (int )Math .floor (deltaX * mZoomManager .getInvScale ());
6323+ int roundedDeltaX = contentToViewDimension (contentDeltaX );
6324+ int contentDeltaY = (int )Math .floor (deltaY * mZoomManager .getInvScale ());
6325+ int roundedDeltaY = contentToViewDimension (contentDeltaY );
6326+ mLastTouchX -= roundedDeltaX ;
6327+ mLastTouchY -= roundedDeltaY ;
6328+ }
63636329 }
63646330
6365- doDrag (deltaX , deltaY );
6366-
63676331 // Turn off scrollbars when dragging a layer.
63686332 if (keepScrollBarsVisible &&
6369- mTouchMode != TOUCH_DRAG_LAYER_MODE ) {
6333+ mTouchMode != TOUCH_DRAG_LAYER_MODE &&
6334+ mTouchMode != TOUCH_DRAG_TEXT_MODE ) {
63706335 if (mHeldMotionless != MOTIONLESS_TRUE ) {
63716336 mHeldMotionless = MOTIONLESS_TRUE ;
63726337 invalidate ();
@@ -6387,11 +6352,6 @@ public void run() {
63876352 break ;
63886353 }
63896354 case MotionEvent .ACTION_UP : {
6390- mGestureDetector .onTouchEvent (ev );
6391- if (mTouchInEditText && mConfirmMove ) {
6392- stopTouch ();
6393- break ; // We've been scrolling the edit text.
6394- }
63956355 if (!mConfirmMove && mIsEditingText && mSelectionStarted &&
63966356 mIsCaretSelection ) {
63976357 showPasteWindow ();
@@ -6505,6 +6465,7 @@ public void run() {
65056465 }
65066466 case TOUCH_DRAG_MODE :
65076467 case TOUCH_DRAG_LAYER_MODE :
6468+ case TOUCH_DRAG_TEXT_MODE :
65086469 mPrivateHandler .removeMessages (DRAG_HELD_MOTIONLESS );
65096470 mPrivateHandler .removeMessages (AWAKEN_SCROLL_BARS );
65106471 // if the user waits a while w/o moving before the
@@ -6701,20 +6662,31 @@ private void startDrag() {
67016662 }
67026663 }
67036664
6704- private void doDrag (int deltaX , int deltaY ) {
6665+ private boolean doDrag (int deltaX , int deltaY ) {
6666+ boolean allDrag = true ;
67056667 if ((deltaX | deltaY ) != 0 ) {
67066668 int oldX = getScrollX ();
67076669 int oldY = getScrollY ();
67086670 int rangeX = computeMaxScrollX ();
67096671 int rangeY = computeMaxScrollY ();
6710- // Check for the original scrolling layer in case we change
6711- // directions. mTouchMode might be TOUCH_DRAG_MODE if we have
6712- // reached the edge of a layer but mScrollingLayer will be non-zero
6713- // if we initiated the drag on a layer.
6714- if (mCurrentScrollingLayerId != 0 ) {
6715- final int contentX = viewToContentDimension (deltaX );
6716- final int contentY = viewToContentDimension (deltaY );
6717-
6672+ final int contentX = (int )Math .floor (deltaX * mZoomManager .getInvScale ());
6673+ final int contentY = (int )Math .floor (deltaY * mZoomManager .getInvScale ());
6674+
6675+ // Assume page scrolling and change below if we're wrong
6676+ mTouchMode = TOUCH_DRAG_MODE ;
6677+
6678+ // Check special scrolling before going to main page scrolling.
6679+ if (mIsEditingText && mTouchInEditText && canTextScroll (deltaX , deltaY )) {
6680+ // Edit text scrolling
6681+ oldX = getTextScrollX ();
6682+ rangeX = getMaxTextScrollX ();
6683+ deltaX = contentX ;
6684+ oldY = getTextScrollY ();
6685+ rangeY = getMaxTextScrollY ();
6686+ deltaY = contentY ;
6687+ mTouchMode = TOUCH_DRAG_TEXT_MODE ;
6688+ allDrag = false ;
6689+ } else if (mCurrentScrollingLayerId != 0 ) {
67186690 // Check the scrolling bounds to see if we will actually do any
67196691 // scrolling. The rectangle is in document coordinates.
67206692 final int maxX = mScrollingLayerRect .right ;
@@ -6734,12 +6706,7 @@ private void doDrag(int deltaX, int deltaY) {
67346706 oldY = mScrollingLayerRect .top ;
67356707 rangeX = maxX ;
67366708 rangeY = maxY ;
6737- } else {
6738- // Scroll the main page if we are not going to scroll the
6739- // layer. This does not reset mScrollingLayer in case the
6740- // user changes directions and the layer can scroll the
6741- // other way.
6742- mTouchMode = TOUCH_DRAG_MODE ;
6709+ allDrag = false ;
67436710 }
67446711 }
67456712
@@ -6755,11 +6722,13 @@ private void doDrag(int deltaX, int deltaY) {
67556722 }
67566723 }
67576724 mZoomManager .keepZoomPickerVisible ();
6725+ return allDrag ;
67586726 }
67596727
67606728 private void stopTouch () {
67616729 if (mScroller .isFinished () && !mSelectingText
6762- && (mTouchMode == TOUCH_DRAG_MODE || mTouchMode == TOUCH_DRAG_LAYER_MODE )) {
6730+ && (mTouchMode == TOUCH_DRAG_MODE
6731+ || mTouchMode == TOUCH_DRAG_LAYER_MODE )) {
67636732 WebViewCore .resumePriority ();
67646733 WebViewCore .resumeUpdatePicture (mWebViewCore );
67656734 nativeSetIsScrolling (false );
@@ -7153,6 +7122,13 @@ private void doFling() {
71537122 maxY = mScrollingLayerRect .bottom ;
71547123 // No overscrolling for layers.
71557124 overscrollDistance = overflingDistance = 0 ;
7125+ } else if (mTouchMode == TOUCH_DRAG_TEXT_MODE ) {
7126+ scrollX = getTextScrollX ();
7127+ scrollY = getTextScrollY ();
7128+ maxX = getMaxTextScrollX ();
7129+ maxY = getMaxTextScrollY ();
7130+ // No overscrolling for edit text.
7131+ overscrollDistance = overflingDistance = 0 ;
71567132 }
71577133
71587134 if (mSnapScrollMode != SNAP_NONE ) {
@@ -7232,7 +7208,7 @@ private void doFling() {
72327208 final int time = mScroller .getDuration ();
72337209
72347210 // Suppress scrollbars for layer scrolling.
7235- if (mTouchMode != TOUCH_DRAG_LAYER_MODE ) {
7211+ if (mTouchMode != TOUCH_DRAG_LAYER_MODE && mTouchMode != TOUCH_DRAG_TEXT_MODE ) {
72367212 mWebViewPrivate .awakenScrollBars (time );
72377213 }
72387214
@@ -7590,6 +7566,36 @@ public synchronized WebViewCore getWebViewCore() {
75907566 return mWebViewCore ;
75917567 }
75927568
7569+ private boolean canTextScroll (int directionX , int directionY ) {
7570+ int scrollX = getTextScrollX ();
7571+ int scrollY = getTextScrollY ();
7572+ int maxScrollX = getMaxTextScrollX ();
7573+ int maxScrollY = getMaxTextScrollY ();
7574+ boolean canScrollX = (directionX > 0 )
7575+ ? (scrollX < maxScrollX )
7576+ : (scrollX > 0 );
7577+ boolean canScrollY = (directionY > 0 )
7578+ ? (scrollY < maxScrollY )
7579+ : (scrollY > 0 );
7580+ return canScrollX || canScrollY ;
7581+ }
7582+
7583+ private int getTextScrollX () {
7584+ return -mEditTextContent .left ;
7585+ }
7586+
7587+ private int getTextScrollY () {
7588+ return -mEditTextContent .top ;
7589+ }
7590+
7591+ private int getMaxTextScrollX () {
7592+ return Math .max (0 , mEditTextContent .width () - mEditTextBounds .width ());
7593+ }
7594+
7595+ private int getMaxTextScrollY () {
7596+ return Math .max (0 , mEditTextContent .height () - mEditTextBounds .height ());
7597+ }
7598+
75937599 /**
75947600 * Used only by TouchEventQueue to store pending touch events.
75957601 */
@@ -8909,8 +8915,7 @@ private void computeEditTextScroll() {
89098915
89108916 private void scrollEditText (int scrollX , int scrollY ) {
89118917 // Scrollable edit text. Scroll it.
8912- float maxScrollX = (float )(mEditTextContent .width () -
8913- mEditTextBounds .width ());
8918+ float maxScrollX = getMaxTextScrollX ();
89148919 float scrollPercentX = ((float )scrollX )/maxScrollX ;
89158920 mEditTextContent .offsetTo (-scrollX , -scrollY );
89168921 mWebViewCore .sendMessageAtFrontOfQueue (EventHub .SCROLL_TEXT_INPUT , 0 ,
0 commit comments