diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java index 721f867f2458c..7bc154b68857d 100644 --- a/core/java/android/webkit/WebTextView.java +++ b/core/java/android/webkit/WebTextView.java @@ -78,7 +78,9 @@ import java.util.ArrayList; private float mDragStartY; private long mDragStartTime; private boolean mDragSent; - private boolean mPageScrolled; + // True if the most recent drag event has caused either the TextView to + // scroll or the web page to scroll. Gets reset after a touch down. + private boolean mScrolled; // Array to store the final character added in onTextChanged, so that its // KeyEvents may be determined. private char[] mCharacter = new char[1]; @@ -384,7 +386,7 @@ import java.util.ArrayList; mDragStartY = event.getY(); mDragStartTime = event.getEventTime(); mDragSent = false; - mPageScrolled = false; + mScrolled = false; break; case MotionEvent.ACTION_MOVE: Spannable buffer = getText(); @@ -393,8 +395,10 @@ import java.util.ArrayList; super.onTouchEvent(event); if (mScrollX != initialScrollX || mScrollY != initialScrollY) { - // TextView scrolled, so return true. - // FIXME: Need to make the webkit text scroll to reflect this + if (mWebView != null) { + mWebView.scrollFocusedTextInput(mScrollX, mScrollY); + } + mScrolled = true; return true; } if (mWebView != null) { @@ -406,7 +410,7 @@ import java.util.ArrayList; } boolean scrolled = mWebView.textFieldDrag(event); if (scrolled) { - mPageScrolled = true; + mScrolled = true; cancelLongPress(); return true; } @@ -414,12 +418,10 @@ import java.util.ArrayList; return false; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: - if (!mPageScrolled) { - // If the page scrolled, we do not want to change the selection, - // and the long press has already been canceled, so there is - // no need to call into super. - // FIXME: Once we enable scrolling the text inside the - // textfield, need to check that as well. + if (!mScrolled) { + // If the page scrolled, or the TextView scrolled, we do not + // want to change the selection, and the long press has already + // been canceled, so there is no need to call into super. super.onTouchEvent(event); } // Necessary for the WebView to reset its state diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 9eaa9a3d62394..19df87feb7a9d 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -379,6 +379,10 @@ public class WebView extends AbsoluteLayout // take control of touch events unless it says no for touch down event. private boolean mPreventDrag; + // To keep track of whether the current drag was initiated by a WebTextView, + // so that we know not to hide the cursor + boolean mDragFromTextInput; + // Whether or not to draw the cursor ring. private boolean mDrawCursorRing = true; @@ -3823,7 +3827,9 @@ public class WebView extends AbsoluteLayout mTouchMode = TOUCH_DRAG_MODE; WebViewCore.pauseUpdate(mWebViewCore); - nativeHideCursor(); + if (!mDragFromTextInput) { + nativeHideCursor(); + } // remove the zoom anchor if there is any if (mZoomScale != 0) { mWebViewCore @@ -4489,6 +4495,19 @@ public class WebView extends AbsoluteLayout nativeSelectBestAt(rect); } + /** + * Scroll the focused text field/area to match the WebTextView + * @param x New x position of the WebTextView in view coordinates + * @param y New y position of the WebTextView in view coordinates + */ + /*package*/ void scrollFocusedTextInput(int x, int y) { + if (!inEditingMode() || mWebViewCore == null) { + return; + } + mWebViewCore.sendMessage(EventHub.SCROLL_TEXT_INPUT, viewToContent(x), + viewToContent(y)); + } + /** * Set our starting point and time for a drag from the WebTextView. */ @@ -4516,9 +4535,12 @@ public class WebView extends AbsoluteLayout if (!inEditingMode()) { return false; } + mDragFromTextInput = true; event.offsetLocation((float) (mWebTextView.getLeft() - mScrollX), (float) (mWebTextView.getTop() - mScrollY)); - return onTouchEvent(event); + boolean result = onTouchEvent(event); + mDragFromTextInput = false; + return result; } /*package*/ void shortPressOnTextField() { diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 99ceec276f493..4993fcf05741b 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -591,6 +591,7 @@ final class WebViewCore { } static final String[] HandlerDebugString = { + "SCROLL_TEXT_INPUT", // = 99 "LOAD_URL", // = 100; "STOP_LOADING", // = 101; "RELOAD", // = 102; @@ -641,6 +642,7 @@ final class WebViewCore { class EventHub { // Message Ids + static final int SCROLL_TEXT_INPUT = 99; static final int LOAD_URL = 100; static final int STOP_LOADING = 101; static final int RELOAD = 102; @@ -745,9 +747,10 @@ final class WebViewCore { @Override public void handleMessage(Message msg) { if (DebugFlags.WEB_VIEW_CORE) { - Log.v(LOGTAG, (msg.what < LOAD_URL || msg.what + Log.v(LOGTAG, (msg.what < SCROLL_TEXT_INPUT || msg.what > FREE_MEMORY ? Integer.toString(msg.what) - : HandlerDebugString[msg.what - LOAD_URL]) + : HandlerDebugString[msg.what + - SCROLL_TEXT_INPUT]) + " arg1=" + msg.arg1 + " arg2=" + msg.arg2 + " obj=" + msg.obj); } @@ -764,6 +767,10 @@ final class WebViewCore { mNativeClass = 0; break; + case SCROLL_TEXT_INPUT: + nativeScrollFocusedTextInput(msg.arg1, msg.arg2); + break; + case LOAD_URL: loadUrl((String) msg.obj); break; @@ -1797,6 +1804,11 @@ final class WebViewCore { WebView.CLEAR_TEXT_ENTRY).sendToTarget(); } + /** + * Scroll the focused textfield to (x, y) in document space + */ + private native void nativeScrollFocusedTextInput(int x, int y); + // these must be in document space (i.e. not scaled/zoomed). private native void nativeSetScrollOffset(int gen, int dx, int dy);