summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Yohei Yukawa <yukawa@google.com> 2014-04-17 12:40:31 +0900
committer Yohei Yukawa <yukawa@google.com> 2014-04-29 03:53:34 +0900
commit4de04795f988cc7447feb9ad00e179273f75a6a3 (patch)
tree999217c65b333c8731a3d65a06b0cd94593d646e
parent250bb6e3e045a88022db526b074e7ab38c47d93c (diff)
Return the cursor position in screen coordinates
From its beginning, InputMethodService#onUpdateCursor has provided the cursor position in local coordinates in the attached view. However, the local coordinates is not useful for IMEs to render a floating UI near the cursor because the IME is not able to know the origin of the attached view. With this CL, CURSOR_ANCHOR_MONITOR_MODE_CURSOR_RECT also means that the IME will receive the cursor position in screen coordinates. Because this is a new constant in the next release, conditionally changing the coordinates never causes compatibility issues as long as its behavior is well documented. BUG: 14323360 Change-Id: I3acf2317ae1d763d11dae5ef73c2a1348b377c71
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java11
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java29
2 files changed, 32 insertions, 8 deletions
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index c51d1a78e5ad..ec581d1a71e1 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -255,7 +255,8 @@ public class InputMethodService extends AbstractInputMethodService {
public static final int CURSOR_ANCHOR_MONITOR_MODE_NONE = 0x0;
/**
- * The IME expects that {@link #onUpdateCursor(Rect)} is called back.
+ * The IME will receive {@link #onUpdateCursor(Rect)} called back with the current
+ * cursor rectangle in screen coordinates.
*/
public static final int CURSOR_ANCHOR_MONITOR_MODE_CURSOR_RECT = 0x1;
@@ -1703,9 +1704,11 @@ public class InputMethodService extends AbstractInputMethodService {
}
/**
- * Called when the application has reported a new location of its text
- * cursor. This is only called if explicitly requested by the input method.
- * The default implementation does nothing.
+ * Called when the application has reported a new location of its text cursor. This is only
+ * called if explicitly requested by the input method. The default implementation does nothing.
+ * @param newCursor The new cursor position, in screen coordinates if the input method calls
+ * {@link #setCursorAnchorMonitorMode} with {@link #CURSOR_ANCHOR_MONITOR_MODE_CURSOR_RECT}.
+ * Otherwise, this is in local coordinates.
*/
public void onUpdateCursor(Rect newCursor) {
// Intentionally empty
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index e3bd9fd261be..02278733d270 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -317,6 +317,10 @@ public final class InputMethodManager {
int mCursorSelEnd;
int mCursorCandStart;
int mCursorCandEnd;
+ /**
+ * The buffer to retrieve the view location in screen coordinates in {@link #updateCursor}.
+ */
+ private final int[] mViewTopLeft = new int[2];
// -----------------------------------------------------------
@@ -1487,12 +1491,26 @@ public final class InputMethodManager {
return false;
}
synchronized (mH) {
- return mCursorAnchorMonitorMode ==
- InputMethodService.CURSOR_ANCHOR_MONITOR_MODE_CURSOR_RECT;
+ return (mCursorAnchorMonitorMode &
+ InputMethodService.CURSOR_ANCHOR_MONITOR_MODE_CURSOR_RECT) != 0;
}
}
/**
+ * Returns true if the current input method wants to receive the cursor rectangle in
+ * screen coordinates rather than local coordinates in the attached view.
+ *
+ * @hide
+ */
+ public boolean usesScreenCoordinatesForCursorLocked() {
+ // {@link InputMethodService#CURSOR_ANCHOR_MONITOR_MODE_CURSOR_RECT} also means
+ // that {@link InputMethodService#onUpdateCursor} should provide the cursor rectangle
+ // in screen coordinates rather than local coordinates.
+ return (mCursorAnchorMonitorMode &
+ InputMethodService.CURSOR_ANCHOR_MONITOR_MODE_CURSOR_RECT) != 0;
+ }
+
+ /**
* Set cursor/anchor monitor mode via {@link com.android.server.InputMethodManagerService}.
* This is an internal method for {@link android.inputmethodservice.InputMethodService} and
* should never be used from IMEs and applications.
@@ -1518,15 +1536,18 @@ public final class InputMethodManager {
|| mCurrentTextBoxAttribute == null || mCurMethod == null) {
return;
}
-
mTmpCursorRect.set(left, top, right, bottom);
if (!mCursorRect.equals(mTmpCursorRect)) {
if (DEBUG) Log.d(TAG, "updateCursor");
try {
if (DEBUG) Log.v(TAG, "CURSOR CHANGE: " + mCurMethod);
- mCurMethod.updateCursor(mTmpCursorRect);
mCursorRect.set(mTmpCursorRect);
+ if (usesScreenCoordinatesForCursorLocked()) {
+ view.getLocationOnScreen(mViewTopLeft);
+ mTmpCursorRect.offset(mViewTopLeft[0], mViewTopLeft[1]);
+ }
+ mCurMethod.updateCursor(mTmpCursorRect);
} catch (RemoteException e) {
Log.w(TAG, "IME died: " + mCurId, e);
}