diff options
Diffstat (limited to 'java/src')
7 files changed, 165 insertions, 105 deletions
diff --git a/java/src/com/android/inputmethod/compat/ViewCompatUtils.java b/java/src/com/android/inputmethod/compat/ViewCompatUtils.java index deb6809e7..afbe8c890 100644 --- a/java/src/com/android/inputmethod/compat/ViewCompatUtils.java +++ b/java/src/com/android/inputmethod/compat/ViewCompatUtils.java @@ -31,6 +31,9 @@ public final class ViewCompatUtils { private static final Method METHOD_setPaddingRelative = CompatUtils.getMethod( View.class, "setPaddingRelative", int.class, int.class, int.class, int.class); + // Note that View.setElevation(float) has been introduced in API level 21. + private static final Method METHOD_setElevation = CompatUtils.getMethod( + View.class, "setElevation", float.class); private ViewCompatUtils() { // This utility class is not publicly instantiable. @@ -51,4 +54,11 @@ public final class ViewCompatUtils { } CompatUtils.invoke(view, null, METHOD_setPaddingRelative, start, top, end, bottom); } + + public static void setElevation(final View view, final float elevation) { + if (METHOD_setElevation == null) { + return; + } + CompatUtils.invoke(view, null, METHOD_setElevation, elevation); + } } diff --git a/java/src/com/android/inputmethod/event/InputTransaction.java b/java/src/com/android/inputmethod/event/InputTransaction.java index 5bc9111de..b18bf5638 100644 --- a/java/src/com/android/inputmethod/event/InputTransaction.java +++ b/java/src/com/android/inputmethod/event/InputTransaction.java @@ -33,7 +33,7 @@ public class InputTransaction { // Initial conditions public final SettingsValues mSettingsValues; - public final Event mEvent; + private final Event mEvent; public final long mTimestamp; public final int mSpaceState; public final int mShiftState; diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index f967f620a..5af0be649 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -29,6 +29,7 @@ import android.graphics.Region; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.graphics.drawable.NinePatchDrawable; +import android.text.TextUtils; import android.util.AttributeSet; import android.view.View; @@ -48,6 +49,7 @@ import java.util.HashSet; * @attr ref R.styleable#KeyboardView_spacebarBackground * @attr ref R.styleable#KeyboardView_spacebarIconWidthRatio * @attr ref R.styleable#KeyboardView_keyHintLetterPadding + * @attr ref R.styleable#KeyboardView_keyPopupHintLetter * @attr ref R.styleable#KeyboardView_keyPopupHintLetterPadding * @attr ref R.styleable#KeyboardView_keyShiftedLetterHintPadding * @attr ref R.styleable#KeyboardView_keyTextShadowRadius @@ -74,6 +76,7 @@ public class KeyboardView extends View { // XML attributes private final KeyVisualAttributes mKeyVisualAttributes; private final float mKeyHintLetterPadding; + private final String mKeyPopupHintLetter; private final float mKeyPopupHintLetterPadding; private final float mKeyShiftedLetterHintPadding; private final float mKeyTextShadowRadius; @@ -85,9 +88,6 @@ public class KeyboardView extends View { private final Rect mKeyBackgroundPadding = new Rect(); private static final float KET_TEXT_SHADOW_RADIUS_DISABLED = -1.0f; - // HORIZONTAL ELLIPSIS "...", character for popup hint. - private static final String POPUP_HINT_CHAR = "\u2026"; - // The maximum key label width in the proportion to the key width. private static final float MAX_LABEL_RATIO = 0.90f; @@ -132,6 +132,8 @@ public class KeyboardView extends View { R.styleable.KeyboardView_spacebarIconWidthRatio, 1.0f); mKeyHintLetterPadding = keyboardViewAttr.getDimension( R.styleable.KeyboardView_keyHintLetterPadding, 0.0f); + mKeyPopupHintLetter = keyboardViewAttr.getString( + R.styleable.KeyboardView_keyPopupHintLetter); mKeyPopupHintLetterPadding = keyboardViewAttr.getDimension( R.styleable.KeyboardView_keyPopupHintLetterPadding, 0.0f); mKeyShiftedLetterHintPadding = keyboardViewAttr.getDimension( @@ -468,6 +470,9 @@ public class KeyboardView extends View { // Draw popup hint "..." at the bottom right corner of the key. protected void drawKeyPopupHint(final Key key, final Canvas canvas, final Paint paint, final KeyDrawParams params) { + if (TextUtils.isEmpty(mKeyPopupHintLetter)) { + return; + } final int keyWidth = key.getDrawWidth(); final int keyHeight = key.getHeight(); @@ -478,7 +483,7 @@ public class KeyboardView extends View { final float hintX = keyWidth - mKeyHintLetterPadding - TypefaceUtils.getReferenceCharWidth(paint) / 2.0f; final float hintY = keyHeight - mKeyPopupHintLetterPadding; - canvas.drawText(POPUP_HINT_CHAR, hintX, hintY, paint); + canvas.drawText(mKeyPopupHintLetter, hintX, hintY, paint); } protected static void drawIcon(final Canvas canvas, final Drawable icon, final int x, diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 4adc28d7a..c7c3aaa18 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -295,7 +295,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } } - public void postResetCaches(final boolean tryResumeSuggestions, final int remainingTries) { + public void postResetInputConnectionCaches(final boolean tryResumeSuggestions, + final int remainingTries) { removeMessages(MSG_RESET_CACHES); sendMessage(obtainMessage(MSG_RESET_CACHES, tryResumeSuggestions ? 1 : 0, remainingTries, null)); @@ -762,9 +763,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private static class EditorChangeInfo { public final boolean mIsSameInputType; public final boolean mHasSameOrientation; - public EditorChangeInfo(final boolean isSameInputType, final boolean hasSameOrientation) { + public final boolean mCanReachInputConnection; + public EditorChangeInfo(final boolean isSameInputType, final boolean hasSameOrientation, + final boolean canReachInputConnection) { mIsSameInputType = isSameInputType; mHasSameOrientation = hasSameOrientation; + mCanReachInputConnection = canReachInputConnection; } } @@ -772,16 +776,66 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private void onStartInputInternal(final EditorInfo editorInfo, final boolean restarting) { super.onStartInput(editorInfo, restarting); + if (editorInfo == null) { + Log.e(TAG, "Null EditorInfo in onStartInput()"); + return; + } SettingsValues currentSettingsValues = mSettings.getCurrent(); - mLastEditorChangeInfo = new EditorChangeInfo( - currentSettingsValues.isSameInputType(editorInfo), - currentSettingsValues.hasSameOrientation(getResources().getConfiguration())); + final boolean isSameInputType = currentSettingsValues.isSameInputType(editorInfo); + final boolean hasSameOrientation = + currentSettingsValues.hasSameOrientation(getResources().getConfiguration()); + mRichImm.clearSubtypeCaches(); + final boolean inputTypeChanged = !isSameInputType; + final boolean isDifferentTextField = !restarting || inputTypeChanged; + if (isDifferentTextField || !hasSameOrientation) { + loadSettings(); + currentSettingsValues = mSettings.getCurrent(); + } + + // Note: the following does a round-trip IPC on the main thread: be careful + final Locale currentLocale = mSubtypeSwitcher.getCurrentSubtypeLocale(); + final Suggest suggest = mInputLogic.mSuggest; + if (null != currentLocale && !currentLocale.equals(suggest.getLocale())) { + // TODO: Do this automatically. + resetSuggest(); + } + if (isDifferentTextField && currentSettingsValues.mAutoCorrectionEnabledPerUserSettings) { + suggest.setAutoCorrectionThreshold(currentSettingsValues.mAutoCorrectionThreshold); + } + + // The app calling setText() has the effect of clearing the composing + // 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(mSubtypeSwitcher.getCombiningRulesExtraValueOfCurrentSubtype()); + // TODO[IL]: Can the following be moved to InputLogic#startInput? + final boolean canReachInputConnection; + if (!mInputLogic.mConnection.resetCachesUponCursorMoveAndReturnSuccess( + editorInfo.initialSelStart, editorInfo.initialSelEnd, + false /* shouldFinishComposition */)) { + // Sometimes, while rotating, for some reason the framework tells the app we are not + // connected to it and that means we can't refresh the cache. In this case, schedule a + // refresh later. + // We try resetting the caches up to 5 times before giving up. + mHandler.postResetInputConnectionCaches(isDifferentTextField || !hasSameOrientation, + 5 /* remainingTries */); + canReachInputConnection = false; + } else { + // When rotating, initialSelStart and initialSelEnd sometimes are lying. Make a best + // effort to work around this bug. + mInputLogic.mConnection.tryFixLyingCursorPosition(); + mHandler.postResumeSuggestions(true /* shouldIncludeResumedWordInSuggestions */, + true /* shouldDelay */); + canReachInputConnection = true; + } + + mLastEditorChangeInfo = new EditorChangeInfo(isSameInputType, hasSameOrientation, + canReachInputConnection); } @SuppressWarnings("deprecation") private void onStartInputViewInternal(final EditorInfo editorInfo, final boolean restarting) { super.onStartInputView(editorInfo, restarting); - mRichImm.clearSubtypeCaches(); final KeyboardSwitcher switcher = mKeyboardSwitcher; switcher.updateKeyboardTheme(); final MainKeyboardView mainKeyboardView = switcher.getMainKeyboardView(); @@ -837,56 +891,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // Note: This call should be done by InputMethodService? updateFullscreenMode(); - // The app calling setText() has the effect of clearing the composing - // 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(mSubtypeSwitcher.getCombiningRulesExtraValueOfCurrentSubtype()); - - // Note: the following does a round-trip IPC on the main thread: be careful - final Locale currentLocale = mSubtypeSwitcher.getCurrentSubtypeLocale(); - final Suggest suggest = mInputLogic.mSuggest; - if (null != currentLocale && !currentLocale.equals(suggest.getLocale())) { - // TODO: Do this automatically. - resetSuggest(); - } - - // TODO[IL]: Can the following be moved to InputLogic#startInput? - final boolean canReachInputConnection; - if (!mInputLogic.mConnection.resetCachesUponCursorMoveAndReturnSuccess( - editorInfo.initialSelStart, editorInfo.initialSelEnd, - false /* shouldFinishComposition */)) { - // Sometimes, while rotating, for some reason the framework tells the app we are not - // connected to it and that means we can't refresh the cache. In this case, schedule a - // refresh later. - // We try resetting the caches up to 5 times before giving up. - mHandler.postResetCaches(isDifferentTextField, 5 /* remainingTries */); - // mLastSelection{Start,End} are reset later in this method, don't need to do it here - canReachInputConnection = false; - } else { - // When rotating, initialSelStart and initialSelEnd sometimes are lying. Make a best - // effort to work around this bug. - mInputLogic.mConnection.tryFixLyingCursorPosition(); - mHandler.postResumeSuggestions(true /* shouldIncludeResumedWordInSuggestions */, - true /* shouldDelay */); - canReachInputConnection = true; - } - - if (isDifferentTextField || !mLastEditorChangeInfo.mHasSameOrientation) { - loadSettings(); - } final SettingsValues currentSettingsValues = mSettings.getCurrent(); if (isDifferentTextField) { mainKeyboardView.closing(); - if (currentSettingsValues.mAutoCorrectionEnabledPerUserSettings) { - suggest.setAutoCorrectionThreshold( - currentSettingsValues.mAutoCorrectionThreshold); - } - switcher.loadKeyboard(editorInfo, currentSettingsValues, getCurrentAutoCapsState(), getCurrentRecapitalizeState()); - if (!canReachInputConnection) { + if (!mLastEditorChangeInfo.mCanReachInputConnection) { // If we can't reach the input connection, we will call loadKeyboard again later, // so we need to save its state now. The call will be done in #retryResetCaches. switcher.saveKeyboardState(); diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java index a6b3b710b..ea63cef02 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -17,6 +17,7 @@ package com.android.inputmethod.latin; import android.inputmethodservice.InputMethodService; +import android.os.Build; import android.text.TextUtils; import android.util.Log; import android.view.KeyEvent; @@ -811,4 +812,25 @@ public final class RichInputConnection { public boolean isCursorPositionKnown() { return INVALID_CURSOR_POSITION != mExpectedSelStart; } + + /** + * Work around a bug that was present before Jelly Bean upon rotation. + * + * Before Jelly Bean, there is a bug where setComposingRegion and other committing + * functions on the input connection get ignored until the cursor moves. This method works + * around the bug by wiggling the cursor first, which reactivates the connection and has + * the subsequent methods work, then restoring it to its original position. + * + * On platforms on which this method is not present, this is a no-op. + */ + public void maybeMoveTheCursorAroundAndRestoreToWorkaroundABug() { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { + if (mExpectedSelStart > 0) { + mIC.setSelection(mExpectedSelStart - 1, mExpectedSelStart - 1); + } else { + mIC.setSelection(mExpectedSelStart + 1, mExpectedSelStart + 1); + } + mIC.setSelection(mExpectedSelStart, mExpectedSelEnd); + } + } } diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java index 9e20abc17..2be792040 100644 --- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java @@ -426,12 +426,17 @@ public final class InputLogic { cancelDoubleSpacePeriodCountdown(); } - if (processedEvent.isConsumed()) { - handleConsumedEvent(inputTransaction); - } else if (processedEvent.isFunctionalKeyEvent()) { - handleFunctionalEvent(inputTransaction, currentKeyboardScriptId, handler); - } else { - handleNonFunctionalEvent(inputTransaction, handler); + Event currentEvent = processedEvent; + while (null != currentEvent) { + if (currentEvent.isConsumed()) { + handleConsumedEvent(currentEvent, inputTransaction); + } else if (currentEvent.isFunctionalKeyEvent()) { + handleFunctionalEvent(currentEvent, inputTransaction, currentKeyboardScriptId, + handler); + } else { + handleNonFunctionalEvent(currentEvent, inputTransaction, handler); + } + currentEvent = currentEvent.mNextEvent; } if (!inputTransaction.didAutoCorrect() && processedEvent.mKeyCode != Constants.CODE_SHIFT && processedEvent.mKeyCode != Constants.CODE_CAPSLOCK @@ -584,13 +589,14 @@ public final class InputLogic { * Consumed events represent events that have already been consumed, typically by the * combining chain. * + * @param event The event to handle. * @param inputTransaction The transaction in progress. */ - private void handleConsumedEvent(final InputTransaction inputTransaction) { + private void handleConsumedEvent(final Event event, final InputTransaction inputTransaction) { // A consumed event may have text to commit and an update to the composing state, so // we evaluate both. With some combiners, it's possible than an event contains both // and we enter both of the following if clauses. - final CharSequence textToCommit = inputTransaction.mEvent.getTextToCommit(); + final CharSequence textToCommit = event.getTextToCommit(); if (!TextUtils.isEmpty(textToCommit)) { mConnection.commitText(textToCommit, 1); inputTransaction.setDidAffectContents(); @@ -611,15 +617,15 @@ public final class InputLogic { * manage keyboard-related stuff like shift, language switch, settings, layout switch, or * any key that results in multiple code points like the ".com" key. * + * @param event The event to handle. * @param inputTransaction The transaction in progress. */ - private void handleFunctionalEvent(final InputTransaction inputTransaction, + private void handleFunctionalEvent(final Event event, final InputTransaction inputTransaction, // TODO: remove these arguments final int currentKeyboardScriptId, final LatinIME.UIHandler handler) { - final Event event = inputTransaction.mEvent; switch (event.mKeyCode) { case Constants.CODE_DELETE: - handleBackspace(inputTransaction, currentKeyboardScriptId); + handleBackspaceEvent(event, inputTransaction, currentKeyboardScriptId); // Backspace is a functional key, but it affects the contents of the editor. inputTransaction.setDidAffectContents(); break; @@ -670,11 +676,7 @@ public final class InputLogic { // TODO: remove this object final Event tmpEvent = Event.createSoftwareKeypressEvent(Constants.CODE_ENTER, event.mKeyCode, event.mX, event.mY, event.isKeyRepeat()); - final InputTransaction tmpTransaction = new InputTransaction( - inputTransaction.mSettingsValues, tmpEvent, - inputTransaction.mTimestamp, inputTransaction.mSpaceState, - inputTransaction.mShiftState); - handleNonSpecialCharacter(tmpTransaction, handler); + handleNonSpecialCharacterEvent(tmpEvent, inputTransaction, 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(); @@ -690,12 +692,13 @@ public final class InputLogic { * These events are generally events that cause input, but in some cases they may do other * things like trigger an editor action. * + * @param event The event to handle. * @param inputTransaction The transaction in progress. */ - private void handleNonFunctionalEvent(final InputTransaction inputTransaction, + private void handleNonFunctionalEvent(final Event event, + final InputTransaction inputTransaction, // TODO: remove this argument final LatinIME.UIHandler handler) { - final Event event = inputTransaction.mEvent; inputTransaction.setDidAffectContents(); switch (event.mCodePoint) { case Constants.CODE_ENTER: @@ -718,11 +721,11 @@ public final class InputLogic { } else { // No action label, and the action from imeOptions is NONE: this is a regular // enter key that should input a carriage return. - handleNonSpecialCharacter(inputTransaction, handler); + handleNonSpecialCharacterEvent(event, inputTransaction, handler); } break; default: - handleNonSpecialCharacter(inputTransaction, handler); + handleNonSpecialCharacterEvent(event, inputTransaction, handler); break; } } @@ -735,16 +738,18 @@ public final class InputLogic { * manage keyboard-related stuff like shift, language switch, settings, layout switch, or * any key that results in multiple code points like the ".com" key. * + * @param event The event to handle. * @param inputTransaction The transaction in progress. */ - private void handleNonSpecialCharacter(final InputTransaction inputTransaction, + private void handleNonSpecialCharacterEvent(final Event event, + final InputTransaction inputTransaction, // TODO: remove this argument final LatinIME.UIHandler handler) { - final int codePoint = inputTransaction.mEvent.mCodePoint; + final int codePoint = event.mCodePoint; mSpaceState = SpaceState.NONE; if (inputTransaction.mSettingsValues.isWordSeparator(codePoint) || Character.getType(codePoint) == Character.OTHER_SYMBOL) { - handleSeparator(inputTransaction, handler); + handleSeparatorEvent(event, inputTransaction, handler); } else { if (SpaceState.PHANTOM == inputTransaction.mSpaceState) { if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) { @@ -756,21 +761,23 @@ public final class InputLogic { commitTyped(inputTransaction.mSettingsValues, LastComposedWord.NOT_A_SEPARATOR); } } - handleNonSeparator(inputTransaction.mSettingsValues, inputTransaction); + handleNonSeparatorEvent(event, inputTransaction.mSettingsValues, inputTransaction); } } /** * Handle a non-separator. + * @param event The event to handle. * @param settingsValues The current settings values. * @param inputTransaction The transaction in progress. */ - private void handleNonSeparator(final SettingsValues settingsValues, + private void handleNonSeparatorEvent(final Event event, final SettingsValues settingsValues, final InputTransaction inputTransaction) { - final int codePoint = inputTransaction.mEvent.mCodePoint; + final int codePoint = event.mCodePoint; // TODO: refactor this method to stop flipping isComposingWord around all the time, and - // 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. + // make it shorter (possibly cut into several pieces). Also factor + // handleNonSpecialCharacterEvent which has the same name as other handle* methods but is + // not the same. boolean isComposingWord = mWordComposer.isComposingWord(); // TODO: remove isWordConnector() and use isUsuallyFollowedBySpace() instead. @@ -817,7 +824,7 @@ public final class InputLogic { resetComposingState(false /* alsoResetLastComposedWord */); } if (isComposingWord) { - mWordComposer.applyProcessedEvent(inputTransaction.mEvent); + mWordComposer.applyProcessedEvent(event); // If it's the first letter, make note of auto-caps state if (mWordComposer.isSingleLetter()) { mWordComposer.setCapitalizedModeAtStartComposingTime(inputTransaction.mShiftState); @@ -825,10 +832,10 @@ public final class InputLogic { mConnection.setComposingText(getTextWithUnderline( mWordComposer.getTypedWord()), 1); } else { - final boolean swapWeakSpace = tryStripSpaceAndReturnWhetherShouldSwapInstead( + final boolean swapWeakSpace = tryStripSpaceAndReturnWhetherShouldSwapInstead(event, inputTransaction); - if (swapWeakSpace && trySwapSwapperAndSpace(inputTransaction)) { + if (swapWeakSpace && trySwapSwapperAndSpace(event, inputTransaction)) { mSpaceState = SpaceState.WEAK; } else { sendKeyCodePoint(settingsValues, codePoint); @@ -841,12 +848,13 @@ public final class InputLogic { /** * Handle input of a separator code point. + * @param event The event to handle. * @param inputTransaction The transaction in progress. */ - private void handleSeparator(final InputTransaction inputTransaction, + private void handleSeparatorEvent(final Event event, final InputTransaction inputTransaction, // TODO: remove this argument final LatinIME.UIHandler handler) { - final int codePoint = inputTransaction.mEvent.mCodePoint; + final int codePoint = event.mCodePoint; final SettingsValues settingsValues = inputTransaction.mSettingsValues; final boolean wasComposingWord = mWordComposer.isComposingWord(); // We avoid sending spaces in languages without spaces if we were composing. @@ -872,7 +880,7 @@ public final class InputLogic { } } - final boolean swapWeakSpace = tryStripSpaceAndReturnWhetherShouldSwapInstead( + final boolean swapWeakSpace = tryStripSpaceAndReturnWhetherShouldSwapInstead(event, inputTransaction); final boolean isInsideDoubleQuoteOrAfterDigit = Constants.CODE_DOUBLE_QUOTE == codePoint @@ -897,10 +905,10 @@ public final class InputLogic { promotePhantomSpace(settingsValues); } - if (tryPerformDoubleSpacePeriod(inputTransaction)) { + if (tryPerformDoubleSpacePeriod(event, inputTransaction)) { mSpaceState = SpaceState.DOUBLE; inputTransaction.setRequiresUpdateSuggestions(); - } else if (swapWeakSpace && trySwapSwapperAndSpace(inputTransaction)) { + } else if (swapWeakSpace && trySwapSwapperAndSpace(event, inputTransaction)) { mSpaceState = SpaceState.SWAP_PUNCTUATION; mSuggestionStripViewAccessor.setNeutralSuggestionStrip(); } else if (Constants.CODE_SPACE == codePoint) { @@ -947,12 +955,12 @@ public final class InputLogic { /** * Handle a press on the backspace key. + * @param event The event to handle. * @param inputTransaction The transaction in progress. */ - private void handleBackspace(final InputTransaction inputTransaction, + private void handleBackspaceEvent(final Event event, final InputTransaction inputTransaction, // TODO: remove this argument, put it into settingsValues final int currentKeyboardScriptId) { - final Event event = inputTransaction.mEvent; mSpaceState = SpaceState.NONE; mDeleteCount++; @@ -1103,16 +1111,18 @@ public final class InputLogic { * * This method will check that there are two characters before the cursor and that the first * one is a space before it does the actual swapping. + * @param event The event to handle. * @param inputTransaction The transaction in progress. * @return true if the swap has been performed, false if it was prevented by preliminary checks. */ - private boolean trySwapSwapperAndSpace(final InputTransaction inputTransaction) { + private boolean trySwapSwapperAndSpace(final Event event, + final InputTransaction inputTransaction) { final int codePointBeforeCursor = mConnection.getCodePointBeforeCursor(); if (Constants.CODE_SPACE != codePointBeforeCursor) { return false; } mConnection.deleteSurroundingText(1, 0); - final String text = inputTransaction.mEvent.getTextToCommit() + " "; + final String text = event.getTextToCommit() + " "; mConnection.commitText(text, 1); inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW); return true; @@ -1120,13 +1130,14 @@ public final class InputLogic { /* * Strip a trailing space if necessary and returns whether it's a swap weak space situation. + * @param event The event to handle. * @param inputTransaction The transaction in progress. * @return whether we should swap the space instead of removing it. */ - private boolean tryStripSpaceAndReturnWhetherShouldSwapInstead( + private boolean tryStripSpaceAndReturnWhetherShouldSwapInstead(final Event event, final InputTransaction inputTransaction) { - final int codePoint = inputTransaction.mEvent.mCodePoint; - final boolean isFromSuggestionStrip = inputTransaction.mEvent.isSuggestionStripPress(); + final int codePoint = event.mCodePoint; + final boolean isFromSuggestionStrip = event.isSuggestionStripPress(); if (Constants.CODE_ENTER == codePoint && SpaceState.SWAP_PUNCTUATION == inputTransaction.mSpaceState) { mConnection.removeTrailingSpace(); @@ -1171,14 +1182,16 @@ public final class InputLogic { * these conditions are fulfilled, this method applies the transformation and returns true. * Otherwise, it does nothing and returns false. * + * @param event The event to handle. * @param inputTransaction The transaction in progress. * @return true if we applied the double-space-to-period transformation, false otherwise. */ - private boolean tryPerformDoubleSpacePeriod(final InputTransaction inputTransaction) { + private boolean tryPerformDoubleSpacePeriod(final Event event, + final InputTransaction inputTransaction) { // Check the setting, the typed character and the countdown. If any of the conditions is // not fulfilled, return false. if (!inputTransaction.mSettingsValues.mUseDoubleSpacePeriod - || Constants.CODE_SPACE != inputTransaction.mEvent.mCodePoint + || Constants.CODE_SPACE != event.mCodePoint || !isDoubleSpacePeriodCountdownActive(inputTransaction)) { return false; } @@ -1424,6 +1437,7 @@ public final class InputLogic { mLatinIME.getCoordinatesForCurrentKeyboard(codePoints)); mWordComposer.setCursorPositionWithinWord( typedWord.codePointCount(0, numberOfCharsInWordBeforeCursor)); + mConnection.maybeMoveTheCursorAroundAndRestoreToWorkaroundABug(); mConnection.setComposingRegion(expectedCursorPosition - numberOfCharsInWordBeforeCursor, expectedCursorPosition + range.getNumberOfCharsInWordAfterCursor()); if (suggestions.size() <= (shouldIncludeResumedWordInSuggestions ? 1 : 0)) { @@ -2021,7 +2035,7 @@ public final class InputLogic { mConnection.getExpectedSelectionStart(), mConnection.getExpectedSelectionEnd(), shouldFinishComposition)) { if (0 < remainingTries) { - handler.postResetCaches(tryResumeSuggestions, remainingTries - 1); + handler.postResetInputConnectionCaches(tryResumeSuggestions, remainingTries - 1); return false; } // If remainingTries is 0, we should stop waiting for new tries, however we'll still diff --git a/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java index 21f2afd01..6d7f53cf0 100644 --- a/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java +++ b/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java @@ -63,7 +63,6 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment { private AlertDialog mSubtypeEnablerNotificationDialog; private String mSubtypePreferenceKeyForSubtypeEnabler; - private static final int MENU_ADD_SUBTYPE = Menu.FIRST; private static final String KEY_IS_ADDING_NEW_SUBTYPE = "is_adding_new_subtype"; private static final String KEY_IS_SUBTYPE_ENABLER_NOTIFICATION_DIALOG_OPEN = "is_subtype_enabler_notification_dialog_open"; @@ -581,14 +580,13 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment { @Override public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) { - final MenuItem addSubtypeMenu = menu.add(0, MENU_ADD_SUBTYPE, 0, R.string.add_style); - addSubtypeMenu.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); + inflater.inflate(R.menu.add_style, menu); } @Override public boolean onOptionsItemSelected(final MenuItem item) { final int itemId = item.getItemId(); - if (itemId == MENU_ADD_SUBTYPE) { + if (itemId == R.id.action_add_style) { final SubtypePreference newSubtype = SubtypePreference.newIncompleteSubtypePreference(getActivity(), mSubtypeProxy); getPreferenceScreen().addPreference(newSubtype); |