From 6345562e2b351221a9bc0341f7dbd26095290b64 Mon Sep 17 00:00:00 2001 From: Jean Chalard Date: Fri, 27 Jun 2014 21:38:57 +0900 Subject: [PATCH] [SD4] Restart suggestions on language change ...otherwise we can't recompute the composition when we change scripts. This also fixes when we register that we need to take note that the current subtype was used. Luckily this is a good occasion for some cleanup that I've wanted to do for some time: use InputTransaction for onTextInput (with the goal to ultimately remove it entirely) Bug: 15840116 Change-Id: Ie4f4f9157b66b79237eeb3db75535803124d3e19 --- .../inputmethod/event/InputTransaction.java | 16 ++++++++ .../android/inputmethod/latin/LatinIME.java | 38 +++++++++---------- .../latin/inputlogic/InputLogic.java | 31 ++++++++++----- 3 files changed, 56 insertions(+), 29 deletions(-) diff --git a/java/src/com/android/inputmethod/event/InputTransaction.java b/java/src/com/android/inputmethod/event/InputTransaction.java index 4fe9b403e..cdff265c6 100644 --- a/java/src/com/android/inputmethod/event/InputTransaction.java +++ b/java/src/com/android/inputmethod/event/InputTransaction.java @@ -41,6 +41,7 @@ public class InputTransaction { // Outputs private int mRequiredShiftUpdate = SHIFT_NO_UPDATE; private boolean mRequiresUpdateSuggestions = false; + private boolean mDidAffectContents = false; public InputTransaction(final SettingsValues settingsValues, final Event event, final long timestamp, final int spaceState, final int shiftState) { @@ -81,4 +82,19 @@ public class InputTransaction { public boolean requiresUpdateSuggestions() { return mRequiresUpdateSuggestions; } + + /** + * Indicate that this transaction affected the contents of the editor. + */ + public void setDidAffectContents() { + mDidAffectContents = true; + } + + /** + * Find out whether this transaction affected contents of the editor. + * @return Whether this transaction affected contents of the editor. + */ + public boolean didAffectContents() { + return mDidAffectContents; + } } diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index c9a4bf5a1..865ff07d6 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -232,10 +232,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen break; case MSG_REOPEN_DICTIONARIES: latinIme.resetSuggest(); - // In theory we could call latinIme.updateSuggestionStrip() right away, but - // in the practice, the dictionary is not finished opening yet so we wouldn't - // get any suggestions. Wait one frame. - postUpdateSuggestionStrip(); + // We need to re-evaluate the currently composing word in case the script has + // changed. + postResumeSuggestions(true /* shouldIncludeResumedWordInSuggestions */); break; case MSG_UPDATE_TAIL_BATCH_INPUT_COMPLETED: latinIme.mInputLogic.onUpdateTailBatchInputCompleted( @@ -447,22 +446,22 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen static final class SubtypeState { private InputMethodSubtype mLastActiveSubtype; - private boolean mCurrentSubtypeUsed; + private boolean mCurrentSubtypeHasBeenUsed; - public void currentSubtypeUsed() { - mCurrentSubtypeUsed = true; + public void setCurrentSubtypeHasBeenUsed() { + mCurrentSubtypeHasBeenUsed = true; } public void switchSubtype(final IBinder token, final RichInputMethodManager richImm) { final InputMethodSubtype currentSubtype = richImm.getInputMethodManager() .getCurrentInputMethodSubtype(); final InputMethodSubtype lastActiveSubtype = mLastActiveSubtype; - final boolean currentSubtypeUsed = mCurrentSubtypeUsed; - if (currentSubtypeUsed) { + final boolean currentSubtypeHasBeenUsed = mCurrentSubtypeHasBeenUsed; + if (currentSubtypeHasBeenUsed) { mLastActiveSubtype = currentSubtype; - mCurrentSubtypeUsed = false; + mCurrentSubtypeHasBeenUsed = false; } - if (currentSubtypeUsed + if (currentSubtypeHasBeenUsed && richImm.checkIfSubtypeBelongsToThisImeAndEnabled(lastActiveSubtype) && !currentSubtype.equals(lastActiveSubtype)) { richImm.setInputMethodAndSubtype(token, lastActiveSubtype); @@ -796,8 +795,7 @@ 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(restarting, editorInfo, - mSubtypeSwitcher.getCombiningRulesExtraValueOfCurrentSubtype()); + mInputLogic.startInput(mSubtypeSwitcher.getCombiningRulesExtraValueOfCurrentSubtype()); // Note: the following does a round-trip IPC on the main thread: be careful final Locale currentLocale = mSubtypeSwitcher.getCurrentSubtypeLocale(); @@ -930,12 +928,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mKeyboardSwitcher.requestUpdatingShiftState(getCurrentAutoCapsState(), getCurrentRecapitalizeState()); } - - mSubtypeState.currentSubtypeUsed(); } @Override - public void onUpdateCursor(Rect rect) { + public void onUpdateCursor(final Rect rect) { if (DEBUG) { Log.i(TAG, "onUpdateCursor:" + rect.toShortString()); } @@ -1268,9 +1264,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen public void onTextInput(final String rawText) { // TODO: have the keyboard pass the correct key code when we need it. final Event event = Event.createSoftwareTextEvent(rawText, Event.NOT_A_KEY_CODE); - mInputLogic.onTextInput(mSettings.getCurrent(), event, mHandler); - mKeyboardSwitcher.requestUpdatingShiftState(getCurrentAutoCapsState(), - getCurrentRecapitalizeState()); + final InputTransaction completeInputTransaction = + mInputLogic.onTextInput(mSettings.getCurrent(), event, + mKeyboardSwitcher.getKeyboardShiftMode(), mHandler); + updateStateAfterInputTransaction(completeInputTransaction); mKeyboardSwitcher.onCodeInput(Constants.CODE_OUTPUT_TEXT, getCurrentAutoCapsState(), getCurrentRecapitalizeState()); } @@ -1490,6 +1487,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (inputTransaction.requiresUpdateSuggestions()) { mHandler.postUpdateSuggestionStrip(); } + if (inputTransaction.didAffectContents()) { + mSubtypeState.setCurrentSubtypeHasBeenUsed(); + } } private void hapticAndAudioFeedback(final int code, final int repeatCount) { diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java index 158663d96..8831d36f7 100644 --- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java @@ -119,17 +119,10 @@ public final class InputLogic { * Initializes the input logic for input in an editor. * * Call this when input starts or restarts in some editor (typically, in onStartInputView). - * If the input is starting in the same field as before, set `restarting' to true. This allows - * the input logic to reset only necessary stuff and save performance. Also, when restarting - * some things must not be done (for example, the keyboard should not be reset to the - * alphabetic layout), so do not send false to this just in case. * - * @param restarting whether input is starting in the same field as before. Unused for now. - * @param editorInfo the editorInfo associated with the editor. * @param combiningSpec the combining spec string for this subtype */ - public void startInput(final boolean restarting, final EditorInfo editorInfo, - final String combiningSpec) { + public void startInput(final String combiningSpec) { mEnteredText = null; mWordComposer.restartCombining(combiningSpec); resetComposingState(true /* alsoResetLastComposedWord */); @@ -154,7 +147,8 @@ public final class InputLogic { * @param combiningSpec the spec string for the combining rules */ public void onSubtypeChanged(final String combiningSpec) { - mWordComposer.restartCombining(combiningSpec); + finishInput(); + startInput(combiningSpec); } /** @@ -187,11 +181,16 @@ public final class InputLogic { * * @param settingsValues the current values of the settings. * @param event the input event containing the data. + * @return the complete transaction object */ - public void onTextInput(final SettingsValues settingsValues, final Event event, + public InputTransaction onTextInput(final SettingsValues settingsValues, final Event event, + final int keyboardShiftMode, // TODO: remove this argument final LatinIME.UIHandler handler) { final String rawText = event.mText.toString(); + final InputTransaction inputTransaction = new InputTransaction(settingsValues, event, + SystemClock.uptimeMillis(), mSpaceState, + getActualCapsMode(settingsValues, keyboardShiftMode)); mConnection.beginBatchEdit(); if (mWordComposer.isComposingWord()) { commitCurrentAutoCorrection(settingsValues, rawText, handler); @@ -208,6 +207,9 @@ public final class InputLogic { // Space state must be updated before calling updateShiftState mSpaceState = SpaceState.NONE; mEnteredText = text; + inputTransaction.setDidAffectContents(); + inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW); + return inputTransaction; } /** @@ -238,6 +240,9 @@ public final class InputLogic { final Event event = Event.createSuggestionPickedEvent(suggestionInfo); final InputTransaction inputTransaction = new InputTransaction(settingsValues, event, SystemClock.uptimeMillis(), mSpaceState, keyboardShiftState); + // Manual pick affects the contents of the editor, so we take note of this. It's important + // for the sequence of language switching. + inputTransaction.setDidAffectContents(); mConnection.beginBatchEdit(); if (SpaceState.PHANTOM == mSpaceState && suggestion.length() > 0 // In the batch input mode, a manually picked suggested word should just replace @@ -404,6 +409,8 @@ public final class InputLogic { switch (event.mKeyCode) { case Constants.CODE_DELETE: handleBackspace(inputTransaction, currentKeyboardScriptId); + // Backspace is a functional key, but it affects the contents of the editor. + inputTransaction.setDidAffectContents(); break; case Constants.CODE_SHIFT: performRecapitalization(inputTransaction.mSettingsValues); @@ -457,11 +464,15 @@ public final class InputLogic { inputTransaction.mTimestamp, inputTransaction.mSpaceState, inputTransaction.mShiftState); didAutoCorrect = handleNonSpecialCharacter(tmpTransaction, handler); + // Shift + Enter is treated as a functional key but it results in adding a new + // line, so that does affect the contents of the editor. + inputTransaction.setDidAffectContents(); break; default: throw new RuntimeException("Unknown key code : " + event.mKeyCode); } } else { + inputTransaction.setDidAffectContents(); switch (event.mCodePoint) { case Constants.CODE_ENTER: final EditorInfo editorInfo = getCurrentInputEditorInfo();