aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com
diff options
context:
space:
mode:
authorJean Chalard <jchalard@google.com>2014-10-01 18:06:26 +0900
committerJean Chalard <jchalard@google.com>2014-10-01 19:17:31 +0900
commit38144047ea3985c9345e7fbe6bb3aafbeaea5f06 (patch)
tree13ff04bce00fe4437d962c27f2b64269acb04646 /java/src/com
parent7b673c72651aa7dbfc3fc87fe2190d8cffb320c1 (diff)
downloadlatinime-38144047ea3985c9345e7fbe6bb3aafbeaea5f06.tar.gz
latinime-38144047ea3985c9345e7fbe6bb3aafbeaea5f06.tar.xz
latinime-38144047ea3985c9345e7fbe6bb3aafbeaea5f06.zip
Make a better effort to detect a framework lie.
Bug: 17130496 Change-Id: I1a3631670c152d9b7667c9c4e08e14c48569eef5
Diffstat (limited to 'java/src/com')
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java6
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputConnection.java20
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java26
3 files changed, 35 insertions, 17 deletions
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 5aae010ac..64e404601 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -926,8 +926,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// mLastSelection{Start,End} are reset later in this method, no need to do it here
needToCallLoadKeyboardLater = true;
} else {
- // When rotating, initialSelStart and initialSelEnd sometimes are lying. Make a best
- // effort to work around this bug.
+ // When rotating, and when input is starting again in a field from where the focus
+ // didn't move (the keyboard having been closed with the back key),
+ // initialSelStart and initialSelEnd sometimes are lying. Make a best effort to
+ // work around this bug.
mInputLogic.mConnection.tryFixLyingCursorPosition();
mHandler.postResumeSuggestions(true /* shouldIncludeResumedWordInSuggestions */,
true /* shouldDelay */);
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index 750706113..a7ea2a1c8 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -849,8 +849,9 @@ public final class RichInputConnection {
/**
* Try to get the text from the editor to expose lies the framework may have been
- * telling us. Concretely, when the device rotates, the frameworks tells us about where the
- * cursor used to be initially in the editor at the time it first received the focus; this
+ * telling us. Concretely, when the device rotates and when the keyboard reopens in the same
+ * text field after having been closed with the back key, the frameworks tells us about where
+ * the cursor used to be initially in the editor at the time it first received the focus; this
* may be completely different from the place it is upon rotation. Since we don't have any
* means to get the real value, try at least to ask the text view for some characters and
* detect the most damaging cases: when the cursor position is declared to be much smaller
@@ -859,7 +860,20 @@ public final class RichInputConnection {
public void tryFixLyingCursorPosition() {
final CharSequence textBeforeCursor = getTextBeforeCursor(
Constants.EDITOR_CONTENTS_CACHE_SIZE, 0);
- if (null == textBeforeCursor) {
+ final CharSequence selectedText = mIC.getSelectedText(0 /* flags */);
+ if (null == textBeforeCursor ||
+ (!TextUtils.isEmpty(selectedText) && mExpectedSelEnd == mExpectedSelStart)) {
+ // If textBeforeCursor is null, we have no idea what kind of text field we have or if
+ // thinking about the "cursor position" actually makes any sense. In this case we
+ // remember a meaningless cursor position. Contrast this with an empty string, which is
+ // valid and should mean the cursor is at the start of the text.
+ // Also, if we expect we don't have a selection but we DO have non-empty selected text,
+ // then the framework lied to us about the cursor position. In this case, we should just
+ // revert to the most basic behavior possible for the next action (backspace in
+ // particular comes to mind), so we remember a meaningless cursor position which should
+ // result in degraded behavior from the next input.
+ // Interestingly, in either case, chances are any action the user takes next will result
+ // in a call to onUpdateSelection, which should set things right.
mExpectedSelStart = mExpectedSelEnd = Constants.NOT_A_CURSOR_POSITION;
} else {
final int textLength = textBeforeCursor.length();
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index d7e1eba8b..1a7db6223 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -1127,19 +1127,21 @@ public final class InputLogic {
StatsUtils.onBackspaceSelectedText(numCharsDeleted);
} else {
// There is no selection, just delete one character.
- if (Constants.NOT_A_CURSOR_POSITION == mConnection.getExpectedSelectionEnd()) {
- // This should never happen.
- Log.e(TAG, "Backspace when we don't know the selection position");
- }
- if (inputTransaction.mSettingsValues.isBeforeJellyBean() ||
- inputTransaction.mSettingsValues.mInputAttributes.isTypeNull()) {
- // There are two possible reasons to send a key event: either the field has
+ if (inputTransaction.mSettingsValues.isBeforeJellyBean()
+ || inputTransaction.mSettingsValues.mInputAttributes.isTypeNull()
+ || Constants.NOT_A_CURSOR_POSITION
+ == mConnection.getExpectedSelectionEnd()) {
+ // There are three possible reasons to send a key event: either the field has
// type TYPE_NULL, in which case the keyboard should send events, or we are
- // running in backward compatibility mode. Before Jelly bean, the keyboard
- // would simulate a hardware keyboard event on pressing enter or delete. This
- // is bad for many reasons (there are race conditions with commits) but some
- // applications are relying on this behavior so we continue to support it for
- // older apps, so we retain this behavior if the app has target SDK < JellyBean.
+ // running in backward compatibility mode, or we don't know the cursor position.
+ // Before Jelly bean, the keyboard would simulate a hardware keyboard event on
+ // pressing enter or delete. This is bad for many reasons (there are race
+ // conditions with commits) but some applications are relying on this behavior
+ // so we continue to support it for older apps, so we retain this behavior if
+ // the app has target SDK < JellyBean.
+ // As for the case where we don't know the cursor position, it can happen
+ // because of bugs in the framework. But the framework should know, so the next
+ // best thing is to leave it to whatever it thinks is best.
sendDownUpKeyEvent(KeyEvent.KEYCODE_DEL);
int totalDeletedLength = 1;
if (mDeleteCount > Constants.DELETE_ACCELERATE_AT) {