* commit '8a413a2a62788cef59e2cb0a4362392e036cd7be': Introduce a mechanism to hide the indicator speculatively
This commit is contained in:
commit
2b06811843
2 changed files with 52 additions and 16 deletions
|
@ -158,7 +158,7 @@ public class TextDecorator {
|
||||||
if (!currentFullScreenMode && fullScreenMode) {
|
if (!currentFullScreenMode && fullScreenMode) {
|
||||||
// Currently full screen mode is not supported.
|
// Currently full screen mode is not supported.
|
||||||
// TODO: Support full screen mode.
|
// TODO: Support full screen mode.
|
||||||
hideIndicator();
|
mUiOperator.hideUi();
|
||||||
}
|
}
|
||||||
mIsFullScreenMode = fullScreenMode;
|
mIsFullScreenMode = fullScreenMode;
|
||||||
}
|
}
|
||||||
|
@ -193,17 +193,36 @@ public class TextDecorator {
|
||||||
layoutImmediately();
|
layoutImmediately();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void hideIndicator() {
|
/**
|
||||||
mUiOperator.hideUi();
|
* Hides indicator if the new composing text doesn't match the expected one.
|
||||||
|
*
|
||||||
|
* <p>Calling this method is optional but recommended whenever the new composition is passed to
|
||||||
|
* the application. The motivation of this method is to reduce the UI latency. With this method,
|
||||||
|
* we can hide the indicator without waiting the arrival of the
|
||||||
|
* {@link InputMethodService#onUpdateCursorAnchorInfo(CursorAnchorInfo)} callback, assuming that
|
||||||
|
* the application accepts the new composing text without any modification. Even if this
|
||||||
|
* assumption is false, the indicator will be shown again when
|
||||||
|
* {@link InputMethodService#onUpdateCursorAnchorInfo(CursorAnchorInfo)} is actually received.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param newComposingText the new composing text that is being passed to the application.
|
||||||
|
*/
|
||||||
|
public void hideIndicatorIfNecessary(final CharSequence newComposingText) {
|
||||||
|
if (mMode != MODE_COMMIT && mMode != MODE_ADD_TO_DICTIONARY) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!TextUtils.equals(newComposingText, mWaitingWord.mWord)) {
|
||||||
|
mUiOperator.hideUi();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancelLayoutInternalUnexpectedly(final String message) {
|
private void cancelLayoutInternalUnexpectedly(final String message) {
|
||||||
hideIndicator();
|
mUiOperator.hideUi();
|
||||||
Log.d(TAG, message);
|
Log.d(TAG, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancelLayoutInternalExpectedly(final String message) {
|
private void cancelLayoutInternalExpectedly(final String message) {
|
||||||
hideIndicator();
|
mUiOperator.hideUi();
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, message);
|
Log.d(TAG, message);
|
||||||
}
|
}
|
||||||
|
@ -261,7 +280,7 @@ public class TextDecorator {
|
||||||
lastCharRectFlag & CursorAnchorInfoCompatWrapper.CHARACTER_RECT_TYPE_MASK;
|
lastCharRectFlag & CursorAnchorInfoCompatWrapper.CHARACTER_RECT_TYPE_MASK;
|
||||||
if (lastCharRect == null || matrix == null || lastCharRectType !=
|
if (lastCharRect == null || matrix == null || lastCharRectType !=
|
||||||
CursorAnchorInfoCompatWrapper.CHARACTER_RECT_TYPE_FULLY_VISIBLE) {
|
CursorAnchorInfoCompatWrapper.CHARACTER_RECT_TYPE_FULLY_VISIBLE) {
|
||||||
hideIndicator();
|
mUiOperator.hideUi();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final RectF segmentStartCharRect = new RectF(lastCharRect);
|
final RectF segmentStartCharRect = new RectF(lastCharRect);
|
||||||
|
@ -312,13 +331,13 @@ public class TextDecorator {
|
||||||
if (!TextUtils.isEmpty(composingText)) {
|
if (!TextUtils.isEmpty(composingText)) {
|
||||||
// This is an unexpected case.
|
// This is an unexpected case.
|
||||||
// TODO: Document this.
|
// TODO: Document this.
|
||||||
hideIndicator();
|
mUiOperator.hideUi();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// In MODE_ADD_TO_DICTIONARY, we cannot retrieve the character position at all because
|
// In MODE_ADD_TO_DICTIONARY, we cannot retrieve the character position at all because
|
||||||
// of the lack of composing text. We will use the insertion marker position instead.
|
// of the lack of composing text. We will use the insertion marker position instead.
|
||||||
if (info.isInsertionMarkerClipped()) {
|
if (info.isInsertionMarkerClipped()) {
|
||||||
hideIndicator();
|
mUiOperator.hideUi();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final float insertionMarkerHolizontal = info.getInsertionMarkerHorizontal();
|
final float insertionMarkerHolizontal = info.getInsertionMarkerHorizontal();
|
||||||
|
|
|
@ -649,7 +649,7 @@ public final class InputLogic {
|
||||||
// message, this is called outside any batch edit. Potentially, this may result in some
|
// message, this is called outside any batch edit. Potentially, this may result in some
|
||||||
// janky flickering of the screen, although the display speed makes it unlikely in
|
// janky flickering of the screen, although the display speed makes it unlikely in
|
||||||
// the practice.
|
// the practice.
|
||||||
mConnection.setComposingText(textWithUnderline, 1);
|
setComposingTextInternal(textWithUnderline, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -672,7 +672,7 @@ public final class InputLogic {
|
||||||
inputTransaction.setDidAffectContents();
|
inputTransaction.setDidAffectContents();
|
||||||
}
|
}
|
||||||
if (mWordComposer.isComposingWord()) {
|
if (mWordComposer.isComposingWord()) {
|
||||||
mConnection.setComposingText(mWordComposer.getTypedWord(), 1);
|
setComposingTextInternal(mWordComposer.getTypedWord(), 1);
|
||||||
inputTransaction.setDidAffectContents();
|
inputTransaction.setDidAffectContents();
|
||||||
inputTransaction.setRequiresUpdateSuggestions();
|
inputTransaction.setRequiresUpdateSuggestions();
|
||||||
}
|
}
|
||||||
|
@ -908,8 +908,7 @@ public final class InputLogic {
|
||||||
if (mWordComposer.isSingleLetter()) {
|
if (mWordComposer.isSingleLetter()) {
|
||||||
mWordComposer.setCapitalizedModeAtStartComposingTime(inputTransaction.mShiftState);
|
mWordComposer.setCapitalizedModeAtStartComposingTime(inputTransaction.mShiftState);
|
||||||
}
|
}
|
||||||
mConnection.setComposingText(getTextWithUnderline(
|
setComposingTextInternal(getTextWithUnderline(mWordComposer.getTypedWord()), 1);
|
||||||
mWordComposer.getTypedWord()), 1);
|
|
||||||
} else {
|
} else {
|
||||||
final boolean swapWeakSpace = tryStripSpaceAndReturnWhetherShouldSwapInstead(event,
|
final boolean swapWeakSpace = tryStripSpaceAndReturnWhetherShouldSwapInstead(event,
|
||||||
inputTransaction);
|
inputTransaction);
|
||||||
|
@ -1072,7 +1071,7 @@ public final class InputLogic {
|
||||||
mWordComposer.applyProcessedEvent(event);
|
mWordComposer.applyProcessedEvent(event);
|
||||||
}
|
}
|
||||||
if (mWordComposer.isComposingWord()) {
|
if (mWordComposer.isComposingWord()) {
|
||||||
mConnection.setComposingText(getTextWithUnderline(mWordComposer.getTypedWord()), 1);
|
setComposingTextInternal(getTextWithUnderline(mWordComposer.getTypedWord()), 1);
|
||||||
} else {
|
} else {
|
||||||
mConnection.commitText("", 1);
|
mConnection.commitText("", 1);
|
||||||
}
|
}
|
||||||
|
@ -1640,7 +1639,7 @@ public final class InputLogic {
|
||||||
final int[] codePoints = StringUtils.toCodePointArray(stringToCommit);
|
final int[] codePoints = StringUtils.toCodePointArray(stringToCommit);
|
||||||
mWordComposer.setComposingWord(codePoints,
|
mWordComposer.setComposingWord(codePoints,
|
||||||
mLatinIME.getCoordinatesForCurrentKeyboard(codePoints));
|
mLatinIME.getCoordinatesForCurrentKeyboard(codePoints));
|
||||||
mConnection.setComposingText(textToCommit, 1);
|
setComposingTextInternal(textToCommit, 1);
|
||||||
}
|
}
|
||||||
// Don't restart suggestion yet. We'll restart if the user deletes the separator.
|
// Don't restart suggestion yet. We'll restart if the user deletes the separator.
|
||||||
mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
|
mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
|
||||||
|
@ -1973,10 +1972,10 @@ public final class InputLogic {
|
||||||
}
|
}
|
||||||
final String lastWord = batchInputText.substring(indexOfLastSpace);
|
final String lastWord = batchInputText.substring(indexOfLastSpace);
|
||||||
mWordComposer.setBatchInputWord(lastWord);
|
mWordComposer.setBatchInputWord(lastWord);
|
||||||
mConnection.setComposingText(lastWord, 1);
|
setComposingTextInternal(lastWord, 1);
|
||||||
} else {
|
} else {
|
||||||
mWordComposer.setBatchInputWord(batchInputText);
|
mWordComposer.setBatchInputWord(batchInputText);
|
||||||
mConnection.setComposingText(batchInputText, 1);
|
setComposingTextInternal(batchInputText, 1);
|
||||||
}
|
}
|
||||||
mConnection.endBatchEdit();
|
mConnection.endBatchEdit();
|
||||||
// Space state must be updated before calling updateShiftState
|
// Space state must be updated before calling updateShiftState
|
||||||
|
@ -2175,6 +2174,24 @@ public final class InputLogic {
|
||||||
inputStyle, sequenceNumber, callback);
|
inputStyle, sequenceNumber, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used as an injection point for each call of
|
||||||
|
* {@link RichInputConnection#setComposingText(CharSequence, int)}.
|
||||||
|
*
|
||||||
|
* <p>Currently using this method is optional and you can still directly call
|
||||||
|
* {@link RichInputConnection#setComposingText(CharSequence, int)}, but it is recommended to
|
||||||
|
* use this method whenever possible to optimize the behavior of {@link TextDecorator}.<p>
|
||||||
|
* <p>TODO: Should we move this mechanism to {@link RichInputConnection}?</p>
|
||||||
|
*
|
||||||
|
* @param newComposingText the composing text to be set
|
||||||
|
* @param newCursorPosition the new cursor position
|
||||||
|
*/
|
||||||
|
private void setComposingTextInternal(final CharSequence newComposingText,
|
||||||
|
final int newCursorPosition) {
|
||||||
|
mConnection.setComposingText(newComposingText, newCursorPosition);
|
||||||
|
mTextDecorator.hideIndicatorIfNecessary(newComposingText);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Following methods are tentatively placed in this class for the integration with
|
// Following methods are tentatively placed in this class for the integration with
|
||||||
// TextDecorator.
|
// TextDecorator.
|
||||||
|
|
Loading…
Reference in a new issue