aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin/inputlogic
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/latin/inputlogic')
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java118
1 files changed, 92 insertions, 26 deletions
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 6e9bdc34a..43d75330d 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -36,14 +36,12 @@ import com.android.inputmethod.latin.LastComposedWord;
import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.RichInputConnection;
-import com.android.inputmethod.latin.SubtypeSwitcher;
import com.android.inputmethod.latin.Suggest;
import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback;
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.ProductionFlag;
-import com.android.inputmethod.latin.settings.Settings;
import com.android.inputmethod.latin.settings.SettingsValues;
import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
import com.android.inputmethod.latin.utils.AsyncResultHolder;
@@ -181,6 +179,67 @@ public final class InputLogic {
}
/**
+ * Consider an update to the cursor position. Evaluate whether this update has happened as
+ * part of normal typing or whether it was an explicit cursor move by the user. In any case,
+ * do the necessary adjustments.
+ * @param settingsValues the current settings
+ * @param oldSelStart old selection start
+ * @param oldSelEnd old selection end
+ * @param newSelStart new selection start
+ * @param newSelEnd new selection end
+ * @param composingSpanStart composing span start
+ * @param composingSpanEnd composing span end
+ * @return whether the cursor has moved as a result of user interaction.
+ */
+ public boolean onUpdateSelection(final SettingsValues settingsValues,
+ final int oldSelStart, final int oldSelEnd,
+ final int newSelStart, final int newSelEnd,
+ final int composingSpanStart, final int composingSpanEnd) {
+ if (mConnection.isBelatedExpectedUpdate(oldSelStart, newSelStart, oldSelEnd, newSelEnd)) {
+ return false;
+ }
+ // TODO: the following is probably better done in resetEntireInputState().
+ // it should only happen when the cursor moved, and the very purpose of the
+ // test below is to narrow down whether this happened or not. Likewise with
+ // the call to updateShiftState.
+ // We set this to NONE because after a cursor move, we don't want the space
+ // state-related special processing to kick in.
+ mSpaceState = SpaceState.NONE;
+
+ final boolean selectionChangedOrSafeToReset =
+ oldSelStart != newSelStart || oldSelEnd != newSelEnd // selection changed
+ || !mWordComposer.isComposingWord(); // safe to reset
+ final boolean hasOrHadSelection = (oldSelStart != oldSelEnd || newSelStart != newSelEnd);
+ final int moveAmount = newSelStart - oldSelStart;
+ if (selectionChangedOrSafeToReset && (hasOrHadSelection
+ || !mWordComposer.moveCursorByAndReturnIfInsideComposingWord(moveAmount))) {
+ // If we are composing a word and moving the cursor, we would want to set a
+ // suggestion span for recorrection to work correctly. Unfortunately, that
+ // would involve the keyboard committing some new text, which would move the
+ // cursor back to where it was. Latin IME could then fix the position of the cursor
+ // again, but the asynchronous nature of the calls results in this wreaking havoc
+ // with selection on double tap and the like.
+ // Another option would be to send suggestions each time we set the composing
+ // text, but that is probably too expensive to do, so we decided to leave things
+ // as is.
+ resetEntireInputState(settingsValues, newSelStart, newSelEnd);
+ } else {
+ // resetEntireInputState calls resetCachesUponCursorMove, but forcing the
+ // composition to end. But in all cases where we don't reset the entire input
+ // state, we still want to tell the rich input connection about the new cursor
+ // position so that it can update its caches.
+ mConnection.resetCachesUponCursorMoveAndReturnSuccess(
+ newSelStart, newSelEnd, false /* shouldFinishComposition */);
+ }
+
+ // We moved the cursor. If we are touching a word, we need to resume suggestion.
+ mLatinIME.mHandler.postResumeSuggestions();
+ // Reset the last recapitalization.
+ mRecapitalizeStatus.deactivate();
+ return true;
+ }
+
+ /**
* React to a code input. It may be a code point to insert, or a symbolic value that influences
* the keyboard behavior.
*
@@ -192,13 +251,12 @@ public final class InputLogic {
* @param y the y-coordinate where the user pressed the key, or NOT_A_COORDINATE.
*/
public void onCodeInput(final int code, final int x, final int y,
- // TODO: remove these three arguments
- final LatinIME.UIHandler handler,
- final KeyboardSwitcher keyboardSwitcher, final SubtypeSwitcher subtypeSwitcher) {
+ final SettingsValues settingsValues,
+ // TODO: remove these two arguments
+ final LatinIME.UIHandler handler, final KeyboardSwitcher keyboardSwitcher) {
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
ResearchLogger.latinIME_onCodeInput(code, x, y);
}
- final SettingsValues settingsValues = Settings.getInstance().getCurrent();
final long when = SystemClock.uptimeMillis();
if (code != Constants.CODE_DELETE
|| when > mLastKeyTime + Constants.LONG_PRESS_MILLISECONDS) {
@@ -247,7 +305,8 @@ public final class InputLogic {
onSettingsKeyPressed();
break;
case Constants.CODE_SHORTCUT:
- subtypeSwitcher.switchToShortcutIME(mLatinIME);
+ // We need to switch to the shortcut IME. This is handled by LatinIME since the
+ // input logic has no business with IME switching.
break;
case Constants.CODE_ACTION_NEXT:
performEditorAction(EditorInfo.IME_ACTION_NEXT);
@@ -602,8 +661,21 @@ public final class InputLogic {
final boolean swapWeakSpace = maybeStripSpace(settingsValues, codePoint, spaceState,
isFromSuggestionStrip);
- if (SpaceState.PHANTOM == spaceState &&
- settingsValues.isUsuallyPrecededBySpace(codePoint)) {
+ final boolean isInsideDoubleQuoteOrAfterDigit = Constants.CODE_DOUBLE_QUOTE == codePoint
+ && mConnection.isInsideDoubleQuoteOrAfterDigit();
+
+ final boolean needsPrecedingSpace;
+ if (SpaceState.PHANTOM != spaceState) {
+ needsPrecedingSpace = false;
+ } else if (Constants.CODE_DOUBLE_QUOTE == codePoint) {
+ // Double quotes behave like they are usually preceded by space iff we are
+ // not inside a double quote or after a digit.
+ needsPrecedingSpace = !isInsideDoubleQuoteOrAfterDigit;
+ } else {
+ needsPrecedingSpace = settingsValues.isUsuallyPrecededBySpace(codePoint);
+ }
+
+ if (needsPrecedingSpace) {
promotePhantomSpace(settingsValues);
}
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
@@ -630,14 +702,17 @@ public final class InputLogic {
if (swapWeakSpace) {
swapSwapperAndSpace(keyboardSwitcher);
mSpaceState = SpaceState.SWAP_PUNCTUATION;
- } else if (SpaceState.PHANTOM == spaceState
- && settingsValues.isUsuallyFollowedBySpace(codePoint)) {
+ } else if ((SpaceState.PHANTOM == spaceState
+ && settingsValues.isUsuallyFollowedBySpace(codePoint))
+ || (Constants.CODE_DOUBLE_QUOTE == codePoint
+ && isInsideDoubleQuoteOrAfterDigit)) {
// 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
// space. For example, if I type "Good dat", pick "day" from the suggestion strip
// then insert a comma and go on to typing the next word, I want the space to be
// inserted automatically before the next word, the same way it is when I don't
- // input the comma.
+ // input the comma. A double quote behaves like it's usually followed by space if
+ // we're inside a double quote.
// The case is a little different if the separator is a space stripper. Such a
// separator does not normally need a space on the right (that's the difference
// between swappers and strippers), so we should not stay in phantom space state if
@@ -647,7 +722,7 @@ public final class InputLogic {
// Set punctuation right away. onUpdateSelection will fire but tests whether it is
// already displayed or not, so it's okay.
- mLatinIME.setPunctuationSuggestions();
+ mLatinIME.setNeutralSuggestionStrip();
}
keyboardSwitcher.updateShiftState();
@@ -1000,7 +1075,7 @@ public final class InputLogic {
}
if (!mWordComposer.isComposingWord() && !settingsValues.mBigramPredictionEnabled) {
- mLatinIME.setPunctuationSuggestions();
+ mLatinIME.setNeutralSuggestionStrip();
return;
}
@@ -1256,15 +1331,10 @@ public final class InputLogic {
* This is called from the KeyboardSwitcher (through a trampoline in LatinIME) because it
* needs to know auto caps state to display the right layout.
*
- * @param optionalSettingsValues settings values, or null if we should just get the current ones
- * from the singleton.
+ * @param settingsValues the relevant settings values
* @return a caps mode from TextUtils.CAP_MODE_* or Constants.TextUtils.CAP_MODE_OFF.
*/
- public int getCurrentAutoCapsState(final SettingsValues optionalSettingsValues) {
- // If we are in a batch edit, we need to use the same settings values as the outside
- // code, that will pass it to us. Otherwise, we can just take the current values.
- final SettingsValues settingsValues = null != optionalSettingsValues
- ? optionalSettingsValues : Settings.getInstance().getCurrent();
+ public int getCurrentAutoCapsState(final SettingsValues settingsValues) {
if (!settingsValues.mAutoCap) return Constants.TextUtils.CAP_MODE_OFF;
final EditorInfo ei = getCurrentInputEditorInfo();
@@ -1390,11 +1460,7 @@ public final class InputLogic {
final int newSelStart, final int newSelEnd) {
final boolean shouldFinishComposition = mWordComposer.isComposingWord();
resetComposingState(true /* alsoResetLastComposedWord */);
- if (settingsValues.mBigramPredictionEnabled) {
- mLatinIME.clearSuggestionStrip();
- } else {
- mLatinIME.setSuggestedWords(settingsValues.mSpacingAndPunctuations.mSuggestPuncList);
- }
+ mLatinIME.setNeutralSuggestionStrip();
mConnection.resetCachesUponCursorMoveAndReturnSuccess(newSelStart, newSelEnd,
shouldFinishComposition);
}