summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/webkit/WebView.java126
-rw-r--r--core/java/android/webkit/WebViewCore.java4
-rw-r--r--core/res/res/values/public.xml1
3 files changed, 99 insertions, 32 deletions
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 6dc3be540f0e..7efe2ff4efe0 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -908,14 +908,22 @@ public class WebView extends AbsoluteLayout
// know to handle Shift and arrows natively first
private boolean mAccessibilityScriptInjected;
+
+ /**
+ * How long the caret handle will last without being touched.
+ */
+ private static final long CARET_HANDLE_STAMINA_MS = 3000;
+
private Drawable mSelectHandleLeft;
private Drawable mSelectHandleRight;
+ private Drawable mSelectHandleCenter;
private Rect mSelectCursorBase = new Rect();
private int mSelectCursorBaseLayerId;
private Rect mSelectCursorExtent = new Rect();
private int mSelectCursorExtentLayerId;
private Rect mSelectDraggingCursor;
private Point mSelectDraggingOffset = new Point();
+ private boolean mIsCaretSelection;
static final int HANDLE_ID_START = 0;
static final int HANDLE_ID_END = 1;
static final int HANDLE_ID_BASE = 2;
@@ -1012,6 +1020,7 @@ public class WebView extends AbsoluteLayout
static final int COPY_TO_CLIPBOARD = 141;
static final int INIT_EDIT_FIELD = 142;
static final int REPLACE_TEXT = 143;
+ static final int CLEAR_CARET_HANDLE = 144;
private static final int FIRST_PACKAGE_MSG_ID = SCROLL_TO_MSG_ID;
private static final int LAST_PACKAGE_MSG_ID = HIT_TEST_RESULT;
@@ -1418,7 +1427,7 @@ public class WebView extends AbsoluteLayout
IntentFilter filter = new IntentFilter();
filter.addAction(KeyChain.ACTION_STORAGE_CHANGED);
sTrustStorageListener = new TrustStorageListener();
- Intent current =
+ Intent current =
context.getApplicationContext().registerReceiver(sTrustStorageListener, filter);
if (current != null) {
handleCertTrustChanged();
@@ -5108,31 +5117,45 @@ public class WebView extends AbsoluteLayout
}
private void drawTextSelectionHandles(Canvas canvas) {
- if (mSelectHandleLeft == null) {
- mSelectHandleLeft = mContext.getResources().getDrawable(
- com.android.internal.R.drawable.text_select_handle_left);
- }
int[] handles = new int[4];
getSelectionHandles(handles);
int start_x = contentToViewDimension(handles[0]);
int start_y = contentToViewDimension(handles[1]);
int end_x = contentToViewDimension(handles[2]);
int end_y = contentToViewDimension(handles[3]);
- // Magic formula copied from TextView
- start_x -= (mSelectHandleLeft.getIntrinsicWidth() * 3) / 4;
- mSelectHandleLeft.setBounds(start_x, start_y,
- start_x + mSelectHandleLeft.getIntrinsicWidth(),
- start_y + mSelectHandleLeft.getIntrinsicHeight());
- if (mSelectHandleRight == null) {
- mSelectHandleRight = mContext.getResources().getDrawable(
- com.android.internal.R.drawable.text_select_handle_right);
+
+ if (mIsCaretSelection) {
+ if (mSelectHandleCenter == null) {
+ mSelectHandleCenter = mContext.getResources().getDrawable(
+ com.android.internal.R.drawable.text_select_handle_middle);
+ }
+ // Caret handle is centered
+ start_x -= (mSelectHandleCenter.getIntrinsicWidth() / 2);
+ mSelectHandleCenter.setBounds(start_x, start_y,
+ start_x + mSelectHandleCenter.getIntrinsicWidth(),
+ start_y + mSelectHandleCenter.getIntrinsicHeight());
+ mSelectHandleCenter.draw(canvas);
+ } else {
+ if (mSelectHandleLeft == null) {
+ mSelectHandleLeft = mContext.getResources().getDrawable(
+ com.android.internal.R.drawable.text_select_handle_left);
+ }
+ // Magic formula copied from TextView
+ start_x -= (mSelectHandleLeft.getIntrinsicWidth() * 3) / 4;
+ mSelectHandleLeft.setBounds(start_x, start_y,
+ start_x + mSelectHandleLeft.getIntrinsicWidth(),
+ start_y + mSelectHandleLeft.getIntrinsicHeight());
+ if (mSelectHandleRight == null) {
+ mSelectHandleRight = mContext.getResources().getDrawable(
+ com.android.internal.R.drawable.text_select_handle_right);
+ }
+ end_x -= mSelectHandleRight.getIntrinsicWidth() / 4;
+ mSelectHandleRight.setBounds(end_x, end_y,
+ end_x + mSelectHandleRight.getIntrinsicWidth(),
+ end_y + mSelectHandleRight.getIntrinsicHeight());
+ mSelectHandleLeft.draw(canvas);
+ mSelectHandleRight.draw(canvas);
}
- end_x -= mSelectHandleRight.getIntrinsicWidth() / 4;
- mSelectHandleRight.setBounds(end_x, end_y,
- end_x + mSelectHandleRight.getIntrinsicWidth(),
- end_y + mSelectHandleRight.getIntrinsicHeight());
- mSelectHandleLeft.draw(canvas);
- mSelectHandleRight.draw(canvas);
}
/**
@@ -5554,6 +5577,9 @@ public class WebView extends AbsoluteLayout
+ "keyCode=" + keyCode
+ ", " + event + ", unicode=" + event.getUnicodeChar());
}
+ if (mIsCaretSelection) {
+ selectionDone();
+ }
if (mBlockWebkitViewMessages) {
return false;
}
@@ -5866,6 +5892,7 @@ public class WebView extends AbsoluteLayout
private boolean startSelectActionMode() {
mSelectCallback = new SelectActionModeCallback();
+ mSelectCallback.setTextSelected(!mIsCaretSelection);
mSelectCallback.setWebView(this);
if (startActionMode(mSelectCallback) == null) {
// There is no ActionMode, so do not allow the user to modify a
@@ -5886,9 +5913,13 @@ public class WebView extends AbsoluteLayout
private boolean setupWebkitSelect() {
syncSelectionCursors();
- if (!startSelectActionMode()) {
- selectionDone();
- return false;
+ ClipboardManager cm = (ClipboardManager)(mContext
+ .getSystemService(Context.CLIPBOARD_SERVICE));
+ if (!mIsCaretSelection || cm.hasPrimaryClip()) {
+ if (!startSelectActionMode()) {
+ selectionDone();
+ return false;
+ }
}
mSelectingText = true;
mTouchMode = TOUCH_DRAG_MODE;
@@ -5897,6 +5928,9 @@ public class WebView extends AbsoluteLayout
private void updateWebkitSelection() {
int[] handles = null;
+ if (mIsCaretSelection) {
+ mSelectCursorExtent.set(mSelectCursorBase);
+ }
if (mSelectingText) {
handles = new int[4];
handles[0] = mSelectCursorBase.centerX();
@@ -5910,6 +5944,14 @@ public class WebView extends AbsoluteLayout
mWebViewCore.sendMessageAtFrontOfQueue(EventHub.SELECT_TEXT, handles);
}
+ private void resetCaretTimer() {
+ mPrivateHandler.removeMessages(CLEAR_CARET_HANDLE);
+ if (!mSelectionStarted) {
+ mPrivateHandler.sendEmptyMessageDelayed(CLEAR_CARET_HANDLE,
+ CARET_HANDLE_STAMINA_MS);
+ }
+ }
+
/**
* Use this method to put the WebView into text selection mode.
* Do not rely on this functionality; it will be deprecated in the future.
@@ -5937,9 +5979,14 @@ public class WebView extends AbsoluteLayout
mSelectingText = false;
// finish is idempotent, so this is fine even if selectionDone was
// called by mSelectCallback.onDestroyActionMode
- mSelectCallback.finish();
- mSelectCallback = null;
- updateWebkitSelection();
+ if (mSelectCallback != null) {
+ mSelectCallback.finish();
+ mSelectCallback = null;
+ }
+ if (!mIsCaretSelection) {
+ updateWebkitSelection();
+ }
+ mIsCaretSelection = false;
invalidate(); // redraw without selection
mAutoScrollX = 0;
mAutoScrollY = 0;
@@ -6553,18 +6600,26 @@ public class WebView extends AbsoluteLayout
(eventTime - mLastTouchUpTime), eventTime);
}
mSelectionStarted = false;
- if (mSelectingText && mSelectHandleLeft != null
- && mSelectHandleRight != null) {
+ if (mSelectingText) {
int shiftedY = y - getTitleHeight() + mScrollY;
int shiftedX = x + mScrollX;
- if (mSelectHandleLeft.getBounds()
+ if (mSelectHandleCenter != null && mSelectHandleCenter.getBounds()
.contains(shiftedX, shiftedY)) {
mSelectionStarted = true;
mSelectDraggingCursor = mSelectCursorBase;
- } else if (mSelectHandleRight.getBounds()
+ mPrivateHandler.removeMessages(CLEAR_CARET_HANDLE);
+ } else if (mSelectHandleLeft != null
+ && mSelectHandleLeft.getBounds()
+ .contains(shiftedX, shiftedY)) {
+ mSelectionStarted = true;
+ mSelectDraggingCursor = mSelectCursorBase;
+ } else if (mSelectHandleRight != null
+ && mSelectHandleRight.getBounds()
.contains(shiftedX, shiftedY)) {
mSelectionStarted = true;
mSelectDraggingCursor = mSelectCursorExtent;
+ } else if (mIsCaretSelection) {
+ selectionDone();
}
if (mSelectDraggingCursor != null) {
mSelectDraggingOffset.set(
@@ -7215,6 +7270,9 @@ public class WebView extends AbsoluteLayout
if (mSelectingText) {
mSelectionStarted = false;
+ if (mIsCaretSelection) {
+ resetCaretTimer();
+ }
syncSelectionCursors();
invalidate();
}
@@ -9173,6 +9231,9 @@ public class WebView extends AbsoluteLayout
}
break;
}
+ case CLEAR_CARET_HANDLE:
+ selectionDone();
+ break;
default:
super.handleMessage(msg);
@@ -9423,14 +9484,19 @@ public class WebView extends AbsoluteLayout
mInputConnection.setSelection(data.mStart, data.mEnd);
}
}
-
nativeSetTextSelection(mNativeClass, data.mSelectTextPtr);
if (data.mSelectTextPtr != 0) {
+ mIsCaretSelection = (mFieldPointer == nodePointer)
+ && (mFieldPointer != 0)
+ && (data.mStart == data.mEnd);
if (!mSelectingText) {
setupWebkitSelect();
} else if (!mSelectionStarted) {
syncSelectionCursors();
}
+ if (mIsCaretSelection) {
+ resetCaretTimer();
+ }
} else {
selectionDone();
}
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 84f0b9c845e5..e7d32380fc08 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -2834,7 +2834,7 @@ public final class WebViewCore {
// called by JNI
private void initEditField(int pointer, String text, int inputType,
boolean isSpellCheckEnabled, boolean nextFieldIsText,
- String label, int start, int end) {
+ String label, int start, int end, int selectionPtr) {
if (mWebView == null) {
return;
}
@@ -2844,7 +2844,7 @@ public final class WebViewCore {
WebView.INIT_EDIT_FIELD, initData).sendToTarget();
Message.obtain(mWebView.mPrivateHandler,
WebView.REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID, pointer,
- 0, new TextSelectionData(start, end, 0))
+ 0, new TextSelectionData(start, end, selectionPtr))
.sendToTarget();
}
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 2a6cef3f56b9..6a887db4f23f 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -962,6 +962,7 @@
<java-symbol type="drawable" name="tab_bottom_right_v4" />
<java-symbol type="drawable" name="tab_indicator_v4" />
<java-symbol type="drawable" name="text_select_handle_left" />
+ <java-symbol type="drawable" name="text_select_handle_middle" />
<java-symbol type="drawable" name="text_select_handle_right" />
<java-symbol type="drawable" name="unknown_image" />
<java-symbol type="drawable" name="unlock_default" />