resolved conflicts for merge of 8159336b
to master
Change-Id: I9dd726593c6768b1db35305935ee69b0937358efmain
commit
6da1c674fd
|
@ -158,7 +158,7 @@ public class TextDecorator {
|
|||
if (!currentFullScreenMode && fullScreenMode) {
|
||||
// Currently full screen mode is not supported.
|
||||
// TODO: Support full screen mode.
|
||||
hideIndicator();
|
||||
mUiOperator.hideUi();
|
||||
}
|
||||
mIsFullScreenMode = fullScreenMode;
|
||||
}
|
||||
|
@ -193,17 +193,36 @@ public class TextDecorator {
|
|||
layoutImmediately();
|
||||
}
|
||||
|
||||
private void hideIndicator() {
|
||||
/**
|
||||
* 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) {
|
||||
hideIndicator();
|
||||
mUiOperator.hideUi();
|
||||
Log.d(TAG, message);
|
||||
}
|
||||
|
||||
private void cancelLayoutInternalExpectedly(final String message) {
|
||||
hideIndicator();
|
||||
mUiOperator.hideUi();
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, message);
|
||||
}
|
||||
|
@ -261,7 +280,7 @@ public class TextDecorator {
|
|||
lastCharRectFlag & CursorAnchorInfoCompatWrapper.CHARACTER_RECT_TYPE_MASK;
|
||||
if (lastCharRect == null || matrix == null || lastCharRectType !=
|
||||
CursorAnchorInfoCompatWrapper.CHARACTER_RECT_TYPE_FULLY_VISIBLE) {
|
||||
hideIndicator();
|
||||
mUiOperator.hideUi();
|
||||
return;
|
||||
}
|
||||
final RectF segmentStartCharRect = new RectF(lastCharRect);
|
||||
|
@ -312,13 +331,13 @@ public class TextDecorator {
|
|||
if (!TextUtils.isEmpty(composingText)) {
|
||||
// This is an unexpected case.
|
||||
// TODO: Document this.
|
||||
hideIndicator();
|
||||
mUiOperator.hideUi();
|
||||
return;
|
||||
}
|
||||
// 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.
|
||||
if (info.isInsertionMarkerClipped()) {
|
||||
hideIndicator();
|
||||
mUiOperator.hideUi();
|
||||
return;
|
||||
}
|
||||
final float insertionMarkerHolizontal = info.getInsertionMarkerHorizontal();
|
||||
|
|
|
@ -57,7 +57,6 @@ import android.view.inputmethod.InputMethodSubtype;
|
|||
import com.android.inputmethod.accessibility.AccessibilityUtils;
|
||||
import com.android.inputmethod.annotations.UsedForTesting;
|
||||
import com.android.inputmethod.compat.CursorAnchorInfoCompatWrapper;
|
||||
import com.android.inputmethod.compat.InputConnectionCompatUtils;
|
||||
import com.android.inputmethod.compat.InputMethodServiceCompatUtils;
|
||||
import com.android.inputmethod.dictionarypack.DictionaryPackConstants;
|
||||
import com.android.inputmethod.event.Event;
|
||||
|
@ -778,20 +777,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
// is not guaranteed. It may even be called at the same time on a different thread.
|
||||
final RichInputMethodSubtype richSubtype = new RichInputMethodSubtype(subtype);
|
||||
mSubtypeSwitcher.onSubtypeChanged(richSubtype);
|
||||
mInputLogic.onSubtypeChanged(SubtypeLocaleUtils.getCombiningRulesExtraValue(subtype));
|
||||
mInputLogic.onSubtypeChanged(SubtypeLocaleUtils.getCombiningRulesExtraValue(subtype),
|
||||
mSettings.getCurrent());
|
||||
loadKeyboard();
|
||||
}
|
||||
|
||||
private void onStartInputInternal(final EditorInfo editorInfo, final boolean restarting) {
|
||||
super.onStartInput(editorInfo, restarting);
|
||||
if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK) {
|
||||
// AcceptTypedWord feature relies on CursorAnchorInfo.
|
||||
if (mSettings.getCurrent().mShouldShowUiToAcceptTypedWord) {
|
||||
InputConnectionCompatUtils.requestUpdateCursorAnchorInfo(
|
||||
getCurrentInputConnection(), true /* enableMonitor */,
|
||||
true /* requestImmediateCallback */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
|
@ -860,7 +852,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
// span, so we should reset our state unconditionally, even if restarting is true.
|
||||
// We also tell the input logic about the combining rules for the current subtype, so
|
||||
// it can adjust its combiners if needed.
|
||||
mInputLogic.startInput(mSubtypeSwitcher.getCombiningRulesExtraValueOfCurrentSubtype());
|
||||
mInputLogic.startInput(mSubtypeSwitcher.getCombiningRulesExtraValueOfCurrentSubtype(),
|
||||
currentSettingsValues);
|
||||
|
||||
// Note: the following does a round-trip IPC on the main thread: be careful
|
||||
final Locale currentLocale = mSubtypeSwitcher.getCurrentSubtypeLocale();
|
||||
|
|
|
@ -30,7 +30,9 @@ import android.view.inputmethod.CorrectionInfo;
|
|||
import android.view.inputmethod.ExtractedText;
|
||||
import android.view.inputmethod.ExtractedTextRequest;
|
||||
import android.view.inputmethod.InputConnection;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import com.android.inputmethod.compat.InputConnectionCompatUtils;
|
||||
import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
|
||||
import com.android.inputmethod.latin.utils.CapsModeUtils;
|
||||
import com.android.inputmethod.latin.utils.DebugLogUtils;
|
||||
|
@ -906,4 +908,33 @@ public final class RichInputConnection {
|
|||
mIC.setSelection(mExpectedSelStart, mExpectedSelEnd);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean mCursorAnchorInfoMonitorEnabled = false;
|
||||
|
||||
/**
|
||||
* Requests the editor to call back {@link InputMethodManager#updateCursorAnchorInfo}.
|
||||
* @param enableMonitor {@code true} to request the editor to call back the method whenever the
|
||||
* cursor/anchor position is changed.
|
||||
* @param requestImmediateCallback {@code true} to request the editor to call back the method
|
||||
* as soon as possible to notify the current cursor/anchor position to the input method.
|
||||
* @return {@code true} if the request is accepted. Returns {@code false} otherwise, which
|
||||
* includes "not implemented" or "rejected" or "temporarily unavailable" or whatever which
|
||||
* prevents the application from fulfilling the request. (TODO: Improve the API when it turns
|
||||
* out that we actually need more detailed error codes)
|
||||
*/
|
||||
public boolean requestUpdateCursorAnchorInfo(final boolean enableMonitor,
|
||||
final boolean requestImmediateCallback) {
|
||||
final boolean scheduled = InputConnectionCompatUtils.requestUpdateCursorAnchorInfo(mIC,
|
||||
enableMonitor, requestImmediateCallback);
|
||||
mCursorAnchorInfoMonitorEnabled = (scheduled && enableMonitor);
|
||||
return scheduled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if the application reported that the monitor mode of
|
||||
* {@link InputMethodService#onUpdateCursorAnchorInfo(CursorAnchorInfo)} is currently enabled.
|
||||
*/
|
||||
public boolean isCursorAnchorInfoMonitorEnabled() {
|
||||
return mCursorAnchorInfoMonitorEnabled;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ import com.android.inputmethod.latin.SuggestedWords;
|
|||
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
|
||||
import com.android.inputmethod.latin.WordComposer;
|
||||
import com.android.inputmethod.latin.define.DebugFlags;
|
||||
import com.android.inputmethod.latin.define.ProductionFlags;
|
||||
import com.android.inputmethod.latin.settings.SettingsValues;
|
||||
import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion;
|
||||
import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
|
||||
|
@ -140,8 +141,9 @@ public final class InputLogic {
|
|||
* Call this when input starts or restarts in some editor (typically, in onStartInputView).
|
||||
*
|
||||
* @param combiningSpec the combining spec string for this subtype
|
||||
* @param settingsValues the current settings values
|
||||
*/
|
||||
public void startInput(final String combiningSpec) {
|
||||
public void startInput(final String combiningSpec, final SettingsValues settingsValues) {
|
||||
mEnteredText = null;
|
||||
mWordComposer.restartCombining(combiningSpec);
|
||||
resetComposingState(true /* alsoResetLastComposedWord */);
|
||||
|
@ -159,15 +161,24 @@ public final class InputLogic {
|
|||
} else {
|
||||
mInputLogicHandler.reset();
|
||||
}
|
||||
|
||||
if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK) {
|
||||
// AcceptTypedWord feature relies on CursorAnchorInfo.
|
||||
if (settingsValues.mShouldShowUiToAcceptTypedWord) {
|
||||
mConnection.requestUpdateCursorAnchorInfo(true /* enableMonitor */,
|
||||
true /* requestImmediateCallback */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this when the subtype changes.
|
||||
* @param combiningSpec the spec string for the combining rules
|
||||
* @param settingsValues the current settings values
|
||||
*/
|
||||
public void onSubtypeChanged(final String combiningSpec) {
|
||||
public void onSubtypeChanged(final String combiningSpec, final SettingsValues settingsValues) {
|
||||
finishInput();
|
||||
startInput(combiningSpec);
|
||||
startInput(combiningSpec, settingsValues);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -649,7 +660,7 @@ public final class InputLogic {
|
|||
// 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
|
||||
// the practice.
|
||||
mConnection.setComposingText(textWithUnderline, 1);
|
||||
setComposingTextInternal(textWithUnderline, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -672,7 +683,7 @@ public final class InputLogic {
|
|||
inputTransaction.setDidAffectContents();
|
||||
}
|
||||
if (mWordComposer.isComposingWord()) {
|
||||
mConnection.setComposingText(mWordComposer.getTypedWord(), 1);
|
||||
setComposingTextInternal(mWordComposer.getTypedWord(), 1);
|
||||
inputTransaction.setDidAffectContents();
|
||||
inputTransaction.setRequiresUpdateSuggestions();
|
||||
}
|
||||
|
@ -908,8 +919,7 @@ public final class InputLogic {
|
|||
if (mWordComposer.isSingleLetter()) {
|
||||
mWordComposer.setCapitalizedModeAtStartComposingTime(inputTransaction.mShiftState);
|
||||
}
|
||||
mConnection.setComposingText(getTextWithUnderline(
|
||||
mWordComposer.getTypedWord()), 1);
|
||||
setComposingTextInternal(getTextWithUnderline(mWordComposer.getTypedWord()), 1);
|
||||
} else {
|
||||
final boolean swapWeakSpace = tryStripSpaceAndReturnWhetherShouldSwapInstead(event,
|
||||
inputTransaction);
|
||||
|
@ -1072,7 +1082,7 @@ public final class InputLogic {
|
|||
mWordComposer.applyProcessedEvent(event);
|
||||
}
|
||||
if (mWordComposer.isComposingWord()) {
|
||||
mConnection.setComposingText(getTextWithUnderline(mWordComposer.getTypedWord()), 1);
|
||||
setComposingTextInternal(getTextWithUnderline(mWordComposer.getTypedWord()), 1);
|
||||
} else {
|
||||
mConnection.commitText("", 1);
|
||||
}
|
||||
|
@ -1640,7 +1650,7 @@ public final class InputLogic {
|
|||
final int[] codePoints = StringUtils.toCodePointArray(stringToCommit);
|
||||
mWordComposer.setComposingWord(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.
|
||||
mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
|
||||
|
@ -1973,10 +1983,10 @@ public final class InputLogic {
|
|||
}
|
||||
final String lastWord = batchInputText.substring(indexOfLastSpace);
|
||||
mWordComposer.setBatchInputWord(lastWord);
|
||||
mConnection.setComposingText(lastWord, 1);
|
||||
setComposingTextInternal(lastWord, 1);
|
||||
} else {
|
||||
mWordComposer.setBatchInputWord(batchInputText);
|
||||
mConnection.setComposingText(batchInputText, 1);
|
||||
setComposingTextInternal(batchInputText, 1);
|
||||
}
|
||||
mConnection.endBatchEdit();
|
||||
// Space state must be updated before calling updateShiftState
|
||||
|
@ -2175,6 +2185,24 @@ public final class InputLogic {
|
|||
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
|
||||
// TextDecorator.
|
||||
|
@ -2221,6 +2249,10 @@ public final class InputLogic {
|
|||
*/
|
||||
private boolean shouldShowCommitIndicator(final SuggestedWords suggestedWords,
|
||||
final SettingsValues settingsValues) {
|
||||
if (!mConnection.isCursorAnchorInfoMonitorEnabled()) {
|
||||
// We cannot help in this case because we are heavily relying on this new API.
|
||||
return false;
|
||||
}
|
||||
if (!settingsValues.mShouldShowUiToAcceptTypedWord) {
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue