diff options
Diffstat (limited to 'java/src')
8 files changed, 175 insertions, 193 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java index 8d40e7aa5..a57b9d172 100644 --- a/java/src/com/android/inputmethod/keyboard/Keyboard.java +++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java @@ -75,6 +75,7 @@ public class Keyboard { public static final int CODE_DELETE = -5; public static final int CODE_SETTINGS = -6; public static final int CODE_SHORTCUT = -7; + public static final int CODE_HAPTIC_AND_AUDIO_FEEDBACK_ONLY = -98; // Code value representing the code is not specified. public static final int CODE_UNSPECIFIED = -99; diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java index 34f1c6228..a24195e87 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java @@ -21,6 +21,7 @@ import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Canvas; import android.os.Message; +import android.os.SystemClock; import android.util.AttributeSet; import android.util.Log; import android.view.GestureDetector; @@ -348,11 +349,9 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke // When shift key is double tapped, the first tap is correctly processed as usual tap. And // the second tap is treated as this double tap event, so that we need not mark tracker // calling setAlreadyProcessed() nor remove the tracker from mPointerQueue. - if (ignore) { - mKeyboardActionListener.onCustomRequest(LatinIME.CODE_HAPTIC_AND_AUDIO_FEEDBACK); - } else { - mKeyboardActionListener.onCodeInput(Keyboard.CODE_CAPSLOCK, null, 0, 0); - } + final int primaryCode = ignore ? Keyboard.CODE_HAPTIC_AND_AUDIO_FEEDBACK_ONLY + : Keyboard.CODE_CAPSLOCK; + mKeyboardActionListener.onCodeInput(primaryCode, null, 0, 0); } // This default implementation returns a more keys panel. @@ -453,7 +452,8 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke this, this, pointX, pointY, mMoreKeysWindow, getKeyboardActionListener()); final int translatedX = moreKeysPanel.translateX(tracker.getLastX()); final int translatedY = moreKeysPanel.translateY(tracker.getLastY()); - tracker.onShowMoreKeysPanel(translatedX, translatedY, moreKeysPanel); + tracker.onShowMoreKeysPanel( + translatedX, translatedY, SystemClock.uptimeMillis(), moreKeysPanel); dimEntireKeyboard(true); return true; } diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboardView.java index 0e6e129bb..f2c5b7b49 100644 --- a/java/src/com/android/inputmethod/keyboard/MiniKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboardView.java @@ -27,7 +27,6 @@ import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy; import com.android.inputmethod.keyboard.PointerTracker.TimerProxy; import com.android.inputmethod.latin.R; - /** * A view that renders a virtual {@link MiniKeyboard}. It handles rendering of keys and detecting * key presses and touch movements. @@ -115,7 +114,7 @@ public class MiniKeyboardView extends KeyboardView implements MoreKeysPanel { @Override public DrawingProxy getDrawingProxy() { - return this; + return this; } @Override @@ -174,9 +173,15 @@ public class MiniKeyboardView extends KeyboardView implements MoreKeysPanel { return x; } + private boolean mIsDismissing; + @Override public boolean dismissMoreKeysPanel() { - return mController.dismissMoreKeysPanel(); + if (mIsDismissing) return false; + mIsDismissing = true; + final boolean dismissed = mController.dismissMoreKeysPanel(); + mIsDismissing = false; + return dismissed; } @Override diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index d5986aa32..38c419dc6 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -18,7 +18,6 @@ package com.android.inputmethod.keyboard; import android.content.Context; import android.content.res.Resources; -import android.os.SystemClock; import android.util.Log; import android.view.MotionEvent; import android.widget.TextView; @@ -616,9 +615,9 @@ public class PointerTracker { } } - public void onShowMoreKeysPanel(int x, int y, KeyEventHandler handler) { + public void onShowMoreKeysPanel(int x, int y, long eventTime, KeyEventHandler handler) { onLongPressed(); - onDownEvent(x, y, SystemClock.uptimeMillis(), handler); + onDownEvent(x, y, eventTime, handler); mIsShowingMoreKeysPanel = true; } diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 1666fc191..567537df2 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -157,22 +157,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar SUGGESTION_VISIBILILTY_HIDE_VALUE }; - // Magic space: a space that should disappear on space/apostrophe insertion, move after the - // punctuation on punctuation insertion, and become a real space on alpha char insertion. - // Weak space: a space that be swapped only by suggestion strip punctuation. - // Double space: the state where the user pressed space twice quickly, which LatinIME - // resolved as period-space. Undoing this converts the period to a space. - // Swap punctuation: the state where a (weak or magic) space and a punctuation from the - // suggestion strip have just been swapped. Undoing this swaps them back. - private static final int SPACE_STATE_NONE = 0; - private static final int SPACE_STATE_DOUBLE = 1; - private static final int SPACE_STATE_SWAP_PUNCTUATION = 2; - private static final int SPACE_STATE_MAGIC = 3; - private static final int SPACE_STATE_WEAK = 4; - - // Current space state of the input method. This can be any of the above constants. - private int mSpaceState; - private Settings.Values mSettingsValues; private View mExtractArea; @@ -206,6 +190,12 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private WordComposer mWordComposer = new WordComposer(); private CharSequence mBestWord; private boolean mHasUncommittedTypedChars; + // Magic space: a space that should disappear on space/apostrophe insertion, move after the + // punctuation on punctuation insertion, and become a real space on alpha char insertion. + private boolean mJustAddedMagicSpace; // This indicates whether the last char is a magic space. + // This indicates whether the last keypress resulted in processing of double space replacement + // with period-space. + private boolean mJustReplacedDoubleSpace; private int mCorrectionMode; private int mCommittedLength; @@ -737,7 +727,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mComposingStringBuilder.setLength(0); mHasUncommittedTypedChars = false; mDeleteCount = 0; - mSpaceState = SPACE_STATE_NONE; + mJustAddedMagicSpace = false; + mJustReplacedDoubleSpace = false; loadSettings(); updateCorrectionMode(); @@ -898,13 +889,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar || newSelEnd != candidatesEnd) && mLastSelectionStart != newSelStart; final boolean candidatesCleared = candidatesStart == -1 && candidatesEnd == -1; if (!mExpectingUpdateSelection) { - if (SPACE_STATE_WEAK == mSpaceState) { - // Test for no WEAK_SPACE action because there is a race condition that may end up - // in coming here on a normal key press. We set this to NONE because after - // a cursor move, we don't want the suggestion strip to swap the space with the - // newly inserted punctuation. - mSpaceState = SPACE_STATE_NONE; - } if (((mComposingStringBuilder.length() > 0 && mHasUncommittedTypedChars) || mVoiceProxy.isVoiceInputHighlighted()) && (selectionChanged || candidatesCleared)) { @@ -922,6 +906,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar TextEntryState.reset(); updateSuggestions(); } + mJustAddedMagicSpace = false; // The user moved the cursor. + mJustReplacedDoubleSpace = false; } mExpectingUpdateSelection = false; mHandler.postUpdateShiftKeyState(); @@ -1146,22 +1132,25 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar return false; } - // "ic" may be null - private void swapSwapperAndSpaceWhileInBatchEdit(final InputConnection ic) { - if (null == ic) return; + private void swapSwapperAndSpace() { + final InputConnection ic = getCurrentInputConnection(); + if (ic == null) return; CharSequence lastTwo = ic.getTextBeforeCursor(2, 0); // It is guaranteed lastTwo.charAt(1) is a swapper - else this method is not called. if (lastTwo != null && lastTwo.length() == 2 && lastTwo.charAt(0) == Keyboard.CODE_SPACE) { + ic.beginBatchEdit(); ic.deleteSurroundingText(2, 0); ic.commitText(lastTwo.charAt(1) + " ", 1); + ic.endBatchEdit(); mKeyboardSwitcher.updateShiftState(); } } - private boolean maybeDoubleSpaceWhileInBatchEdit(final InputConnection ic) { - if (mCorrectionMode == Suggest.CORRECTION_NONE) return false; - if (ic == null) return false; + private void maybeDoubleSpace() { + if (mCorrectionMode == Suggest.CORRECTION_NONE) return; + final InputConnection ic = getCurrentInputConnection(); + if (ic == null) return; final CharSequence lastThree = ic.getTextBeforeCursor(3, 0); if (lastThree != null && lastThree.length() == 3 && Utils.canBeFollowedByPeriod(lastThree.charAt(0)) @@ -1169,19 +1158,22 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar && lastThree.charAt(2) == Keyboard.CODE_SPACE && mHandler.isAcceptingDoubleSpaces()) { mHandler.cancelDoubleSpacesTimer(); + ic.beginBatchEdit(); ic.deleteSurroundingText(2, 0); ic.commitText(". ", 1); + ic.endBatchEdit(); mKeyboardSwitcher.updateShiftState(); - return true; + mJustReplacedDoubleSpace = true; + } else { + mHandler.startDoubleSpacesTimer(); } - return false; } - // "ic" must not be null + // "ic" must not null private void maybeRemovePreviousPeriod(final InputConnection ic, CharSequence text) { // When the text's first character is '.', remove the previous period // if there is one. - final CharSequence lastOne = ic.getTextBeforeCursor(1, 0); + CharSequence lastOne = ic.getTextBeforeCursor(1, 0); if (lastOne != null && lastOne.length() == 1 && lastOne.charAt(0) == Keyboard.CODE_PERIOD && text.charAt(0) == Keyboard.CODE_PERIOD) { @@ -1189,10 +1181,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } } - // "ic" may be null - private void removeTrailingSpaceWhileInBatchEdit(final InputConnection ic) { + private void removeTrailingSpace() { + final InputConnection ic = getCurrentInputConnection(); if (ic == null) return; - final CharSequence lastOne = ic.getTextBeforeCursor(1, 0); + + CharSequence lastOne = ic.getTextBeforeCursor(1, 0); if (lastOne != null && lastOne.length() == 1 && lastOne.charAt(0) == Keyboard.CODE_SPACE) { ic.deleteSurroundingText(1, 0); @@ -1229,7 +1222,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // Virtual codes representing custom requests. These are used in onCustomRequest() below. public static final int CODE_SHOW_INPUT_METHOD_PICKER = 1; - public static final int CODE_HAPTIC_AND_AUDIO_FEEDBACK = 2; @Override public boolean onCustomRequest(int requestCode) { @@ -1241,9 +1233,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar return true; } return false; - case CODE_HAPTIC_AND_AUDIO_FEEDBACK: - hapticAndAudioFeedback(Keyboard.CODE_UNSPECIFIED); - return true; } return false; } @@ -1252,28 +1241,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar return mOptionsDialog != null && mOptionsDialog.isShowing(); } - private void insertPunctuationFromSuggestionStrip(final InputConnection ic, final int code) { - final CharSequence beforeText = ic != null ? ic.getTextBeforeCursor(1, 0) : null; - final int toLeft = TextUtils.isEmpty(beforeText) ? 0 : beforeText.charAt(0); - final boolean shouldRegisterSwapPunctuation; - // If we have a space left of the cursor and it's a weak or a magic space, then we should - // swap it, and override the space state with SPACESTATE_SWAP_PUNCTUATION. - // To swap it, we fool handleSeparator to think the previous space state was a - // magic space. - if (Keyboard.CODE_SPACE == toLeft && mSpaceState == SPACE_STATE_WEAK) { - mSpaceState = SPACE_STATE_MAGIC; - shouldRegisterSwapPunctuation = true; - } else { - shouldRegisterSwapPunctuation = false; - } - onCodeInput(code, new int[] { code }, - KeyboardActionListener.NOT_A_TOUCH_COORDINATE, - KeyboardActionListener.NOT_A_TOUCH_COORDINATE); - if (shouldRegisterSwapPunctuation) { - mSpaceState = SPACE_STATE_SWAP_PUNCTUATION; - } - } - // Implementation of {@link KeyboardActionListener}. @Override public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) { @@ -1284,16 +1251,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mLastKeyTime = when; KeyboardSwitcher switcher = mKeyboardSwitcher; final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); - // The space state depends only on the last character pressed and its own previous - // state. Here, we revert the space state to neutral if the key is actually modifying - // the input contents (any non-shift key), which is what we should do for - // all inputs that do not result in a special state. Each character handling is then - // free to override the state as they see fit. - final int spaceState = mSpaceState; + final boolean lastStateOfJustReplacedDoubleSpace = mJustReplacedDoubleSpace; + mJustReplacedDoubleSpace = false; switch (primaryCode) { case Keyboard.CODE_DELETE: - mSpaceState = SPACE_STATE_NONE; - handleBackspace(spaceState); + handleBackspace(lastStateOfJustReplacedDoubleSpace); mDeleteCount++; mExpectingUpdateSelection = true; LatinImeLogger.logOnDelete(); @@ -1318,7 +1280,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar break; case Keyboard.CODE_CAPSLOCK: switcher.toggleCapsLock(); - hapticAndAudioFeedback(primaryCode); + //$FALL-THROUGH$ + case Keyboard.CODE_HAPTIC_AND_AUDIO_FEEDBACK_ONLY: + // Dummy code for haptic and audio feedbacks. + vibrate(); + playKeyClick(primaryCode); break; case Keyboard.CODE_SHORTCUT: mSubtypeSwitcher.switchToShortcutIME(); @@ -1335,11 +1301,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // To sum it up: do not update mExpectingUpdateSelection here. break; default: - mSpaceState = SPACE_STATE_NONE; if (mSettingsValues.isWordSeparator(primaryCode)) { - handleSeparator(primaryCode, x, y, spaceState); + handleSeparator(primaryCode, x, y); } else { - handleCharacter(primaryCode, keyCodes, x, y, spaceState); + handleCharacter(primaryCode, keyCodes, x, y); } mExpectingUpdateSelection = true; break; @@ -1361,7 +1326,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar ic.endBatchEdit(); mKeyboardSwitcher.updateShiftState(); mKeyboardSwitcher.onKey(Keyboard.CODE_DUMMY); - mSpaceState = SPACE_STATE_NONE; + mJustAddedMagicSpace = false; mEnteredText = text; } @@ -1371,7 +1336,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mKeyboardSwitcher.onCancelInput(); } - private void handleBackspace(final int spaceState) { + private void handleBackspace(boolean justReplacedDoubleSpace) { if (mVoiceProxy.logAndRevertVoiceInput()) return; final InputConnection ic = getCurrentInputConnection(); @@ -1409,24 +1374,15 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } mHandler.postUpdateShiftKeyState(); - // TODO: Merge space state with TextEntryState TextEntryState.backspace(); if (TextEntryState.isUndoCommit()) { revertLastWord(ic); ic.endBatchEdit(); return; } - if (SPACE_STATE_DOUBLE == spaceState) { + if (justReplacedDoubleSpace) { if (revertDoubleSpace(ic)) { ic.endBatchEdit(); - // No need to reset mSpaceState, it has already be done (that's why we - // receive it as a parameter) - return; - } - } else if (SPACE_STATE_SWAP_PUNCTUATION == spaceState) { - if (revertSwapPunctuation(ic)) { - ic.endBatchEdit(); - // Likewise return; } } @@ -1476,15 +1432,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } } - private void handleCharacter(final int primaryCode, final int[] keyCodes, final int x, - final int y, final int spaceState) { + private void handleCharacter(int primaryCode, int[] keyCodes, int x, int y) { mVoiceProxy.handleCharacter(); - final InputConnection ic = getCurrentInputConnection(); - if (ic != null) ic.beginBatchEdit(); - if (SPACE_STATE_MAGIC == spaceState - && mSettingsValues.isMagicSpaceStripper(primaryCode)) { - removeTrailingSpaceWhileInBatchEdit(ic); + if (mJustAddedMagicSpace && mSettingsValues.isMagicSpaceStripper(primaryCode)) { + removeTrailingSpace(); } int code = primaryCode; @@ -1502,7 +1454,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar if (switcher.isShiftedOrShiftLocked()) { if (keyCodes == null || keyCodes[0] < Character.MIN_CODE_POINT || keyCodes[0] > Character.MAX_CODE_POINT) { - if (null != ic) ic.endBatchEdit(); return; } code = keyCodes[0]; @@ -1516,7 +1467,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } else { // Some keys, such as [eszett], have upper case as multi-characters. onTextInput(upperCaseString); - if (null != ic) ic.endBatchEdit(); return; } } @@ -1524,6 +1474,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar if (mHasUncommittedTypedChars) { mComposingStringBuilder.append((char) code); mWordComposer.add(code, keyCodes, x, y); + final InputConnection ic = getCurrentInputConnection(); if (ic != null) { // If it's the first letter, make note of auto-caps state if (mWordComposer.size() == 1) { @@ -1541,19 +1492,18 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } else { sendKeyChar((char)code); } - if (SPACE_STATE_MAGIC == spaceState - && mSettingsValues.isMagicSpaceSwapper(primaryCode)) { - if (null != ic) swapSwapperAndSpaceWhileInBatchEdit(ic); + if (mJustAddedMagicSpace && mSettingsValues.isMagicSpaceSwapper(primaryCode)) { + swapSwapperAndSpace(); + } else { + mJustAddedMagicSpace = false; } switcher.updateShiftState(); if (LatinIME.PERF_DEBUG) measureCps(); TextEntryState.typedCharacter((char) code, mSettingsValues.isWordSeparator(code), x, y); - if (null != ic) ic.endBatchEdit(); } - private void handleSeparator(final int primaryCode, final int x, final int y, - final int spaceState) { + private void handleSeparator(int primaryCode, int x, int y) { mVoiceProxy.handleSeparator(); mComposingStateManager.onFinishComposingText(); @@ -1583,45 +1533,21 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } } - final boolean swapMagicSpace; - if (SPACE_STATE_MAGIC == spaceState) { + if (mJustAddedMagicSpace) { if (mSettingsValues.isMagicSpaceSwapper(primaryCode)) { - swapMagicSpace = true; + sendKeyChar((char)primaryCode); + swapSwapperAndSpace(); } else { - swapMagicSpace = false; - if (mSettingsValues.isMagicSpaceStripper(primaryCode)) { - removeTrailingSpaceWhileInBatchEdit(ic); - } + if (mSettingsValues.isMagicSpaceStripper(primaryCode)) removeTrailingSpace(); + sendKeyChar((char)primaryCode); + mJustAddedMagicSpace = false; } } else { - swapMagicSpace = false; + sendKeyChar((char)primaryCode); } - sendKeyChar((char)primaryCode); - - if (Keyboard.CODE_SPACE == primaryCode) { - if (isSuggestionsRequested()) { - if (maybeDoubleSpaceWhileInBatchEdit(ic)) { - mSpaceState = SPACE_STATE_DOUBLE; - } else if (!isShowingPunctuationList()) { - mSpaceState = SPACE_STATE_WEAK; - } - } - - mHandler.startDoubleSpacesTimer(); - if (!isCursorTouchingWord()) { - mHandler.cancelUpdateSuggestions(); - mHandler.postUpdateBigramPredictions(); - } - } else { - if (swapMagicSpace) { - swapSwapperAndSpaceWhileInBatchEdit(ic); - mSpaceState = SPACE_STATE_MAGIC; - } - - // Set punctuation right away. onUpdateSelection will fire but tests whether it is - // already displayed or not, so it's okay. - setPunctuationSuggestions(); + if (isSuggestionsRequested() && primaryCode == Keyboard.CODE_SPACE) { + maybeDoubleSpace(); } TextEntryState.typedCharacter((char) primaryCode, true, x, y); @@ -1634,6 +1560,16 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar ic, mLastSelectionEnd - typedWord.length(), typedWord, mBestWord); } } + if (Keyboard.CODE_SPACE == primaryCode) { + if (!isCursorTouchingWord()) { + mHandler.cancelUpdateSuggestions(); + mHandler.postUpdateBigramPredictions(); + } + } else { + // Set punctuation right away. onUpdateSelection will fire but tests whether it is + // already displayed or not, so it's okay. + setPunctuationSuggestions(); + } mKeyboardSwitcher.updateShiftState(); if (ic != null) { ic.endBatchEdit(); @@ -1668,7 +1604,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar public boolean isSuggestionsStripVisible() { if (mSuggestionsView == null) return false; - if (mSuggestionsView.isShowingAddToDictionaryHint()) + if (mSuggestionsView.isShowingAddToDictionaryHint() || TextEntryState.isRecorrecting()) return true; if (!isShowingSuggestionsStrip()) return false; @@ -1773,6 +1709,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } // Don't auto-correct words with multiple capital letter autoCorrectionAvailable &= !wordComposer.isMostlyCaps(); + autoCorrectionAvailable &= !TextEntryState.isRecorrecting(); // Basically, we update the suggestion strip only when suggestion count > 1. However, // there is an exception: We update the suggestion strip whenever typed word's length @@ -1845,6 +1782,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mVoiceProxy.flushAndLogAllTextModificationCounters(index, suggestion, mSettingsValues.mWordSeparators); + final boolean recorrecting = TextEntryState.isRecorrecting(); final InputConnection ic = getCurrentInputConnection(); if (ic != null) { ic.beginBatchEdit(); @@ -1874,8 +1812,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar LatinImeLogger.logOnManualSuggestion( "", suggestion.toString(), index, suggestions.mWords); // Find out whether the previous character is a space. If it is, as a special case - // for punctuation entered through the suggestion strip, it should be swapped - // if it was a magic or a weak space. This is meant to help in case the user + // for punctuation entered through the suggestion strip, it should be considered + // a magic space even if it was a normal space. This is meant to help in case the user // pressed space on purpose of displaying the suggestion strip punctuation. final int rawPrimaryCode = suggestion.charAt(0); // Maybe apply the "bidi mirrored" conversions for parentheses @@ -1883,8 +1821,15 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar final boolean isRtl = keyboard != null && keyboard.mIsRtlKeyboard; final int primaryCode = Key.getRtlParenthesisCode(rawPrimaryCode, isRtl); - insertPunctuationFromSuggestionStrip(ic, primaryCode); - // TODO: the following endBatchEdit seems useless, check + final CharSequence beforeText = ic != null ? ic.getTextBeforeCursor(1, 0) : ""; + final int toLeft = (ic == null || TextUtils.isEmpty(beforeText)) + ? 0 : beforeText.charAt(0); + final boolean oldMagicSpace = mJustAddedMagicSpace; + if (Keyboard.CODE_SPACE == toLeft) mJustAddedMagicSpace = true; + onCodeInput(primaryCode, new int[] { primaryCode }, + KeyboardActionListener.NOT_A_TOUCH_COORDINATE, + KeyboardActionListener.NOT_A_TOUCH_COORDINATE); + mJustAddedMagicSpace = oldMagicSpace; if (ic != null) { ic.endBatchEdit(); } @@ -1908,7 +1853,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar suggestion.toString(), index, suggestions.mWords); TextEntryState.acceptedSuggestion(mComposingStringBuilder.toString(), suggestion); // Follow it with a space - if (mInsertSpaceOnPickSuggestionManually) { + if (mInsertSpaceOnPickSuggestionManually && !recorrecting) { sendMagicSpace(); } @@ -1928,11 +1873,13 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar || !AutoCorrection.isValidWord( mSuggest.getUnigramDictionaries(), suggestion, true)); - // Fool the state watcher so that a subsequent backspace will not do a revert, unless - // we just did a correction, in which case we need to stay in - // TextEntryState.State.PICKED_SUGGESTION state. - TextEntryState.typedCharacter((char) Keyboard.CODE_SPACE, true, - WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE); + if (!recorrecting) { + // Fool the state watcher so that a subsequent backspace will not do a revert, unless + // we just did a correction, in which case we need to stay in + // TextEntryState.State.PICKED_SUGGESTION state. + TextEntryState.typedCharacter((char) Keyboard.CODE_SPACE, true, + WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE); + } if (!showingAddToDictionaryHint) { // If we're not showing the "Touch again to save", then show corrections again. // In case the cursor position doesn't change, make sure we show the suggestions again. @@ -2074,13 +2021,13 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar return false; } - // "ic" must not be null + // "ic" must not null private boolean sameAsTextBeforeCursor(final InputConnection ic, CharSequence text) { CharSequence beforeText = ic.getTextBeforeCursor(text.length(), 0); return TextUtils.equals(text, beforeText); } - // "ic" must not be null + // "ic" must not null private void revertLastWord(final InputConnection ic) { if (mHasUncommittedTypedChars || mComposingStringBuilder.length() <= 0) { sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); @@ -2114,7 +2061,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mHandler.postUpdateSuggestions(); } - // "ic" must not be null + // "ic" must not null private boolean revertDoubleSpace(final InputConnection ic) { mHandler.cancelDoubleSpacesTimer(); // Here we test whether we indeed have a period and a space before us. This should not @@ -2129,28 +2076,13 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar return true; } - private boolean revertSwapPunctuation(final InputConnection ic) { - // Here we test whether we indeed have a space and something else before us. This should not - // be needed, but it's there just in case something went wrong. - final CharSequence textBeforeCursor = ic.getTextBeforeCursor(2, 0); - // NOTE: This does not work with surrogate pairs. Hopefully when the keyboard is able to - // enter surrogate pairs this code will have been removed. - if (Keyboard.CODE_SPACE != textBeforeCursor.charAt(1)) - return false; - ic.beginBatchEdit(); - ic.deleteSurroundingText(2, 0); - ic.commitText(" " + textBeforeCursor.subSequence(0, 1), 1); - ic.endBatchEdit(); - return true; - } - public boolean isWordSeparator(int code) { return mSettingsValues.isWordSeparator(code); } private void sendMagicSpace() { sendKeyChar((char)Keyboard.CODE_SPACE); - mSpaceState = SPACE_STATE_MAGIC; + mJustAddedMagicSpace = true; mKeyboardSwitcher.updateShiftState(); } @@ -2172,16 +2104,12 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar loadSettings(); } - private void hapticAndAudioFeedback(int primaryCode) { - vibrate(); - playKeyClick(primaryCode); - } - @Override public void onPress(int primaryCode, boolean withSliding) { final KeyboardSwitcher switcher = mKeyboardSwitcher; if (switcher.isVibrateAndSoundFeedbackRequired()) { - hapticAndAudioFeedback(primaryCode); + vibrate(); + playKeyClick(primaryCode); } final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); if (distinctMultiTouch && primaryCode == Keyboard.CODE_SHIFT) { diff --git a/java/src/com/android/inputmethod/latin/MoreSuggestionsView.java b/java/src/com/android/inputmethod/latin/MoreSuggestionsView.java index 51f6c040d..c61dd6313 100644 --- a/java/src/com/android/inputmethod/latin/MoreSuggestionsView.java +++ b/java/src/com/android/inputmethod/latin/MoreSuggestionsView.java @@ -35,7 +35,6 @@ import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy; import com.android.inputmethod.keyboard.PointerTracker.KeyEventHandler; import com.android.inputmethod.keyboard.PointerTracker.TimerProxy; - /** * A view that renders a virtual {@link MoreSuggestions}. It handles rendering of keys and detecting * key presses and touch movements. @@ -125,7 +124,7 @@ public class MoreSuggestionsView extends KeyboardView implements MoreKeysPanel { @Override public DrawingProxy getDrawingProxy() { - return this; + return this; } @Override @@ -180,10 +179,15 @@ public class MoreSuggestionsView extends KeyboardView implements MoreKeysPanel { return x; } + private boolean mIsDismissing; + @Override public boolean dismissMoreKeysPanel() { - if (mController == null) return false; - return mController.dismissMoreKeysPanel(); + if (mIsDismissing) return false; + mIsDismissing = true; + final boolean dismissed = mController.dismissMoreKeysPanel(); + mIsDismissing = false; + return dismissed; } @Override diff --git a/java/src/com/android/inputmethod/latin/SuggestionsView.java b/java/src/com/android/inputmethod/latin/SuggestionsView.java index 3b0715cfd..c25ecb382 100644 --- a/java/src/com/android/inputmethod/latin/SuggestionsView.java +++ b/java/src/com/android/inputmethod/latin/SuggestionsView.java @@ -30,6 +30,7 @@ import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Message; +import android.os.SystemClock; import android.text.Spannable; import android.text.SpannableString; import android.text.Spanned; @@ -831,7 +832,8 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, // Decided to be in the sliding input mode only when the touch point has been moved // upward. mMoreSuggestionsMode = MORE_SUGGESTIONS_IN_SLIDING_MODE; - tracker.onShowMoreKeysPanel(translatedX, translatedY, moreKeysPanel); + tracker.onShowMoreKeysPanel( + translatedX, translatedY, SystemClock.uptimeMillis(), moreKeysPanel); } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP) { // Decided to be in the modal input mode mMoreSuggestionsMode = MORE_SUGGESTIONS_IN_MODAL_MODE; diff --git a/java/src/com/android/inputmethod/latin/TextEntryState.java b/java/src/com/android/inputmethod/latin/TextEntryState.java index 82242f87e..79b3bdebb 100644 --- a/java/src/com/android/inputmethod/latin/TextEntryState.java +++ b/java/src/com/android/inputmethod/latin/TextEntryState.java @@ -30,10 +30,13 @@ public class TextEntryState { private static final int IN_WORD = 2; private static final int ACCEPTED_DEFAULT = 3; private static final int PICKED_SUGGESTION = 4; - private static final int PUNCTUATION_AFTER_ACCEPTED = 5; - private static final int SPACE_AFTER_ACCEPTED = 6; - private static final int SPACE_AFTER_PICKED = 7; - private static final int UNDO_COMMIT = 8; + private static final int PUNCTUATION_AFTER_WORD = 5; + private static final int PUNCTUATION_AFTER_ACCEPTED = 6; + private static final int SPACE_AFTER_ACCEPTED = 7; + private static final int SPACE_AFTER_PICKED = 8; + private static final int UNDO_COMMIT = 9; + private static final int RECORRECTING = 10; + private static final int PICKED_RECORRECTION = 11; private static int sState = UNKNOWN; private static int sPreviousState = UNKNOWN; @@ -76,11 +79,27 @@ public class TextEntryState { } public static void acceptedSuggestion(CharSequence typedWord, CharSequence actualWord) { - setState(PICKED_SUGGESTION); + if (sState == RECORRECTING || sState == PICKED_RECORRECTION) { + setState(PICKED_RECORRECTION); + } else { + setState(PICKED_SUGGESTION); + } if (DEBUG) displayState("acceptedSuggestion", "typedWord", typedWord, "actualWord", actualWord); } + public static void selectedForRecorrection() { + setState(RECORRECTING); + if (DEBUG) displayState("selectedForRecorrection"); + } + + public static void onAbortRecorrection() { + if (sState == RECORRECTING || sState == PICKED_RECORRECTION) { + setState(START); + } + if (DEBUG) displayState("onAbortRecorrection"); + } + public static void typedCharacter(char c, boolean isSeparator, int x, int y) { final boolean isSpace = (c == Keyboard.CODE_SPACE); switch (sState) { @@ -104,6 +123,7 @@ public class TextEntryState { } break; case PICKED_SUGGESTION: + case PICKED_RECORRECTION: if (isSpace) { setState(SPACE_AFTER_PICKED); } else if (isSeparator) { @@ -116,6 +136,7 @@ public class TextEntryState { case START: case UNKNOWN: case SPACE_AFTER_ACCEPTED: + case PUNCTUATION_AFTER_WORD: if (!isSpace && !isSeparator) { setState(IN_WORD); } else { @@ -129,6 +150,9 @@ public class TextEntryState { setState(IN_WORD); } break; + case RECORRECTING: + setState(START); + break; } RingCharBuffer.getInstance().push(c, x, y); if (isSeparator) { @@ -154,10 +178,26 @@ public class TextEntryState { if (DEBUG) displayState("reset"); } + public static boolean isAcceptedDefault() { + return sState == ACCEPTED_DEFAULT; + } + + public static boolean isSpaceAfterPicked() { + return sState == SPACE_AFTER_PICKED; + } + public static boolean isUndoCommit() { return sState == UNDO_COMMIT; } + public static boolean isPunctuationAfterAccepted() { + return sState == PUNCTUATION_AFTER_ACCEPTED; + } + + public static boolean isRecorrecting() { + return sState == RECORRECTING || sState == PICKED_RECORRECTION; + } + public static String getState() { return stateName(sState); } @@ -168,10 +208,13 @@ public class TextEntryState { case IN_WORD: return "IN_WORD"; case ACCEPTED_DEFAULT: return "ACCEPTED_DEFAULT"; case PICKED_SUGGESTION: return "PICKED_SUGGESTION"; + case PUNCTUATION_AFTER_WORD: return "PUNCTUATION_AFTER_WORD"; case PUNCTUATION_AFTER_ACCEPTED: return "PUNCTUATION_AFTER_ACCEPTED"; case SPACE_AFTER_ACCEPTED: return "SPACE_AFTER_ACCEPTED"; case SPACE_AFTER_PICKED: return "SPACE_AFTER_PICKED"; case UNDO_COMMIT: return "UNDO_COMMIT"; + case RECORRECTING: return "RECORRECTING"; + case PICKED_RECORRECTION: return "PICKED_RECORRECTION"; default: return "UNKNOWN"; } } |