Rename mExpectedCursorStart to mExpectedSelStart
Change-Id: If23d8bd73fe464f12f473e093dc87ed68756e1ecmain
parent
a2632aabf7
commit
2bf3a77814
|
@ -64,7 +64,7 @@ public final class RichInputConnection {
|
||||||
* It's not really the cursor position: the cursor may not be there yet, and it's also expected
|
* It's not really the cursor position: the cursor may not be there yet, and it's also expected
|
||||||
* there be cases where it never actually comes to be there.
|
* there be cases where it never actually comes to be there.
|
||||||
*/
|
*/
|
||||||
private int mExpectedCursorPosition = INVALID_CURSOR_POSITION; // in chars, not code points
|
private int mExpectedSelStart = INVALID_CURSOR_POSITION; // in chars, not code points
|
||||||
/**
|
/**
|
||||||
* This contains the committed text immediately preceding the cursor and the composing
|
* This contains the committed text immediately preceding the cursor and the composing
|
||||||
* text if any. It is refreshed when the cursor moves by calling upon the TextView.
|
* text if any. It is refreshed when the cursor moves by calling upon the TextView.
|
||||||
|
@ -103,16 +103,16 @@ public final class RichInputConnection {
|
||||||
final String reference = (beforeCursor.length() <= actualLength) ? beforeCursor.toString()
|
final String reference = (beforeCursor.length() <= actualLength) ? beforeCursor.toString()
|
||||||
: beforeCursor.subSequence(beforeCursor.length() - actualLength,
|
: beforeCursor.subSequence(beforeCursor.length() - actualLength,
|
||||||
beforeCursor.length()).toString();
|
beforeCursor.length()).toString();
|
||||||
if (et.selectionStart != mExpectedCursorPosition
|
if (et.selectionStart != mExpectedSelStart
|
||||||
|| !(reference.equals(internal.toString()))) {
|
|| !(reference.equals(internal.toString()))) {
|
||||||
final String context = "Expected cursor position = " + mExpectedCursorPosition
|
final String context = "Expected selection start = " + mExpectedSelStart
|
||||||
+ "\nActual cursor position = " + et.selectionStart
|
+ "\nActual selection start = " + et.selectionStart
|
||||||
+ "\nExpected text = " + internal.length() + " " + internal
|
+ "\nExpected text = " + internal.length() + " " + internal
|
||||||
+ "\nActual text = " + reference.length() + " " + reference;
|
+ "\nActual text = " + reference.length() + " " + reference;
|
||||||
((LatinIME)mParent).debugDumpStateAndCrashWithException(context);
|
((LatinIME)mParent).debugDumpStateAndCrashWithException(context);
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, DebugLogUtils.getStackTrace(2));
|
Log.e(TAG, DebugLogUtils.getStackTrace(2));
|
||||||
Log.e(TAG, "Exp <> Actual : " + mExpectedCursorPosition + " <> " + et.selectionStart);
|
Log.e(TAG, "Exp <> Actual : " + mExpectedSelStart + " <> " + et.selectionStart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,15 +150,15 @@ public final class RichInputConnection {
|
||||||
* data, so we empty the cache and note that we don't know the new cursor position, and we
|
* data, so we empty the cache and note that we don't know the new cursor position, and we
|
||||||
* return false so that the caller knows about this and can retry later.
|
* return false so that the caller knows about this and can retry later.
|
||||||
*
|
*
|
||||||
* @param newCursorPosition The new position of the cursor, as received from the system.
|
* @param newSelStart The new position of the selection start, as received from the system.
|
||||||
* @param shouldFinishComposition Whether we should finish the composition in progress.
|
* @param shouldFinishComposition Whether we should finish the composition in progress.
|
||||||
* @return true if we were able to connect to the editor successfully, false otherwise. When
|
* @return true if we were able to connect to the editor successfully, false otherwise. When
|
||||||
* this method returns false, the caches could not be correctly refreshed so they were only
|
* this method returns false, the caches could not be correctly refreshed so they were only
|
||||||
* reset: the caller should try again later to return to normal operation.
|
* reset: the caller should try again later to return to normal operation.
|
||||||
*/
|
*/
|
||||||
public boolean resetCachesUponCursorMoveAndReturnSuccess(final int newCursorPosition,
|
public boolean resetCachesUponCursorMoveAndReturnSuccess(final int newSelStart,
|
||||||
final boolean shouldFinishComposition) {
|
final boolean shouldFinishComposition) {
|
||||||
mExpectedCursorPosition = newCursorPosition;
|
mExpectedSelStart = newSelStart;
|
||||||
mComposingText.setLength(0);
|
mComposingText.setLength(0);
|
||||||
final boolean didReloadTextSuccessfully = reloadTextCache();
|
final boolean didReloadTextSuccessfully = reloadTextCache();
|
||||||
if (!didReloadTextSuccessfully) {
|
if (!didReloadTextSuccessfully) {
|
||||||
|
@ -166,14 +166,14 @@ public final class RichInputConnection {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final int lengthOfTextBeforeCursor = mCommittedTextBeforeComposingText.length();
|
final int lengthOfTextBeforeCursor = mCommittedTextBeforeComposingText.length();
|
||||||
if (lengthOfTextBeforeCursor > newCursorPosition
|
if (lengthOfTextBeforeCursor > newSelStart
|
||||||
|| (lengthOfTextBeforeCursor < Constants.EDITOR_CONTENTS_CACHE_SIZE
|
|| (lengthOfTextBeforeCursor < Constants.EDITOR_CONTENTS_CACHE_SIZE
|
||||||
&& newCursorPosition < Constants.EDITOR_CONTENTS_CACHE_SIZE)) {
|
&& newSelStart < Constants.EDITOR_CONTENTS_CACHE_SIZE)) {
|
||||||
// newCursorPosition may be lying -- when rotating the device (probably a framework
|
// newSelStart may be lying -- when rotating the device (probably a framework bug). If
|
||||||
// bug). If we have less chars than we asked for, then we know how many chars we have,
|
// we have less chars than we asked for, then we know how many chars we have, and if we
|
||||||
// and if we got more than newCursorPosition says, then we know it was lying. In both
|
// got more than newSelStart says, then we know it was lying. In both cases the length
|
||||||
// cases the length is more reliable
|
// is more reliable.
|
||||||
mExpectedCursorPosition = lengthOfTextBeforeCursor;
|
mExpectedSelStart = lengthOfTextBeforeCursor;
|
||||||
}
|
}
|
||||||
if (null != mIC && shouldFinishComposition) {
|
if (null != mIC && shouldFinishComposition) {
|
||||||
mIC.finishComposingText();
|
mIC.finishComposingText();
|
||||||
|
@ -199,7 +199,7 @@ public final class RichInputConnection {
|
||||||
if (null == textBeforeCursor) {
|
if (null == textBeforeCursor) {
|
||||||
// For some reason the app thinks we are not connected to it. This looks like a
|
// For some reason the app thinks we are not connected to it. This looks like a
|
||||||
// framework bug... Fall back to ground state and return false.
|
// framework bug... Fall back to ground state and return false.
|
||||||
mExpectedCursorPosition = INVALID_CURSOR_POSITION;
|
mExpectedSelStart = INVALID_CURSOR_POSITION;
|
||||||
Log.e(TAG, "Unable to connect to the editor to retrieve text.");
|
Log.e(TAG, "Unable to connect to the editor to retrieve text.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -232,7 +232,7 @@ public final class RichInputConnection {
|
||||||
if (DEBUG_BATCH_NESTING) checkBatchEdit();
|
if (DEBUG_BATCH_NESTING) checkBatchEdit();
|
||||||
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
|
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
|
||||||
mCommittedTextBeforeComposingText.append(text);
|
mCommittedTextBeforeComposingText.append(text);
|
||||||
mExpectedCursorPosition += text.length() - mComposingText.length();
|
mExpectedSelStart += text.length() - mComposingText.length();
|
||||||
mComposingText.setLength(0);
|
mComposingText.setLength(0);
|
||||||
if (null != mIC) {
|
if (null != mIC) {
|
||||||
mIC.commitText(text, i);
|
mIC.commitText(text, i);
|
||||||
|
@ -245,7 +245,7 @@ public final class RichInputConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canDeleteCharacters() {
|
public boolean canDeleteCharacters() {
|
||||||
return mExpectedCursorPosition > 0;
|
return mExpectedSelStart > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -282,7 +282,7 @@ public final class RichInputConnection {
|
||||||
// heavy pressing of delete, for example DEFAULT_TEXT_CACHE_SIZE - 5 times or so.
|
// heavy pressing of delete, for example DEFAULT_TEXT_CACHE_SIZE - 5 times or so.
|
||||||
// getCapsMode should be updated to be able to return a "not enough info" result so that
|
// getCapsMode should be updated to be able to return a "not enough info" result so that
|
||||||
// we can get more context only when needed.
|
// we can get more context only when needed.
|
||||||
if (TextUtils.isEmpty(mCommittedTextBeforeComposingText) && 0 != mExpectedCursorPosition) {
|
if (TextUtils.isEmpty(mCommittedTextBeforeComposingText) && 0 != mExpectedSelStart) {
|
||||||
if (!reloadTextCache()) {
|
if (!reloadTextCache()) {
|
||||||
Log.w(TAG, "Unable to connect to the editor. "
|
Log.w(TAG, "Unable to connect to the editor. "
|
||||||
+ "Setting caps mode without knowing text.");
|
+ "Setting caps mode without knowing text.");
|
||||||
|
@ -308,8 +308,8 @@ public final class RichInputConnection {
|
||||||
// However, if we don't have an expected cursor position, then we should always
|
// However, if we don't have an expected cursor position, then we should always
|
||||||
// go fetch the cache again (as it happens, INVALID_CURSOR_POSITION < 0, so we need to
|
// go fetch the cache again (as it happens, INVALID_CURSOR_POSITION < 0, so we need to
|
||||||
// test for this explicitly)
|
// test for this explicitly)
|
||||||
if (INVALID_CURSOR_POSITION != mExpectedCursorPosition
|
if (INVALID_CURSOR_POSITION != mExpectedSelStart
|
||||||
&& (cachedLength >= n || cachedLength >= mExpectedCursorPosition)) {
|
&& (cachedLength >= n || cachedLength >= mExpectedSelStart)) {
|
||||||
final StringBuilder s = new StringBuilder(mCommittedTextBeforeComposingText);
|
final StringBuilder s = new StringBuilder(mCommittedTextBeforeComposingText);
|
||||||
// We call #toString() here to create a temporary object.
|
// We call #toString() here to create a temporary object.
|
||||||
// In some situations, this method is called on a worker thread, and it's possible
|
// In some situations, this method is called on a worker thread, and it's possible
|
||||||
|
@ -349,10 +349,10 @@ public final class RichInputConnection {
|
||||||
+ remainingChars, 0);
|
+ remainingChars, 0);
|
||||||
mCommittedTextBeforeComposingText.setLength(len);
|
mCommittedTextBeforeComposingText.setLength(len);
|
||||||
}
|
}
|
||||||
if (mExpectedCursorPosition > beforeLength) {
|
if (mExpectedSelStart > beforeLength) {
|
||||||
mExpectedCursorPosition -= beforeLength;
|
mExpectedSelStart -= beforeLength;
|
||||||
} else {
|
} else {
|
||||||
mExpectedCursorPosition = 0;
|
mExpectedSelStart = 0;
|
||||||
}
|
}
|
||||||
if (null != mIC) {
|
if (null != mIC) {
|
||||||
mIC.deleteSurroundingText(beforeLength, afterLength);
|
mIC.deleteSurroundingText(beforeLength, afterLength);
|
||||||
|
@ -386,7 +386,7 @@ public final class RichInputConnection {
|
||||||
switch (keyEvent.getKeyCode()) {
|
switch (keyEvent.getKeyCode()) {
|
||||||
case KeyEvent.KEYCODE_ENTER:
|
case KeyEvent.KEYCODE_ENTER:
|
||||||
mCommittedTextBeforeComposingText.append("\n");
|
mCommittedTextBeforeComposingText.append("\n");
|
||||||
mExpectedCursorPosition += 1;
|
mExpectedSelStart += 1;
|
||||||
break;
|
break;
|
||||||
case KeyEvent.KEYCODE_DEL:
|
case KeyEvent.KEYCODE_DEL:
|
||||||
if (0 == mComposingText.length()) {
|
if (0 == mComposingText.length()) {
|
||||||
|
@ -398,18 +398,18 @@ public final class RichInputConnection {
|
||||||
} else {
|
} else {
|
||||||
mComposingText.delete(mComposingText.length() - 1, mComposingText.length());
|
mComposingText.delete(mComposingText.length() - 1, mComposingText.length());
|
||||||
}
|
}
|
||||||
if (mExpectedCursorPosition > 0) mExpectedCursorPosition -= 1;
|
if (mExpectedSelStart > 0) mExpectedSelStart -= 1;
|
||||||
break;
|
break;
|
||||||
case KeyEvent.KEYCODE_UNKNOWN:
|
case KeyEvent.KEYCODE_UNKNOWN:
|
||||||
if (null != keyEvent.getCharacters()) {
|
if (null != keyEvent.getCharacters()) {
|
||||||
mCommittedTextBeforeComposingText.append(keyEvent.getCharacters());
|
mCommittedTextBeforeComposingText.append(keyEvent.getCharacters());
|
||||||
mExpectedCursorPosition += keyEvent.getCharacters().length();
|
mExpectedSelStart += keyEvent.getCharacters().length();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
final String text = new String(new int[] { keyEvent.getUnicodeChar() }, 0, 1);
|
final String text = new String(new int[] { keyEvent.getUnicodeChar() }, 0, 1);
|
||||||
mCommittedTextBeforeComposingText.append(text);
|
mCommittedTextBeforeComposingText.append(text);
|
||||||
mExpectedCursorPosition += text.length();
|
mExpectedSelStart += text.length();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -443,7 +443,7 @@ public final class RichInputConnection {
|
||||||
public void setComposingText(final CharSequence text, final int newCursorPosition) {
|
public void setComposingText(final CharSequence text, final int newCursorPosition) {
|
||||||
if (DEBUG_BATCH_NESTING) checkBatchEdit();
|
if (DEBUG_BATCH_NESTING) checkBatchEdit();
|
||||||
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
|
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
|
||||||
mExpectedCursorPosition += text.length() - mComposingText.length();
|
mExpectedSelStart += text.length() - mComposingText.length();
|
||||||
mComposingText.setLength(0);
|
mComposingText.setLength(0);
|
||||||
mComposingText.append(text);
|
mComposingText.append(text);
|
||||||
// TODO: support values of i != 1. At this time, this is never called with i != 1.
|
// TODO: support values of i != 1. At this time, this is never called with i != 1.
|
||||||
|
@ -469,7 +469,7 @@ public final class RichInputConnection {
|
||||||
public boolean setSelection(final int start, final int end) {
|
public boolean setSelection(final int start, final int end) {
|
||||||
if (DEBUG_BATCH_NESTING) checkBatchEdit();
|
if (DEBUG_BATCH_NESTING) checkBatchEdit();
|
||||||
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
|
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
|
||||||
mExpectedCursorPosition = start;
|
mExpectedSelStart = start;
|
||||||
if (null != mIC) {
|
if (null != mIC) {
|
||||||
final boolean isIcValid = mIC.setSelection(start, end);
|
final boolean isIcValid = mIC.setSelection(start, end);
|
||||||
if (!isIcValid) {
|
if (!isIcValid) {
|
||||||
|
@ -500,7 +500,7 @@ public final class RichInputConnection {
|
||||||
// text should never be null, but just in case, it's better to insert nothing than to crash
|
// text should never be null, but just in case, it's better to insert nothing than to crash
|
||||||
if (null == text) text = "";
|
if (null == text) text = "";
|
||||||
mCommittedTextBeforeComposingText.append(text);
|
mCommittedTextBeforeComposingText.append(text);
|
||||||
mExpectedCursorPosition += text.length() - mComposingText.length();
|
mExpectedSelStart += text.length() - mComposingText.length();
|
||||||
mComposingText.setLength(0);
|
mComposingText.setLength(0);
|
||||||
if (null != mIC) {
|
if (null != mIC) {
|
||||||
mIC.commitCompletion(completionInfo);
|
mIC.commitCompletion(completionInfo);
|
||||||
|
@ -788,14 +788,14 @@ public final class RichInputConnection {
|
||||||
*/
|
*/
|
||||||
public boolean isBelatedExpectedUpdate(final int oldSelStart, final int newSelStart) {
|
public boolean isBelatedExpectedUpdate(final int oldSelStart, final int newSelStart) {
|
||||||
// If this is an update that arrives at our expected position, it's a belated update.
|
// If this is an update that arrives at our expected position, it's a belated update.
|
||||||
if (newSelStart == mExpectedCursorPosition) return true;
|
if (newSelStart == mExpectedSelStart) return true;
|
||||||
// If this is an update that moves the cursor from our expected position, it must be
|
// If this is an update that moves the cursor from our expected position, it must be
|
||||||
// an explicit move.
|
// an explicit move.
|
||||||
if (oldSelStart == mExpectedCursorPosition) return false;
|
if (oldSelStart == mExpectedSelStart) return false;
|
||||||
// The following returns true if newSelStart is between oldSelStart and
|
// The following returns true if newSelStart is between oldSelStart and
|
||||||
// mCurrentCursorPosition. We assume that if the updated position is between the old
|
// mCurrentCursorPosition. We assume that if the updated position is between the old
|
||||||
// position and the expected position, then it must be a belated update.
|
// position and the expected position, then it must be a belated update.
|
||||||
return (newSelStart - oldSelStart) * (mExpectedCursorPosition - newSelStart) >= 0;
|
return (newSelStart - oldSelStart) * (mExpectedSelStart - newSelStart) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue