aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--java/src/com/android/inputmethod/keyboard/Keyboard.java2
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java32
-rw-r--r--tests/src/com/android/inputmethod/latin/InputLogicTests.java34
3 files changed, 55 insertions, 13 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 5816e5680..c548f1145 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -680,7 +680,7 @@ public class Keyboard {
a.recycle();
if (resourceId == 0) {
if (LatinImeLogger.sDBG)
- throw new RuntimeException("touchPositionCorrectionData is not defined");
+ Log.e(TAG, "touchPositionCorrectionData is not defined");
return;
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index a053b9bbb..31cbc4ee3 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -203,9 +203,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private WordComposer mWordComposer = new WordComposer();
private int mCorrectionMode;
+
// Keep track of the last selection range to decide if we need to show word alternatives
- private int mLastSelectionStart;
- private int mLastSelectionEnd;
+ private static final int NOT_A_CURSOR_POSITION = -1;
+ private int mLastSelectionStart = NOT_A_CURSOR_POSITION;
+ private int mLastSelectionEnd = NOT_A_CURSOR_POSITION;
// Whether we are expecting an onUpdateSelection event to fire. If it does when we don't
// "expect" it, it means the user actually moved the cursor.
@@ -1401,9 +1403,29 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// inconsistent with backspacing after selecting other suggestions.
restartSuggestionsOnManuallyPickedTypedWord(ic);
} else {
- ic.deleteSurroundingText(1, 0);
- if (mDeleteCount > DELETE_ACCELERATE_AT) {
- ic.deleteSurroundingText(1, 0);
+ // Here we must check whether there is a selection. If so we should remove the
+ // selected text, otherwise we should just delete the character before the cursor.
+ if (mLastSelectionStart != mLastSelectionEnd) {
+ final int lengthToDelete = mLastSelectionEnd - mLastSelectionStart;
+ ic.setSelection(mLastSelectionEnd, mLastSelectionEnd);
+ ic.deleteSurroundingText(lengthToDelete, 0);
+ } else {
+ if (NOT_A_CURSOR_POSITION == mLastSelectionEnd) {
+ // We don't know whether there is a selection or not. We just send a false
+ // hardware key event and let TextView sort it out for us. The problem
+ // here is, this is asynchronous with respect to the input connection
+ // batch edit, so it may flicker. But this only ever happens if backspace
+ // is pressed just after the IME is invoked, and then again only once.
+ // TODO: add an API call that gets the selection indices. This is available
+ // to the IME in the general case via onUpdateSelection anyway, and would
+ // allow us to remove this race condition.
+ sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
+ } else {
+ ic.deleteSurroundingText(1, 0);
+ }
+ if (mDeleteCount > DELETE_ACCELERATE_AT) {
+ ic.deleteSurroundingText(1, 0);
+ }
}
if (isSuggestionsRequested()) {
restartSuggestionsOnWordBeforeCursorIfAtEndOfWord(ic);
diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTests.java b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
index 06ee5bffa..0d5e42b81 100644
--- a/tests/src/com/android/inputmethod/latin/InputLogicTests.java
+++ b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
@@ -41,6 +41,7 @@ public class InputLogicTests extends ServiceTestCase<LatinIME> {
private LatinIME mLatinIME;
private TextView mTextView;
+ private InputConnection mInputConnection;
public InputLogicTests() {
super(LatinIME.class);
@@ -82,6 +83,7 @@ public class InputLogicTests extends ServiceTestCase<LatinIME> {
mLatinIME.onCreateInputView();
mLatinIME.onStartInputView(ei, false);
mLatinIME.onCreateInputMethodInterface().startInput(ic, ei);
+ mInputConnection = ic;
}
// type(int) and type(String): helper methods to send a code point resp. a string to LatinIME.
@@ -106,17 +108,35 @@ public class InputLogicTests extends ServiceTestCase<LatinIME> {
}
public void testTypeWord() {
- final String wordToType = "abcd";
- type(wordToType);
- assertEquals("type word", wordToType, mTextView.getText().toString());
+ final String WORD_TO_TYPE = "abcd";
+ type(WORD_TO_TYPE);
+ assertEquals("type word", WORD_TO_TYPE, mTextView.getText().toString());
}
public void testPickSuggestionThenBackspace() {
- final String wordToType = "tgis";
- type(wordToType);
- mLatinIME.pickSuggestionManually(0, wordToType);
+ final String WORD_TO_TYPE = "tgis";
+ type(WORD_TO_TYPE);
+ mLatinIME.pickSuggestionManually(0, WORD_TO_TYPE);
type(Keyboard.CODE_DELETE);
- assertEquals("press suggestion then backspace", wordToType, mTextView.getText().toString());
+ assertEquals("press suggestion then backspace", WORD_TO_TYPE,
+ mTextView.getText().toString());
}
+ public void testDeleteSelection() {
+ final String STRING_TO_TYPE = "some text delete me some text";
+ final int SELECTION_START = 10;
+ final int SELECTION_END = 19;
+ final String EXPECTED_RESULT = "some text some text";
+ type(STRING_TO_TYPE);
+ // There is no IMF to call onUpdateSelection for us so we must do it by hand.
+ // Send once to simulate the cursor actually responding to the move caused by typing.
+ // This is necessary because LatinIME is bookkeeping to avoid confusing a real cursor
+ // move with a move triggered by LatinIME inputting stuff.
+ mLatinIME.onUpdateSelection(0, 0, STRING_TO_TYPE.length(), STRING_TO_TYPE.length(), -1, -1);
+ mInputConnection.setSelection(SELECTION_START, SELECTION_END);
+ // And now we simulate the user actually selecting some text.
+ mLatinIME.onUpdateSelection(0, 0, SELECTION_START, SELECTION_END, -1, -1);
+ type(Keyboard.CODE_DELETE);
+ assertEquals("delete selection", EXPECTED_RESULT, mTextView.getText().toString());
+ }
}