Merge "[CB03] Pass whole events to the various input logic handlers."
This commit is contained in:
commit
309773c322
3 changed files with 137 additions and 134 deletions
|
@ -130,6 +130,12 @@ public class Event {
|
||||||
return 0 != (FLAG_DEAD & mFlags);
|
return 0 != (FLAG_DEAD & mFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns whether this is a fake key press from the suggestion strip. This happens with
|
||||||
|
// punctuation signs selected from the suggestion strip.
|
||||||
|
public boolean isSuggestionStripPress() {
|
||||||
|
return EVENT_INPUT_KEYPRESS == mType && Constants.SUGGESTION_STRIP_COORDINATE == mX;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: remove this method - we should not have to test this
|
// TODO: remove this method - we should not have to test this
|
||||||
public boolean isCommittable() {
|
public boolean isCommittable() {
|
||||||
return EVENT_INPUT_KEYPRESS == mType || EVENT_MODE_KEY == mType || EVENT_TOGGLE == mType;
|
return EVENT_INPUT_KEYPRESS == mType || EVENT_MODE_KEY == mType || EVENT_TOGGLE == mType;
|
||||||
|
|
|
@ -33,11 +33,7 @@ public class InputTransaction {
|
||||||
|
|
||||||
// Initial conditions
|
// Initial conditions
|
||||||
public final SettingsValues mSettingsValues;
|
public final SettingsValues mSettingsValues;
|
||||||
// If the key inserts a code point, mKeyCode is always equal to the code points. Otherwise,
|
public final Event mEvent;
|
||||||
// it's always a code that may not be a code point, typically a negative number.
|
|
||||||
public final int mKeyCode;
|
|
||||||
public final int mX; // Pressed x-coordinate, or one of Constants.*_COORDINATE
|
|
||||||
public final int mY; // Pressed y-coordinate, or one of Constants.*_COORDINATE
|
|
||||||
public final long mTimestamp;
|
public final long mTimestamp;
|
||||||
public final int mSpaceState;
|
public final int mSpaceState;
|
||||||
public final int mShiftState;
|
public final int mShiftState;
|
||||||
|
@ -45,13 +41,10 @@ public class InputTransaction {
|
||||||
// Outputs
|
// Outputs
|
||||||
private int mRequiredShiftUpdate = SHIFT_NO_UPDATE;
|
private int mRequiredShiftUpdate = SHIFT_NO_UPDATE;
|
||||||
|
|
||||||
public InputTransaction(final SettingsValues settingsValues, final int keyCode,
|
public InputTransaction(final SettingsValues settingsValues, final Event event,
|
||||||
final int x, final int y, final long timestamp, final int spaceState,
|
final long timestamp, final int spaceState, final int shiftState) {
|
||||||
final int shiftState) {
|
|
||||||
mSettingsValues = settingsValues;
|
mSettingsValues = settingsValues;
|
||||||
mKeyCode = keyCode;
|
mEvent = event;
|
||||||
mX = x;
|
|
||||||
mY = y;
|
|
||||||
mTimestamp = timestamp;
|
mTimestamp = timestamp;
|
||||||
mSpaceState = spaceState;
|
mSpaceState = spaceState;
|
||||||
mShiftState = shiftState;
|
mShiftState = shiftState;
|
||||||
|
|
|
@ -368,16 +368,13 @@ public final class InputLogic {
|
||||||
// var because it's confusing. Instead the switch() should handle this in a readable manner.
|
// var because it's confusing. Instead the switch() should handle this in a readable manner.
|
||||||
final int code =
|
final int code =
|
||||||
Event.NOT_A_CODE_POINT == event.mCodePoint ? event.mKeyCode : event.mCodePoint;
|
Event.NOT_A_CODE_POINT == event.mCodePoint ? event.mKeyCode : event.mCodePoint;
|
||||||
final int x = event.mX;
|
final InputTransaction inputTransaction = new InputTransaction(settingsValues, event,
|
||||||
final int y = event.mY;
|
|
||||||
final InputTransaction inputTransaction = new InputTransaction(settingsValues, code, x, y,
|
|
||||||
SystemClock.uptimeMillis(), mSpaceState,
|
SystemClock.uptimeMillis(), mSpaceState,
|
||||||
getActualCapsMode(settingsValues, keyboardShiftMode));
|
getActualCapsMode(settingsValues, keyboardShiftMode));
|
||||||
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
|
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
|
||||||
ResearchLogger.latinIME_onCodeInput(inputTransaction.mKeyCode,
|
ResearchLogger.latinIME_onCodeInput(code, event.mX, event.mY);
|
||||||
inputTransaction.mX, inputTransaction.mY);
|
|
||||||
}
|
}
|
||||||
if (inputTransaction.mKeyCode != Constants.CODE_DELETE
|
if (event.mKeyCode != Constants.CODE_DELETE
|
||||||
|| inputTransaction.mTimestamp > mLastKeyTime + Constants.LONG_PRESS_MILLISECONDS) {
|
|| inputTransaction.mTimestamp > mLastKeyTime + Constants.LONG_PRESS_MILLISECONDS) {
|
||||||
mDeleteCount = 0;
|
mDeleteCount = 0;
|
||||||
}
|
}
|
||||||
|
@ -388,97 +385,104 @@ public final class InputLogic {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Consolidate the double-space period timer, mLastKeyTime, and the space state.
|
// TODO: Consolidate the double-space period timer, mLastKeyTime, and the space state.
|
||||||
if (inputTransaction.mKeyCode != Constants.CODE_SPACE) {
|
if (event.mCodePoint != Constants.CODE_SPACE) {
|
||||||
handler.cancelDoubleSpacePeriodTimer();
|
handler.cancelDoubleSpacePeriodTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean didAutoCorrect = false;
|
boolean didAutoCorrect = false;
|
||||||
switch (inputTransaction.mKeyCode) {
|
if (Event.NOT_A_KEY_CODE != event.mKeyCode) {
|
||||||
case Constants.CODE_DELETE:
|
// A special key, like delete, shift, emoji, or the settings key.
|
||||||
handleBackspace(inputTransaction, handler);
|
switch (event.mKeyCode) {
|
||||||
LatinImeLogger.logOnDelete(inputTransaction.mX, inputTransaction.mY);
|
case Constants.CODE_DELETE:
|
||||||
break;
|
handleBackspace(inputTransaction, handler);
|
||||||
case Constants.CODE_SHIFT:
|
LatinImeLogger.logOnDelete(event.mX, event.mY);
|
||||||
performRecapitalization(inputTransaction.mSettingsValues);
|
break;
|
||||||
inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
|
case Constants.CODE_SHIFT:
|
||||||
break;
|
performRecapitalization(inputTransaction.mSettingsValues);
|
||||||
case Constants.CODE_CAPSLOCK:
|
inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
|
||||||
// Note: Changing keyboard to shift lock state is handled in
|
break;
|
||||||
// {@link KeyboardSwitcher#onCodeInput(int)}.
|
case Constants.CODE_CAPSLOCK:
|
||||||
break;
|
// Note: Changing keyboard to shift lock state is handled in
|
||||||
case Constants.CODE_SYMBOL_SHIFT:
|
// {@link KeyboardSwitcher#onCodeInput(int)}.
|
||||||
// Note: Calling back to the keyboard on the symbol Shift key is handled in
|
break;
|
||||||
// {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}.
|
case Constants.CODE_SYMBOL_SHIFT:
|
||||||
break;
|
// Note: Calling back to the keyboard on the symbol Shift key is handled in
|
||||||
case Constants.CODE_SWITCH_ALPHA_SYMBOL:
|
// {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}.
|
||||||
// Note: Calling back to the keyboard on symbol key is handled in
|
break;
|
||||||
// {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}.
|
case Constants.CODE_SWITCH_ALPHA_SYMBOL:
|
||||||
break;
|
// Note: Calling back to the keyboard on symbol key is handled in
|
||||||
case Constants.CODE_SETTINGS:
|
// {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}.
|
||||||
onSettingsKeyPressed();
|
break;
|
||||||
break;
|
case Constants.CODE_SETTINGS:
|
||||||
case Constants.CODE_SHORTCUT:
|
onSettingsKeyPressed();
|
||||||
// We need to switch to the shortcut IME. This is handled by LatinIME since the
|
break;
|
||||||
// input logic has no business with IME switching.
|
case Constants.CODE_SHORTCUT:
|
||||||
break;
|
// We need to switch to the shortcut IME. This is handled by LatinIME since the
|
||||||
case Constants.CODE_ACTION_NEXT:
|
// input logic has no business with IME switching.
|
||||||
performEditorAction(EditorInfo.IME_ACTION_NEXT);
|
break;
|
||||||
break;
|
case Constants.CODE_ACTION_NEXT:
|
||||||
case Constants.CODE_ACTION_PREVIOUS:
|
performEditorAction(EditorInfo.IME_ACTION_NEXT);
|
||||||
performEditorAction(EditorInfo.IME_ACTION_PREVIOUS);
|
break;
|
||||||
break;
|
case Constants.CODE_ACTION_PREVIOUS:
|
||||||
case Constants.CODE_LANGUAGE_SWITCH:
|
performEditorAction(EditorInfo.IME_ACTION_PREVIOUS);
|
||||||
handleLanguageSwitchKey();
|
break;
|
||||||
break;
|
case Constants.CODE_LANGUAGE_SWITCH:
|
||||||
case Constants.CODE_EMOJI:
|
handleLanguageSwitchKey();
|
||||||
// Note: Switching emoji keyboard is being handled in
|
break;
|
||||||
// {@link KeyboardState#onCodeInput(int,int)}.
|
case Constants.CODE_EMOJI:
|
||||||
break;
|
// Note: Switching emoji keyboard is being handled in
|
||||||
case Constants.CODE_ENTER:
|
// {@link KeyboardState#onCodeInput(int,int)}.
|
||||||
final EditorInfo editorInfo = getCurrentInputEditorInfo();
|
break;
|
||||||
final int imeOptionsActionId =
|
case Constants.CODE_ALPHA_FROM_EMOJI:
|
||||||
InputTypeUtils.getImeOptionsActionIdFromEditorInfo(editorInfo);
|
// Note: Switching back from Emoji keyboard to the main keyboard is being
|
||||||
if (InputTypeUtils.IME_ACTION_CUSTOM_LABEL == imeOptionsActionId) {
|
// handled in {@link KeyboardState#onCodeInput(int,int)}.
|
||||||
// Either we have an actionLabel and we should performEditorAction with actionId
|
break;
|
||||||
// regardless of its value.
|
case Constants.CODE_SHIFT_ENTER:
|
||||||
performEditorAction(editorInfo.actionId);
|
// TODO: remove this object
|
||||||
} else if (EditorInfo.IME_ACTION_NONE != imeOptionsActionId) {
|
final InputTransaction tmpTransaction = new InputTransaction(
|
||||||
// We didn't have an actionLabel, but we had another action to execute.
|
inputTransaction.mSettingsValues, inputTransaction.mEvent,
|
||||||
// EditorInfo.IME_ACTION_NONE explicitly means no action. In contrast,
|
inputTransaction.mTimestamp, inputTransaction.mSpaceState,
|
||||||
// EditorInfo.IME_ACTION_UNSPECIFIED is the default value for an action, so it
|
inputTransaction.mShiftState);
|
||||||
// means there should be an action and the app didn't bother to set a specific
|
didAutoCorrect = handleNonSpecialCharacter(tmpTransaction, handler);
|
||||||
// code for it - presumably it only handles one. It does not have to be treated
|
break;
|
||||||
// in any specific way: anything that is not IME_ACTION_NONE should be sent to
|
default:
|
||||||
// performEditorAction.
|
throw new RuntimeException("Unknown key code : " + event.mKeyCode);
|
||||||
performEditorAction(imeOptionsActionId);
|
}
|
||||||
} else {
|
} else {
|
||||||
// No action label, and the action from imeOptions is NONE: this is a regular
|
switch (event.mCodePoint) {
|
||||||
// enter key that should input a carriage return.
|
case Constants.CODE_ENTER:
|
||||||
didAutoCorrect = handleNonSpecialCharacter(inputTransaction, handler);
|
final EditorInfo editorInfo = getCurrentInputEditorInfo();
|
||||||
|
final int imeOptionsActionId =
|
||||||
|
InputTypeUtils.getImeOptionsActionIdFromEditorInfo(editorInfo);
|
||||||
|
if (InputTypeUtils.IME_ACTION_CUSTOM_LABEL == imeOptionsActionId) {
|
||||||
|
// Either we have an actionLabel and we should performEditorAction with
|
||||||
|
// actionId regardless of its value.
|
||||||
|
performEditorAction(editorInfo.actionId);
|
||||||
|
} else if (EditorInfo.IME_ACTION_NONE != imeOptionsActionId) {
|
||||||
|
// We didn't have an actionLabel, but we had another action to execute.
|
||||||
|
// EditorInfo.IME_ACTION_NONE explicitly means no action. In contrast,
|
||||||
|
// EditorInfo.IME_ACTION_UNSPECIFIED is the default value for an action, so it
|
||||||
|
// means there should be an action and the app didn't bother to set a specific
|
||||||
|
// code for it - presumably it only handles one. It does not have to be treated
|
||||||
|
// in any specific way: anything that is not IME_ACTION_NONE should be sent to
|
||||||
|
// performEditorAction.
|
||||||
|
performEditorAction(imeOptionsActionId);
|
||||||
|
} else {
|
||||||
|
// No action label, and the action from imeOptions is NONE: this is a regular
|
||||||
|
// enter key that should input a carriage return.
|
||||||
|
didAutoCorrect = handleNonSpecialCharacter(inputTransaction, handler);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
didAutoCorrect = handleNonSpecialCharacter(inputTransaction, handler);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case Constants.CODE_SHIFT_ENTER:
|
|
||||||
// TODO: remove this object
|
|
||||||
final InputTransaction tmpTransaction = new InputTransaction(
|
|
||||||
inputTransaction.mSettingsValues, inputTransaction.mKeyCode,
|
|
||||||
inputTransaction.mX, inputTransaction.mY, inputTransaction.mTimestamp,
|
|
||||||
inputTransaction.mSpaceState, inputTransaction.mShiftState);
|
|
||||||
didAutoCorrect = handleNonSpecialCharacter(tmpTransaction, handler);
|
|
||||||
break;
|
|
||||||
case Constants.CODE_ALPHA_FROM_EMOJI:
|
|
||||||
// Note: Switching back from Emoji keyboard to the main keyboard is being handled in
|
|
||||||
// {@link KeyboardState#onCodeInput(int,int)}.
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
didAutoCorrect = handleNonSpecialCharacter(inputTransaction, handler);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
// Reset after any single keystroke, except shift, capslock, and symbol-shift
|
if (!didAutoCorrect && event.mKeyCode != Constants.CODE_SHIFT
|
||||||
if (!didAutoCorrect && inputTransaction.mKeyCode != Constants.CODE_SHIFT
|
&& event.mKeyCode != Constants.CODE_CAPSLOCK
|
||||||
&& inputTransaction.mKeyCode != Constants.CODE_CAPSLOCK
|
&& event.mKeyCode != Constants.CODE_SWITCH_ALPHA_SYMBOL)
|
||||||
&& inputTransaction.mKeyCode != Constants.CODE_SWITCH_ALPHA_SYMBOL)
|
|
||||||
mLastComposedWord.deactivate();
|
mLastComposedWord.deactivate();
|
||||||
if (Constants.CODE_DELETE != inputTransaction.mKeyCode) {
|
if (Constants.CODE_DELETE != event.mKeyCode) {
|
||||||
mEnteredText = null;
|
mEnteredText = null;
|
||||||
}
|
}
|
||||||
mConnection.endBatchEdit();
|
mConnection.endBatchEdit();
|
||||||
|
@ -632,15 +636,16 @@ public final class InputLogic {
|
||||||
private boolean handleNonSpecialCharacter(final InputTransaction inputTransaction,
|
private boolean handleNonSpecialCharacter(final InputTransaction inputTransaction,
|
||||||
// TODO: remove this argument
|
// TODO: remove this argument
|
||||||
final LatinIME.UIHandler handler) {
|
final LatinIME.UIHandler handler) {
|
||||||
|
final int codePoint = inputTransaction.mEvent.mCodePoint;
|
||||||
mSpaceState = SpaceState.NONE;
|
mSpaceState = SpaceState.NONE;
|
||||||
final boolean didAutoCorrect;
|
final boolean didAutoCorrect;
|
||||||
if (inputTransaction.mSettingsValues.isWordSeparator(inputTransaction.mKeyCode)
|
if (inputTransaction.mSettingsValues.isWordSeparator(codePoint)
|
||||||
|| Character.getType(inputTransaction.mKeyCode) == Character.OTHER_SYMBOL) {
|
|| Character.getType(codePoint) == Character.OTHER_SYMBOL) {
|
||||||
didAutoCorrect = handleSeparator(inputTransaction,
|
didAutoCorrect = handleSeparator(inputTransaction,
|
||||||
Constants.SUGGESTION_STRIP_COORDINATE == inputTransaction.mX, handler);
|
inputTransaction.mEvent.isSuggestionStripPress(), handler);
|
||||||
if (inputTransaction.mSettingsValues.mIsInternal) {
|
if (inputTransaction.mSettingsValues.mIsInternal) {
|
||||||
LatinImeLoggerUtils.onSeparator((char)inputTransaction.mKeyCode,
|
LatinImeLoggerUtils.onSeparator((char)codePoint,
|
||||||
inputTransaction.mX, inputTransaction.mY);
|
inputTransaction.mEvent.mX, inputTransaction.mEvent.mY);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
didAutoCorrect = false;
|
didAutoCorrect = false;
|
||||||
|
@ -674,6 +679,7 @@ public final class InputLogic {
|
||||||
final InputTransaction inputTransaction,
|
final InputTransaction inputTransaction,
|
||||||
// TODO: Remove this argument
|
// TODO: Remove this argument
|
||||||
final LatinIME.UIHandler handler) {
|
final LatinIME.UIHandler handler) {
|
||||||
|
final int codePoint = inputTransaction.mEvent.mCodePoint;
|
||||||
// TODO: refactor this method to stop flipping isComposingWord around all the time, and
|
// TODO: refactor this method to stop flipping isComposingWord around all the time, and
|
||||||
// make it shorter (possibly cut into several pieces). Also factor handleNonSpecialCharacter
|
// make it shorter (possibly cut into several pieces). Also factor handleNonSpecialCharacter
|
||||||
// which has the same name as other handle* methods but is not the same.
|
// which has the same name as other handle* methods but is not the same.
|
||||||
|
@ -682,7 +688,7 @@ public final class InputLogic {
|
||||||
// TODO: remove isWordConnector() and use isUsuallyFollowedBySpace() instead.
|
// TODO: remove isWordConnector() and use isUsuallyFollowedBySpace() instead.
|
||||||
// See onStartBatchInput() to see how to do it.
|
// See onStartBatchInput() to see how to do it.
|
||||||
if (SpaceState.PHANTOM == inputTransaction.mSpaceState
|
if (SpaceState.PHANTOM == inputTransaction.mSpaceState
|
||||||
&& !settingsValues.isWordConnector(inputTransaction.mKeyCode)) {
|
&& !settingsValues.isWordConnector(codePoint)) {
|
||||||
if (isComposingWord) {
|
if (isComposingWord) {
|
||||||
// Sanity check
|
// Sanity check
|
||||||
throw new RuntimeException("Should not be composing here");
|
throw new RuntimeException("Should not be composing here");
|
||||||
|
@ -704,7 +710,7 @@ public final class InputLogic {
|
||||||
if (!isComposingWord
|
if (!isComposingWord
|
||||||
// We only start composing if this is a word code point. Essentially that means it's a
|
// We only start composing if this is a word code point. Essentially that means it's a
|
||||||
// a letter or a word connector.
|
// a letter or a word connector.
|
||||||
&& settingsValues.isWordCodePoint(inputTransaction.mKeyCode)
|
&& settingsValues.isWordCodePoint(codePoint)
|
||||||
// We never go into composing state if suggestions are not requested.
|
// We never go into composing state if suggestions are not requested.
|
||||||
&& settingsValues.isSuggestionsRequested() &&
|
&& settingsValues.isSuggestionsRequested() &&
|
||||||
// In languages with spaces, we only start composing a word when we are not already
|
// In languages with spaces, we only start composing a word when we are not already
|
||||||
|
@ -715,8 +721,8 @@ public final class InputLogic {
|
||||||
// the character is a single quote or a dash. The idea here is, single quote and dash
|
// the character is a single quote or a dash. The idea here is, single quote and dash
|
||||||
// are not separators and they should be treated as normal characters, except in the
|
// are not separators and they should be treated as normal characters, except in the
|
||||||
// first position where they should not start composing a word.
|
// first position where they should not start composing a word.
|
||||||
isComposingWord = (Constants.CODE_SINGLE_QUOTE != inputTransaction.mKeyCode
|
isComposingWord = (Constants.CODE_SINGLE_QUOTE != codePoint
|
||||||
&& Constants.CODE_DASH != inputTransaction.mKeyCode);
|
&& Constants.CODE_DASH != codePoint);
|
||||||
// Here we don't need to reset the last composed word. It will be reset
|
// Here we don't need to reset the last composed word. It will be reset
|
||||||
// when we commit this one, if we ever do; if on the other hand we backspace
|
// when we commit this one, if we ever do; if on the other hand we backspace
|
||||||
// it entirely and resume suggestions on the previous word, we'd like to still
|
// it entirely and resume suggestions on the previous word, we'd like to still
|
||||||
|
@ -724,7 +730,8 @@ public final class InputLogic {
|
||||||
resetComposingState(false /* alsoResetLastComposedWord */);
|
resetComposingState(false /* alsoResetLastComposedWord */);
|
||||||
}
|
}
|
||||||
if (isComposingWord) {
|
if (isComposingWord) {
|
||||||
mWordComposer.add(inputTransaction.mKeyCode, inputTransaction.mX, inputTransaction.mY);
|
// TODO: pass the entire event to the word composer.
|
||||||
|
mWordComposer.add(codePoint, inputTransaction.mEvent.mX, inputTransaction.mEvent.mY);
|
||||||
// If it's the first letter, make note of auto-caps state
|
// If it's the first letter, make note of auto-caps state
|
||||||
if (mWordComposer.size() == 1) {
|
if (mWordComposer.size() == 1) {
|
||||||
// We pass 1 to getPreviousWordForSuggestion because we were not composing a word
|
// We pass 1 to getPreviousWordForSuggestion because we were not composing a word
|
||||||
|
@ -737,9 +744,9 @@ public final class InputLogic {
|
||||||
mWordComposer.getTypedWord()), 1);
|
mWordComposer.getTypedWord()), 1);
|
||||||
} else {
|
} else {
|
||||||
final boolean swapWeakSpace = maybeStripSpace(inputTransaction,
|
final boolean swapWeakSpace = maybeStripSpace(inputTransaction,
|
||||||
Constants.SUGGESTION_STRIP_COORDINATE == inputTransaction.mX);
|
inputTransaction.mEvent.isSuggestionStripPress());
|
||||||
|
|
||||||
sendKeyCodePoint(settingsValues, inputTransaction.mKeyCode);
|
sendKeyCodePoint(settingsValues, codePoint);
|
||||||
|
|
||||||
if (swapWeakSpace) {
|
if (swapWeakSpace) {
|
||||||
swapSwapperAndSpace(inputTransaction);
|
swapSwapperAndSpace(inputTransaction);
|
||||||
|
@ -750,8 +757,8 @@ public final class InputLogic {
|
||||||
}
|
}
|
||||||
handler.postUpdateSuggestionStrip();
|
handler.postUpdateSuggestionStrip();
|
||||||
if (settingsValues.mIsInternal) {
|
if (settingsValues.mIsInternal) {
|
||||||
LatinImeLoggerUtils.onNonSeparator((char)inputTransaction.mKeyCode, inputTransaction.mX,
|
LatinImeLoggerUtils.onNonSeparator((char)codePoint, inputTransaction.mEvent.mX,
|
||||||
inputTransaction.mY);
|
inputTransaction.mEvent.mY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -765,9 +772,10 @@ public final class InputLogic {
|
||||||
final boolean isFromSuggestionStrip,
|
final boolean isFromSuggestionStrip,
|
||||||
// TODO: remove this argument
|
// TODO: remove this argument
|
||||||
final LatinIME.UIHandler handler) {
|
final LatinIME.UIHandler handler) {
|
||||||
|
final int codePoint = inputTransaction.mEvent.mCodePoint;
|
||||||
boolean didAutoCorrect = false;
|
boolean didAutoCorrect = false;
|
||||||
// We avoid sending spaces in languages without spaces if we were composing.
|
// We avoid sending spaces in languages without spaces if we were composing.
|
||||||
final boolean shouldAvoidSendingCode = Constants.CODE_SPACE == inputTransaction.mKeyCode
|
final boolean shouldAvoidSendingCode = Constants.CODE_SPACE == codePoint
|
||||||
&& !inputTransaction.mSettingsValues.mSpacingAndPunctuations
|
&& !inputTransaction.mSettingsValues.mSpacingAndPunctuations
|
||||||
.mCurrentLanguageHasSpaces
|
.mCurrentLanguageHasSpaces
|
||||||
&& mWordComposer.isComposingWord();
|
&& mWordComposer.isComposingWord();
|
||||||
|
@ -781,46 +789,44 @@ public final class InputLogic {
|
||||||
if (mWordComposer.isComposingWord()) {
|
if (mWordComposer.isComposingWord()) {
|
||||||
if (inputTransaction.mSettingsValues.mCorrectionEnabled) {
|
if (inputTransaction.mSettingsValues.mCorrectionEnabled) {
|
||||||
final String separator = shouldAvoidSendingCode ? LastComposedWord.NOT_A_SEPARATOR
|
final String separator = shouldAvoidSendingCode ? LastComposedWord.NOT_A_SEPARATOR
|
||||||
: StringUtils.newSingleCodePointString(inputTransaction.mKeyCode);
|
: StringUtils.newSingleCodePointString(codePoint);
|
||||||
commitCurrentAutoCorrection(inputTransaction.mSettingsValues, separator, handler);
|
commitCurrentAutoCorrection(inputTransaction.mSettingsValues, separator, handler);
|
||||||
didAutoCorrect = true;
|
didAutoCorrect = true;
|
||||||
} else {
|
} else {
|
||||||
commitTyped(inputTransaction.mSettingsValues,
|
commitTyped(inputTransaction.mSettingsValues,
|
||||||
StringUtils.newSingleCodePointString(inputTransaction.mKeyCode));
|
StringUtils.newSingleCodePointString(codePoint));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean swapWeakSpace = maybeStripSpace(inputTransaction, isFromSuggestionStrip);
|
final boolean swapWeakSpace = maybeStripSpace(inputTransaction, isFromSuggestionStrip);
|
||||||
|
|
||||||
final boolean isInsideDoubleQuoteOrAfterDigit =
|
final boolean isInsideDoubleQuoteOrAfterDigit = Constants.CODE_DOUBLE_QUOTE == codePoint
|
||||||
Constants.CODE_DOUBLE_QUOTE == inputTransaction.mKeyCode
|
|
||||||
&& mConnection.isInsideDoubleQuoteOrAfterDigit();
|
&& mConnection.isInsideDoubleQuoteOrAfterDigit();
|
||||||
|
|
||||||
final boolean needsPrecedingSpace;
|
final boolean needsPrecedingSpace;
|
||||||
if (SpaceState.PHANTOM != inputTransaction.mSpaceState) {
|
if (SpaceState.PHANTOM != inputTransaction.mSpaceState) {
|
||||||
needsPrecedingSpace = false;
|
needsPrecedingSpace = false;
|
||||||
} else if (Constants.CODE_DOUBLE_QUOTE == inputTransaction.mKeyCode) {
|
} else if (Constants.CODE_DOUBLE_QUOTE == codePoint) {
|
||||||
// Double quotes behave like they are usually preceded by space iff we are
|
// Double quotes behave like they are usually preceded by space iff we are
|
||||||
// not inside a double quote or after a digit.
|
// not inside a double quote or after a digit.
|
||||||
needsPrecedingSpace = !isInsideDoubleQuoteOrAfterDigit;
|
needsPrecedingSpace = !isInsideDoubleQuoteOrAfterDigit;
|
||||||
} else {
|
} else {
|
||||||
needsPrecedingSpace = inputTransaction.mSettingsValues.isUsuallyPrecededBySpace(
|
needsPrecedingSpace = inputTransaction.mSettingsValues.isUsuallyPrecededBySpace(
|
||||||
inputTransaction.mKeyCode);
|
codePoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needsPrecedingSpace) {
|
if (needsPrecedingSpace) {
|
||||||
promotePhantomSpace(inputTransaction.mSettingsValues);
|
promotePhantomSpace(inputTransaction.mSettingsValues);
|
||||||
}
|
}
|
||||||
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
|
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
|
||||||
ResearchLogger.latinIME_handleSeparator(inputTransaction.mKeyCode,
|
ResearchLogger.latinIME_handleSeparator(codePoint, mWordComposer.isComposingWord());
|
||||||
mWordComposer.isComposingWord());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!shouldAvoidSendingCode) {
|
if (!shouldAvoidSendingCode) {
|
||||||
sendKeyCodePoint(inputTransaction.mSettingsValues, inputTransaction.mKeyCode);
|
sendKeyCodePoint(inputTransaction.mSettingsValues, codePoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Constants.CODE_SPACE == inputTransaction.mKeyCode) {
|
if (Constants.CODE_SPACE == codePoint) {
|
||||||
if (inputTransaction.mSettingsValues.isSuggestionsRequested()) {
|
if (inputTransaction.mSettingsValues.isSuggestionsRequested()) {
|
||||||
if (maybeDoubleSpacePeriod(inputTransaction.mSettingsValues, handler)) {
|
if (maybeDoubleSpacePeriod(inputTransaction.mSettingsValues, handler)) {
|
||||||
inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
|
inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
|
||||||
|
@ -837,9 +843,8 @@ public final class InputLogic {
|
||||||
swapSwapperAndSpace(inputTransaction);
|
swapSwapperAndSpace(inputTransaction);
|
||||||
mSpaceState = SpaceState.SWAP_PUNCTUATION;
|
mSpaceState = SpaceState.SWAP_PUNCTUATION;
|
||||||
} else if ((SpaceState.PHANTOM == inputTransaction.mSpaceState
|
} else if ((SpaceState.PHANTOM == inputTransaction.mSpaceState
|
||||||
&& inputTransaction.mSettingsValues.isUsuallyFollowedBySpace(
|
&& inputTransaction.mSettingsValues.isUsuallyFollowedBySpace(codePoint))
|
||||||
inputTransaction.mKeyCode))
|
|| (Constants.CODE_DOUBLE_QUOTE == codePoint
|
||||||
|| (Constants.CODE_DOUBLE_QUOTE == inputTransaction.mKeyCode
|
|
||||||
&& isInsideDoubleQuoteOrAfterDigit)) {
|
&& isInsideDoubleQuoteOrAfterDigit)) {
|
||||||
// If we are in phantom space state, and the user presses a separator, we want to
|
// If we are in phantom space state, and the user presses a separator, we want to
|
||||||
// stay in phantom space state so that the next keypress has a chance to add the
|
// stay in phantom space state so that the next keypress has a chance to add the
|
||||||
|
@ -1056,7 +1061,8 @@ public final class InputLogic {
|
||||||
*/
|
*/
|
||||||
private boolean maybeStripSpace(final InputTransaction inputTransaction,
|
private boolean maybeStripSpace(final InputTransaction inputTransaction,
|
||||||
final boolean isFromSuggestionStrip) {
|
final boolean isFromSuggestionStrip) {
|
||||||
if (Constants.CODE_ENTER == inputTransaction.mKeyCode &&
|
final int codePoint = inputTransaction.mEvent.mCodePoint;
|
||||||
|
if (Constants.CODE_ENTER == codePoint &&
|
||||||
SpaceState.SWAP_PUNCTUATION == inputTransaction.mSpaceState) {
|
SpaceState.SWAP_PUNCTUATION == inputTransaction.mSpaceState) {
|
||||||
mConnection.removeTrailingSpace();
|
mConnection.removeTrailingSpace();
|
||||||
return false;
|
return false;
|
||||||
|
@ -1064,12 +1070,10 @@ public final class InputLogic {
|
||||||
if ((SpaceState.WEAK == inputTransaction.mSpaceState
|
if ((SpaceState.WEAK == inputTransaction.mSpaceState
|
||||||
|| SpaceState.SWAP_PUNCTUATION == inputTransaction.mSpaceState)
|
|| SpaceState.SWAP_PUNCTUATION == inputTransaction.mSpaceState)
|
||||||
&& isFromSuggestionStrip) {
|
&& isFromSuggestionStrip) {
|
||||||
if (inputTransaction.mSettingsValues.isUsuallyPrecededBySpace(
|
if (inputTransaction.mSettingsValues.isUsuallyPrecededBySpace(codePoint)) {
|
||||||
inputTransaction.mKeyCode)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (inputTransaction.mSettingsValues.isUsuallyFollowedBySpace(
|
if (inputTransaction.mSettingsValues.isUsuallyFollowedBySpace(codePoint)) {
|
||||||
inputTransaction.mKeyCode)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
mConnection.removeTrailingSpace();
|
mConnection.removeTrailingSpace();
|
||||||
|
|
Loading…
Reference in a new issue