[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: Ie4f4f9157b66b79237eeb3db75535803124d3e19main
parent
3fb5a541a4
commit
6345562e2b
|
@ -41,6 +41,7 @@ public class InputTransaction {
|
||||||
// Outputs
|
// Outputs
|
||||||
private int mRequiredShiftUpdate = SHIFT_NO_UPDATE;
|
private int mRequiredShiftUpdate = SHIFT_NO_UPDATE;
|
||||||
private boolean mRequiresUpdateSuggestions = false;
|
private boolean mRequiresUpdateSuggestions = false;
|
||||||
|
private boolean mDidAffectContents = false;
|
||||||
|
|
||||||
public InputTransaction(final SettingsValues settingsValues, final Event event,
|
public InputTransaction(final SettingsValues settingsValues, final Event event,
|
||||||
final long timestamp, final int spaceState, final int shiftState) {
|
final long timestamp, final int spaceState, final int shiftState) {
|
||||||
|
@ -81,4 +82,19 @@ public class InputTransaction {
|
||||||
public boolean requiresUpdateSuggestions() {
|
public boolean requiresUpdateSuggestions() {
|
||||||
return mRequiresUpdateSuggestions;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -232,10 +232,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
break;
|
break;
|
||||||
case MSG_REOPEN_DICTIONARIES:
|
case MSG_REOPEN_DICTIONARIES:
|
||||||
latinIme.resetSuggest();
|
latinIme.resetSuggest();
|
||||||
// In theory we could call latinIme.updateSuggestionStrip() right away, but
|
// We need to re-evaluate the currently composing word in case the script has
|
||||||
// in the practice, the dictionary is not finished opening yet so we wouldn't
|
// changed.
|
||||||
// get any suggestions. Wait one frame.
|
postResumeSuggestions(true /* shouldIncludeResumedWordInSuggestions */);
|
||||||
postUpdateSuggestionStrip();
|
|
||||||
break;
|
break;
|
||||||
case MSG_UPDATE_TAIL_BATCH_INPUT_COMPLETED:
|
case MSG_UPDATE_TAIL_BATCH_INPUT_COMPLETED:
|
||||||
latinIme.mInputLogic.onUpdateTailBatchInputCompleted(
|
latinIme.mInputLogic.onUpdateTailBatchInputCompleted(
|
||||||
|
@ -447,22 +446,22 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
|
|
||||||
static final class SubtypeState {
|
static final class SubtypeState {
|
||||||
private InputMethodSubtype mLastActiveSubtype;
|
private InputMethodSubtype mLastActiveSubtype;
|
||||||
private boolean mCurrentSubtypeUsed;
|
private boolean mCurrentSubtypeHasBeenUsed;
|
||||||
|
|
||||||
public void currentSubtypeUsed() {
|
public void setCurrentSubtypeHasBeenUsed() {
|
||||||
mCurrentSubtypeUsed = true;
|
mCurrentSubtypeHasBeenUsed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void switchSubtype(final IBinder token, final RichInputMethodManager richImm) {
|
public void switchSubtype(final IBinder token, final RichInputMethodManager richImm) {
|
||||||
final InputMethodSubtype currentSubtype = richImm.getInputMethodManager()
|
final InputMethodSubtype currentSubtype = richImm.getInputMethodManager()
|
||||||
.getCurrentInputMethodSubtype();
|
.getCurrentInputMethodSubtype();
|
||||||
final InputMethodSubtype lastActiveSubtype = mLastActiveSubtype;
|
final InputMethodSubtype lastActiveSubtype = mLastActiveSubtype;
|
||||||
final boolean currentSubtypeUsed = mCurrentSubtypeUsed;
|
final boolean currentSubtypeHasBeenUsed = mCurrentSubtypeHasBeenUsed;
|
||||||
if (currentSubtypeUsed) {
|
if (currentSubtypeHasBeenUsed) {
|
||||||
mLastActiveSubtype = currentSubtype;
|
mLastActiveSubtype = currentSubtype;
|
||||||
mCurrentSubtypeUsed = false;
|
mCurrentSubtypeHasBeenUsed = false;
|
||||||
}
|
}
|
||||||
if (currentSubtypeUsed
|
if (currentSubtypeHasBeenUsed
|
||||||
&& richImm.checkIfSubtypeBelongsToThisImeAndEnabled(lastActiveSubtype)
|
&& richImm.checkIfSubtypeBelongsToThisImeAndEnabled(lastActiveSubtype)
|
||||||
&& !currentSubtype.equals(lastActiveSubtype)) {
|
&& !currentSubtype.equals(lastActiveSubtype)) {
|
||||||
richImm.setInputMethodAndSubtype(token, 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.
|
// 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
|
// We also tell the input logic about the combining rules for the current subtype, so
|
||||||
// it can adjust its combiners if needed.
|
// it can adjust its combiners if needed.
|
||||||
mInputLogic.startInput(restarting, editorInfo,
|
mInputLogic.startInput(mSubtypeSwitcher.getCombiningRulesExtraValueOfCurrentSubtype());
|
||||||
mSubtypeSwitcher.getCombiningRulesExtraValueOfCurrentSubtype());
|
|
||||||
|
|
||||||
// Note: the following does a round-trip IPC on the main thread: be careful
|
// Note: the following does a round-trip IPC on the main thread: be careful
|
||||||
final Locale currentLocale = mSubtypeSwitcher.getCurrentSubtypeLocale();
|
final Locale currentLocale = mSubtypeSwitcher.getCurrentSubtypeLocale();
|
||||||
|
@ -930,12 +928,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
mKeyboardSwitcher.requestUpdatingShiftState(getCurrentAutoCapsState(),
|
mKeyboardSwitcher.requestUpdatingShiftState(getCurrentAutoCapsState(),
|
||||||
getCurrentRecapitalizeState());
|
getCurrentRecapitalizeState());
|
||||||
}
|
}
|
||||||
|
|
||||||
mSubtypeState.currentSubtypeUsed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpdateCursor(Rect rect) {
|
public void onUpdateCursor(final Rect rect) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.i(TAG, "onUpdateCursor:" + rect.toShortString());
|
Log.i(TAG, "onUpdateCursor:" + rect.toShortString());
|
||||||
}
|
}
|
||||||
|
@ -1268,9 +1264,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
public void onTextInput(final String rawText) {
|
public void onTextInput(final String rawText) {
|
||||||
// TODO: have the keyboard pass the correct key code when we need it.
|
// TODO: have the keyboard pass the correct key code when we need it.
|
||||||
final Event event = Event.createSoftwareTextEvent(rawText, Event.NOT_A_KEY_CODE);
|
final Event event = Event.createSoftwareTextEvent(rawText, Event.NOT_A_KEY_CODE);
|
||||||
mInputLogic.onTextInput(mSettings.getCurrent(), event, mHandler);
|
final InputTransaction completeInputTransaction =
|
||||||
mKeyboardSwitcher.requestUpdatingShiftState(getCurrentAutoCapsState(),
|
mInputLogic.onTextInput(mSettings.getCurrent(), event,
|
||||||
getCurrentRecapitalizeState());
|
mKeyboardSwitcher.getKeyboardShiftMode(), mHandler);
|
||||||
|
updateStateAfterInputTransaction(completeInputTransaction);
|
||||||
mKeyboardSwitcher.onCodeInput(Constants.CODE_OUTPUT_TEXT, getCurrentAutoCapsState(),
|
mKeyboardSwitcher.onCodeInput(Constants.CODE_OUTPUT_TEXT, getCurrentAutoCapsState(),
|
||||||
getCurrentRecapitalizeState());
|
getCurrentRecapitalizeState());
|
||||||
}
|
}
|
||||||
|
@ -1490,6 +1487,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
if (inputTransaction.requiresUpdateSuggestions()) {
|
if (inputTransaction.requiresUpdateSuggestions()) {
|
||||||
mHandler.postUpdateSuggestionStrip();
|
mHandler.postUpdateSuggestionStrip();
|
||||||
}
|
}
|
||||||
|
if (inputTransaction.didAffectContents()) {
|
||||||
|
mSubtypeState.setCurrentSubtypeHasBeenUsed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void hapticAndAudioFeedback(final int code, final int repeatCount) {
|
private void hapticAndAudioFeedback(final int code, final int repeatCount) {
|
||||||
|
|
|
@ -119,17 +119,10 @@ public final class InputLogic {
|
||||||
* Initializes the input logic for input in an editor.
|
* Initializes the input logic for input in an editor.
|
||||||
*
|
*
|
||||||
* Call this when input starts or restarts in some editor (typically, in onStartInputView).
|
* 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
|
* @param combiningSpec the combining spec string for this subtype
|
||||||
*/
|
*/
|
||||||
public void startInput(final boolean restarting, final EditorInfo editorInfo,
|
public void startInput(final String combiningSpec) {
|
||||||
final String combiningSpec) {
|
|
||||||
mEnteredText = null;
|
mEnteredText = null;
|
||||||
mWordComposer.restartCombining(combiningSpec);
|
mWordComposer.restartCombining(combiningSpec);
|
||||||
resetComposingState(true /* alsoResetLastComposedWord */);
|
resetComposingState(true /* alsoResetLastComposedWord */);
|
||||||
|
@ -154,7 +147,8 @@ public final class InputLogic {
|
||||||
* @param combiningSpec the spec string for the combining rules
|
* @param combiningSpec the spec string for the combining rules
|
||||||
*/
|
*/
|
||||||
public void onSubtypeChanged(final String combiningSpec) {
|
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 settingsValues the current values of the settings.
|
||||||
* @param event the input event containing the data.
|
* @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
|
// TODO: remove this argument
|
||||||
final LatinIME.UIHandler handler) {
|
final LatinIME.UIHandler handler) {
|
||||||
final String rawText = event.mText.toString();
|
final String rawText = event.mText.toString();
|
||||||
|
final InputTransaction inputTransaction = new InputTransaction(settingsValues, event,
|
||||||
|
SystemClock.uptimeMillis(), mSpaceState,
|
||||||
|
getActualCapsMode(settingsValues, keyboardShiftMode));
|
||||||
mConnection.beginBatchEdit();
|
mConnection.beginBatchEdit();
|
||||||
if (mWordComposer.isComposingWord()) {
|
if (mWordComposer.isComposingWord()) {
|
||||||
commitCurrentAutoCorrection(settingsValues, rawText, handler);
|
commitCurrentAutoCorrection(settingsValues, rawText, handler);
|
||||||
|
@ -208,6 +207,9 @@ public final class InputLogic {
|
||||||
// Space state must be updated before calling updateShiftState
|
// Space state must be updated before calling updateShiftState
|
||||||
mSpaceState = SpaceState.NONE;
|
mSpaceState = SpaceState.NONE;
|
||||||
mEnteredText = text;
|
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 Event event = Event.createSuggestionPickedEvent(suggestionInfo);
|
||||||
final InputTransaction inputTransaction = new InputTransaction(settingsValues,
|
final InputTransaction inputTransaction = new InputTransaction(settingsValues,
|
||||||
event, SystemClock.uptimeMillis(), mSpaceState, keyboardShiftState);
|
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();
|
mConnection.beginBatchEdit();
|
||||||
if (SpaceState.PHANTOM == mSpaceState && suggestion.length() > 0
|
if (SpaceState.PHANTOM == mSpaceState && suggestion.length() > 0
|
||||||
// In the batch input mode, a manually picked suggested word should just replace
|
// In the batch input mode, a manually picked suggested word should just replace
|
||||||
|
@ -404,6 +409,8 @@ public final class InputLogic {
|
||||||
switch (event.mKeyCode) {
|
switch (event.mKeyCode) {
|
||||||
case Constants.CODE_DELETE:
|
case Constants.CODE_DELETE:
|
||||||
handleBackspace(inputTransaction, currentKeyboardScriptId);
|
handleBackspace(inputTransaction, currentKeyboardScriptId);
|
||||||
|
// Backspace is a functional key, but it affects the contents of the editor.
|
||||||
|
inputTransaction.setDidAffectContents();
|
||||||
break;
|
break;
|
||||||
case Constants.CODE_SHIFT:
|
case Constants.CODE_SHIFT:
|
||||||
performRecapitalization(inputTransaction.mSettingsValues);
|
performRecapitalization(inputTransaction.mSettingsValues);
|
||||||
|
@ -457,11 +464,15 @@ public final class InputLogic {
|
||||||
inputTransaction.mTimestamp, inputTransaction.mSpaceState,
|
inputTransaction.mTimestamp, inputTransaction.mSpaceState,
|
||||||
inputTransaction.mShiftState);
|
inputTransaction.mShiftState);
|
||||||
didAutoCorrect = handleNonSpecialCharacter(tmpTransaction, handler);
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new RuntimeException("Unknown key code : " + event.mKeyCode);
|
throw new RuntimeException("Unknown key code : " + event.mKeyCode);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
inputTransaction.setDidAffectContents();
|
||||||
switch (event.mCodePoint) {
|
switch (event.mCodePoint) {
|
||||||
case Constants.CODE_ENTER:
|
case Constants.CODE_ENTER:
|
||||||
final EditorInfo editorInfo = getCurrentInputEditorInfo();
|
final EditorInfo editorInfo = getCurrentInputEditorInfo();
|
||||||
|
|
Loading…
Reference in New Issue