Skip to content

Commit fcff68f

Browse files
author
George Mount
committed
Enable scrolling page while editing text.
Bug 6194113 Change-Id: I27841bcf0635b9c8579e6db081612fd9e506d4ca
1 parent f9c1f99 commit fcff68f

File tree

1 file changed

+97
-92
lines changed

1 file changed

+97
-92
lines changed

core/java/android/webkit/WebViewClassic.java

Lines changed: 97 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,6 @@
7070
import android.util.EventLog;
7171
import android.util.Log;
7272
import android.view.Display;
73-
import android.view.GestureDetector;
74-
import android.view.GestureDetector.SimpleOnGestureListener;
7573
import android.view.Gravity;
7674
import android.view.HapticFeedbackConstants;
7775
import 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

Comments
 (0)