diff --git a/java/res/xml-sw600dp/key_styles_common.xml b/java/res/xml-sw600dp/key_styles_common.xml index 6b06ce77a..a2d2fd827 100644 --- a/java/res/xml-sw600dp/key_styles_common.xml +++ b/java/res/xml-sw600dp/key_styles_common.xml @@ -36,34 +36,38 @@ + + + latin:backgroundType="stickyOff" + latin:parentStyle="baseForShiftKeyStyle" /> + latin:backgroundType="stickyOn" + latin:parentStyle="baseForShiftKeyStyle" /> + latin:backgroundType="stickyOff" + latin:parentStyle="baseForShiftKeyStyle" /> + + + latin:backgroundType="stickyOff" + latin:parentStyle="baseForShiftKeyStyle" /> + latin:backgroundType="stickyOn" + latin:parentStyle="baseForShiftKeyStyle" /> + latin:backgroundType="stickyOff" + latin:parentStyle="baseForShiftKeyStyle" /> + + + latin:backgroundType="stickyOff" + latin:parentStyle="baseForShiftKeyStyle" /> + latin:backgroundType="stickyOn" + latin:parentStyle="baseForShiftKeyStyle" /> + latin:backgroundType="stickyOff" + latin:parentStyle="baseForShiftKeyStyle" /> diff --git a/java/res/xml/rows_phone.xml b/java/res/xml/rows_phone.xml index 9299c2aa5..d8dcfbd62 100644 --- a/java/res/xml/rows_phone.xml +++ b/java/res/xml/rows_phone.xml @@ -70,7 +70,7 @@ latin:keyStyle="num0KeyStyle" latin:code="0x0030" latin:keyLabel="0 +" - latin:moreKeys="!embeddedMoreKey!,+" /> + latin:moreKeys="!noPanelAutoMoreKey!,+" /> { private static final int MORE_KEYS_FLAGS_FIXED_COLUMN_ORDER = 0x80000000; private static final int MORE_KEYS_FLAGS_HAS_LABELS = 0x40000000; private static final int MORE_KEYS_FLAGS_NEEDS_DIVIDERS = 0x20000000; - private static final int MORE_KEYS_FLAGS_EMBEDDED_MORE_KEY = 0x10000000; + private static final int MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY = 0x10000000; private static final String MORE_KEYS_AUTO_COLUMN_ORDER = "!autoColumnOrder!"; private static final String MORE_KEYS_FIXED_COLUMN_ORDER = "!fixedColumnOrder!"; private static final String MORE_KEYS_HAS_LABELS = "!hasLabels!"; private static final String MORE_KEYS_NEEDS_DIVIDERS = "!needsDividers!"; - private static final String MORE_KEYS_EMBEDDED_MORE_KEY = "!embeddedMoreKey!"; + private static final String MORE_KEYS_NO_PANEL_AUTO_MORE_KEY = "!noPanelAutoMoreKey!"; /** Background type that represents different key background visual than normal one. */ public final int mBackgroundType; @@ -281,8 +281,8 @@ public class Key implements Comparable { if (KeySpecParser.getBooleanValue(moreKeys, MORE_KEYS_NEEDS_DIVIDERS)) { moreKeysColumn |= MORE_KEYS_FLAGS_NEEDS_DIVIDERS; } - if (KeySpecParser.getBooleanValue(moreKeys, MORE_KEYS_EMBEDDED_MORE_KEY)) { - moreKeysColumn |= MORE_KEYS_FLAGS_EMBEDDED_MORE_KEY; + if (KeySpecParser.getBooleanValue(moreKeys, MORE_KEYS_NO_PANEL_AUTO_MORE_KEY)) { + moreKeysColumn |= MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY; } mMoreKeysColumnAndFlags = moreKeysColumn; @@ -657,8 +657,8 @@ public class Key implements Comparable { return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_NEEDS_DIVIDERS) != 0; } - public final boolean hasEmbeddedMoreKey() { - return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_EMBEDDED_MORE_KEY) != 0; + public final boolean hasNoPanelAutoMoreKey() { + return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY) != 0; } public final String getOutputText() { diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 7295efab1..4323f7171 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -32,7 +32,6 @@ import com.android.inputmethod.keyboard.KeyboardLayoutSet.KeyboardLayoutSetExcep import com.android.inputmethod.keyboard.PointerTracker.TimerProxy; import com.android.inputmethod.keyboard.internal.KeyboardState; import com.android.inputmethod.latin.AudioAndHapticFeedbackManager; -import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.InputView; import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinImeLogger; @@ -300,26 +299,6 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { ? keyboardView.getTimerProxy().isInDoubleTapShiftKeyTimeout() : false; } - // Implements {@link KeyboardState.SwitchActions}. - @Override - public void startLongPressTimer(final int code) { - final MainKeyboardView keyboardView = getMainKeyboardView(); - if (keyboardView != null) { - final TimerProxy timer = keyboardView.getTimerProxy(); - timer.startLongPressTimer(code); - } - } - - // Implements {@link KeyboardState.SwitchActions}. - @Override - public void cancelLongPressTimer() { - final MainKeyboardView keyboardView = getMainKeyboardView(); - if (keyboardView != null) { - final TimerProxy timer = keyboardView.getTimerProxy(); - timer.cancelLongPressTimer(); - } - } - private void hapticAndAudioFeedback(final int code) { if (mKeyboardView == null || mKeyboardView.isInSlidingKeyInput()) { return; @@ -327,14 +306,6 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { AudioAndHapticFeedbackManager.getInstance().hapticAndAudioFeedback(code, mKeyboardView); } - public void onLongPressTimeout(final int code) { - mState.onLongPressTimeout(code); - final Keyboard keyboard = getKeyboard(); - if (keyboard != null && keyboard.mId.isAlphabetKeyboard() && code == Constants.CODE_SHIFT) { - hapticAndAudioFeedback(code); - } - } - /** * Updates state machine to figure out when to automatically switch back to the previous mode. */ diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java index 435adb6f5..2e8772635 100644 --- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java @@ -248,11 +248,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack } break; case MSG_LONGPRESS_KEY: - if (tracker != null) { - keyboardView.onLongPress(tracker); - } else { - KeyboardSwitcher.getInstance().onLongPressTimeout(msg.arg1); - } + keyboardView.onLongPress(tracker); break; case MSG_UPDATE_BATCH_INPUT: tracker.updateBatchInputByTimer(SystemClock.uptimeMillis()); @@ -283,23 +279,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack return hasMessages(MSG_REPEAT_KEY); } - @Override - public void startLongPressTimer(final int code) { - cancelLongPressTimer(); - final int delay; - switch (code) { - case Constants.CODE_SHIFT: - delay = mLongPressShiftLockTimeout; - break; - default: - delay = 0; - break; - } - if (delay > 0) { - sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, code, 0), delay); - } - } - @Override public void startLongPressTimer(final PointerTracker tracker) { cancelLongPressTimer(); @@ -1002,7 +981,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack ResearchLogger.mainKeyboardView_onLongPress(); } final int code = key.mCode; - if (key.hasEmbeddedMoreKey()) { + if (key.hasNoPanelAutoMoreKey()) { final int embeddedCode = key.mMoreKeys[0].mCode; tracker.onLongPressed(); invokeCodeInput(embeddedCode); diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index a28bd1a1e..958aaf569 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -92,7 +92,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element { public boolean isTypingState(); public void startKeyRepeatTimer(PointerTracker tracker); public void startLongPressTimer(PointerTracker tracker); - public void startLongPressTimer(int code); public void cancelLongPressTimer(); public void startDoubleTapShiftKeyTimer(); public void cancelDoubleTapShiftKeyTimer(); @@ -112,8 +111,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element { @Override public void startLongPressTimer(PointerTracker tracker) {} @Override - public void startLongPressTimer(int code) {} - @Override public void cancelLongPressTimer() {} @Override public void startDoubleTapShiftKeyTimer() {} diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java index 3e25c3b86..a9e04bccf 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java @@ -43,6 +43,7 @@ public final class KeyboardCodesSet { "key_enter", "key_space", "key_shift", + "key_capslock", "key_switch_alpha_symbol", "key_output_text", "key_delete", @@ -79,6 +80,7 @@ public final class KeyboardCodesSet { Constants.CODE_ENTER, Constants.CODE_SPACE, Constants.CODE_SHIFT, + Constants.CODE_CAPSLOCK, Constants.CODE_SWITCH_ALPHA_SYMBOL, Constants.CODE_OUTPUT_TEXT, Constants.CODE_DELETE, @@ -116,6 +118,7 @@ public final class KeyboardCodesSet { DEFAULT[12], DEFAULT[13], DEFAULT[14], + DEFAULT[15], CODE_RIGHT_PARENTHESIS, CODE_LEFT_PARENTHESIS, CODE_GREATER_THAN_SIGN, diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java index bb6dec69e..e1cee427e 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java @@ -30,7 +30,7 @@ import com.android.inputmethod.latin.RecapitalizeStatus; * The input events are {@link #onLoadKeyboard()}, {@link #onSaveKeyboardState()}, * {@link #onPressKey(int,boolean,int)}, {@link #onReleaseKey(int,boolean)}, * {@link #onCodeInput(int,int)}, {@link #onFinishSlidingInput()}, {@link #onCancelInput()}, - * {@link #onUpdateShiftState(int,int)}, {@link #onLongPressTimeout(int)}. + * {@link #onUpdateShiftState(int,int)}. * * The actions are {@link SwitchActions}'s methods. */ @@ -56,8 +56,6 @@ public final class KeyboardState { public void startDoubleTapShiftKeyTimer(); public boolean isInDoubleTapShiftKeyTimeout(); public void cancelDoubleTapShiftKeyTimer(); - public void startLongPressTimer(int code); - public void cancelLongPressTimer(); } private final SwitchActions mSwitchActions; @@ -320,13 +318,16 @@ public final class KeyboardState { Log.d(TAG, "onPressKey: code=" + Constants.printableCode(code) + " single=" + isSinglePointer + " autoCaps=" + autoCaps + " " + this); } + if (code != Constants.CODE_SHIFT) { + // Because the double tap shift key timer is to detect two consecutive shift key press, + // it should be canceled when a non-shift key is pressed. + mSwitchActions.cancelDoubleTapShiftKeyTimer(); + } if (code == Constants.CODE_SHIFT) { onPressShift(); } else if (code == Constants.CODE_SWITCH_ALPHA_SYMBOL) { onPressSymbol(); } else { - mSwitchActions.cancelDoubleTapShiftKeyTimer(); - mSwitchActions.cancelLongPressTimer(); mLongPressShiftLockFired = false; mShiftKeyState.onOtherKeyPressed(); mSymbolKeyState.onOtherKeyPressed(); @@ -380,15 +381,6 @@ public final class KeyboardState { mSymbolKeyState.onRelease(); } - public void onLongPressTimeout(final int code) { - if (DEBUG_EVENT) { - Log.d(TAG, "onLongPressTimeout: code=" + Constants.printableCode(code) + " " + this); - } - if (mIsAlphabetMode && code == Constants.CODE_SHIFT) { - mLongPressShiftLockFired = true; - } - } - public void onUpdateShiftState(final int autoCaps, final int recapitalizeMode) { if (DEBUG_EVENT) { Log.d(TAG, "onUpdateShiftState: autoCaps=" + autoCaps + ", recapitalizeMode=" @@ -448,7 +440,9 @@ public final class KeyboardState { mLongPressShiftLockFired = false; // If we are recapitalizing, we don't do any of the normal processing, including // importantly the double tap timer. - if (RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE != mRecapitalizeMode) return; + if (RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE != mRecapitalizeMode) { + return; + } if (mIsAlphabetMode) { mIsInDoubleTapShiftKey = mSwitchActions.isInDoubleTapShiftKeyTimeout(); if (!mIsInDoubleTapShiftKey) { @@ -484,7 +478,6 @@ public final class KeyboardState { setShifted(MANUAL_SHIFT); mShiftKeyState.onPress(); } - mSwitchActions.startLongPressTimer(Constants.CODE_SHIFT); } } else { // In symbol mode, just toggle symbol and symbol more keyboard. @@ -617,6 +610,12 @@ public final class KeyboardState { break; } + if (code == Constants.CODE_CAPSLOCK) { + // Changing shift lock state will be handled at {@link #onPressShift()} when the shift + // key is released. + mLongPressShiftLockFired = true; + } + // If the code is a letter, update keyboard shift state. if (Constants.isLetterCode(code)) { updateAlphabetShiftState(autoCaps, RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE); diff --git a/java/src/com/android/inputmethod/latin/Constants.java b/java/src/com/android/inputmethod/latin/Constants.java index 64c14d32f..bb4a42ede 100644 --- a/java/src/com/android/inputmethod/latin/Constants.java +++ b/java/src/com/android/inputmethod/latin/Constants.java @@ -172,22 +172,23 @@ public final class Constants { /** * Special keys code. Must be negative. - * These should be aligned with KeyboardCodesSet.ID_TO_NAME[], - * KeyboardCodesSet.DEFAULT[] and KeyboardCodesSet.RTL[] + * These should be aligned with {@link KeyboardCodesSet#ID_TO_NAME}, + * {@link KeyboardCodesSet#DEFAULT}, and {@link KeyboardCodesSet#RTL}. */ public static final int CODE_SHIFT = -1; - public static final int CODE_SWITCH_ALPHA_SYMBOL = -2; - public static final int CODE_OUTPUT_TEXT = -3; - public static final int CODE_DELETE = -4; - public static final int CODE_SETTINGS = -5; - public static final int CODE_SHORTCUT = -6; - public static final int CODE_ACTION_NEXT = -7; - public static final int CODE_ACTION_PREVIOUS = -8; - public static final int CODE_LANGUAGE_SWITCH = -9; - public static final int CODE_RESEARCH = -10; - public static final int CODE_SHIFT_ENTER = -11; + public static final int CODE_CAPSLOCK = -2; + public static final int CODE_SWITCH_ALPHA_SYMBOL = -3; + public static final int CODE_OUTPUT_TEXT = -4; + 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_ACTION_NEXT = -8; + public static final int CODE_ACTION_PREVIOUS = -9; + public static final int CODE_LANGUAGE_SWITCH = -10; + public static final int CODE_RESEARCH = -11; + public static final int CODE_SHIFT_ENTER = -12; // Code value representing the code is not specified. - public static final int CODE_UNSPECIFIED = -12; + public static final int CODE_UNSPECIFIED = -13; public static boolean isLetterCode(final int code) { return code >= CODE_SPACE; @@ -196,6 +197,7 @@ public final class Constants { public static String printableCode(final int code) { switch (code) { case CODE_SHIFT: return "shift"; + case CODE_CAPSLOCK: return "capslock"; case CODE_SWITCH_ALPHA_SYMBOL: return "symbol"; case CODE_OUTPUT_TEXT: return "text"; case CODE_DELETE: return "delete"; diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 98008ac1c..0bf167fd4 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -1420,8 +1420,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen LatinImeLogger.logOnDelete(x, y); break; case Constants.CODE_SHIFT: - // Note: calling back to the keyboard on Shift key is handled in onPressKey() - // and onReleaseKey(). + // Note: Calling back to the keyboard on Shift key is handled in + // {@link #onPressKey(int,boolean)} and {@link #onReleaseKey(int,boolean)}. final Keyboard currentKeyboard = switcher.getKeyboard(); if (null != currentKeyboard && currentKeyboard.mId.isAlphabetKeyboard()) { // TODO: Instead of checking for alphabetic keyboard here, separate keycodes for @@ -1429,9 +1429,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen handleRecapitalize(); } break; + case Constants.CODE_CAPSLOCK: + // Note: Changing keyboard to shift lock state is handled in + // {@link KeyboardSwitcher#onCodeInput(int)}. + break; case Constants.CODE_SWITCH_ALPHA_SYMBOL: - // Note: calling back to the keyboard on symbol key is handled in onPressKey() - // and onReleaseKey(). + // Note: Calling back to the keyboard on symbol key is handled in + // {@link #onPressKey(int,boolean)} and {@link #onReleaseKey(int,boolean)}. break; case Constants.CODE_SETTINGS: onSettingsKeyPressed(); @@ -1484,8 +1488,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen break; } switcher.onCodeInput(primaryCode); - // Reset after any single keystroke, except shift and symbol-shift + // Reset after any single keystroke, except shift, capslock, and symbol-shift if (!didAutoCorrect && primaryCode != Constants.CODE_SHIFT + && primaryCode != Constants.CODE_CAPSLOCK && primaryCode != Constants.CODE_SWITCH_ALPHA_SYMBOL) mLastComposedWord.deactivate(); if (Constants.CODE_DELETE != primaryCode) { diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTestsBase.java b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTestsBase.java index e06ca064a..6991d05fa 100644 --- a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTestsBase.java +++ b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTestsBase.java @@ -18,6 +18,8 @@ package com.android.inputmethod.keyboard.internal; import android.test.AndroidTestCase; +import com.android.inputmethod.latin.Constants; + public class KeyboardStateTestsBase extends AndroidTestCase implements MockKeyboardSwitcher.MockConstants { protected MockKeyboardSwitcher mSwitcher; @@ -119,7 +121,11 @@ public class KeyboardStateTestsBase extends AndroidTestCase public void longPressKey(final int code, final int afterPress, final int afterLongPress) { pressKey(code, afterPress); - mSwitcher.onLongPressTimeout(code); + // Long press shift key will register {@link Constants#CODE_CAPS_LOCK}. See + // {@link R.xml#key_styles_common} and its baseForShiftKeyStyle. We thus emulate the + // behavior here. + final int longPressCode = code == CODE_SHIFT ? Constants.CODE_CAPSLOCK : code; + mSwitcher.onCodeInput(longPressCode); assertLayout("afterLongPress", afterLongPress, mSwitcher.getLayoutId()); } diff --git a/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java b/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java index 90dbaabc9..8506e16f2 100644 --- a/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java +++ b/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java @@ -139,24 +139,6 @@ public class MockKeyboardSwitcher implements KeyboardState.SwitchActions { return mIsInDoubleTapShiftKeyTimeout; } - @Override - public void startLongPressTimer(final int code) { - mLongPressTimeoutCode = code; - } - - @Override - public void cancelLongPressTimer() { - mLongPressTimeoutCode = 0; - } - - public void onLongPressTimeout(final int code) { - // TODO: Handle simultaneous long presses. - if (mLongPressTimeoutCode == code) { - mLongPressTimeoutCode = 0; - mState.onLongPressTimeout(code); - } - } - public void updateShiftState() { mState.onUpdateShiftState(mAutoCapsState, RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE); }