[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
main
Jean Chalard 2014-06-27 21:38:57 +09:00
parent 3fb5a541a4
commit 6345562e2b
3 changed files with 56 additions and 29 deletions

View File

@ -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;
}
}

View File

@ -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) {

View File

@ -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();