am ecf46df2: [IL54] Add a mirror method to fix the cursor pos estimate

* commit 'ecf46df22683b997311ba77b34b33dffa8be43c0':
  [IL54] Add a mirror method to fix the cursor pos estimate
main
Jean Chalard 2014-01-09 23:39:23 -08:00 committed by Android Git Automerger
commit a9d45c9bf4
2 changed files with 57 additions and 5 deletions

View File

@ -788,9 +788,9 @@ public final class RichInputConnection {
// This update is "belated" if we are expecting it. That is, mExpectedSelStart and // This update is "belated" if we are expecting it. That is, mExpectedSelStart and
// mExpectedSelEnd match the new values that the TextView is updating TO. // mExpectedSelEnd match the new values that the TextView is updating TO.
if (mExpectedSelStart == newSelStart && mExpectedSelEnd == newSelEnd) return true; if (mExpectedSelStart == newSelStart && mExpectedSelEnd == newSelEnd) return true;
// This update is not belated if mExpectedSelStart and mExpeectedSelend match the old // This update is not belated if mExpectedSelStart and mExpectedSelEnd match the old
// values, and one of newSelStart or newSelEnd is updated to a different value. In this // values, and one of newSelStart or newSelEnd is updated to a different value. In this
// case, there is likely something other than the IME that has moved the selection endpoint // case, there is likely something other than the IME has moved the selection endpoint
// to the new value. // to the new value.
if (mExpectedSelStart == oldSelStart && mExpectedSelEnd == oldSelEnd if (mExpectedSelStart == oldSelStart && mExpectedSelEnd == oldSelEnd
&& (oldSelStart != newSelStart || oldSelEnd != newSelEnd)) return false; && (oldSelStart != newSelStart || oldSelEnd != newSelEnd)) return false;
@ -813,4 +813,54 @@ public final class RichInputConnection {
public boolean textBeforeCursorLooksLikeURL() { public boolean textBeforeCursorLooksLikeURL() {
return StringUtils.lastPartLooksLikeURL(mCommittedTextBeforeComposingText); return StringUtils.lastPartLooksLikeURL(mCommittedTextBeforeComposingText);
} }
/**
* 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
* 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
* than it really is.
*/
public void tryFixLyingCursorPosition() {
final CharSequence textBeforeCursor = getTextBeforeCursor(
Constants.EDITOR_CONTENTS_CACHE_SIZE, 0);
if (null == textBeforeCursor) {
mExpectedSelStart = mExpectedSelEnd = Constants.NOT_A_CURSOR_POSITION;
} else {
final int textLength = textBeforeCursor.length();
if (textLength > mExpectedSelStart
|| (textLength < Constants.EDITOR_CONTENTS_CACHE_SIZE
&& mExpectedSelStart < Constants.EDITOR_CONTENTS_CACHE_SIZE)) {
// It should not be possible to have only one of those variables be
// NOT_A_CURSOR_POSITION, so if they are equal, either the selection is zero-sized
// (simple cursor, no selection) or there is no cursor/we don't know its pos
final boolean wasEqual = mExpectedSelStart == mExpectedSelEnd;
mExpectedSelStart = textLength;
// We can't figure out the value of mLastSelectionEnd :(
// But at least if it's smaller than mLastSelectionStart something is wrong,
// and if they used to be equal we also don't want to make it look like there is a
// selection.
if (wasEqual || mExpectedSelStart > mExpectedSelEnd) {
mExpectedSelEnd = mExpectedSelStart;
}
}
}
}
public int getExpectedSelectionStart() {
return mExpectedSelStart;
}
public int getExpectedSelectionEnd() {
return mExpectedSelEnd;
}
/**
* @return whether there is a selection currently active.
*/
public boolean hasSelection() {
return mExpectedSelEnd != mExpectedSelStart;
}
} }

View File

@ -133,6 +133,7 @@ public final class InputLogic {
mLastSelectionEnd = editorInfo.initialSelEnd; mLastSelectionEnd = editorInfo.initialSelEnd;
// In some cases (namely, after rotation of the device) editorInfo.initialSelStart is lying // In some cases (namely, after rotation of the device) editorInfo.initialSelStart is lying
// so we try using some heuristics to find out about these and fix them. // so we try using some heuristics to find out about these and fix them.
mConnection.tryFixLyingCursorPosition();
tryFixLyingCursorPosition(); tryFixLyingCursorPosition();
mInputLogicHandler = new InputLogicHandler(mLatinIME, this); mInputLogicHandler = new InputLogicHandler(mLatinIME, this);
} }
@ -1750,6 +1751,7 @@ public final class InputLogic {
// If remainingTries is 0, we should stop waiting for new tries, but it's still // If remainingTries is 0, we should stop waiting for new tries, but it's still
// better to load the keyboard (less things will be broken). // better to load the keyboard (less things will be broken).
} }
mConnection.tryFixLyingCursorPosition();
tryFixLyingCursorPosition(); tryFixLyingCursorPosition();
keyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(), settingsValues); keyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(), settingsValues);
if (tryResumeSuggestions) { if (tryResumeSuggestions) {