diff options
| author | 2014-04-17 12:40:31 +0900 | |
|---|---|---|
| committer | 2014-04-29 03:53:34 +0900 | |
| commit | 4de04795f988cc7447feb9ad00e179273f75a6a3 (patch) | |
| tree | 999217c65b333c8731a3d65a06b0cd94593d646e | |
| parent | 250bb6e3e045a88022db526b074e7ab38c47d93c (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.java | 11 | ||||
| -rw-r--r-- | core/java/android/view/inputmethod/InputMethodManager.java | 29 |
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); } |