aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/keyboard/Keyboard.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardId.java52
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSet.java76
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java93
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java152
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/ModifierKeyState.java12
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/ShiftKeyState.java2
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java40
8 files changed, 243 insertions, 186 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 5816e5680..c548f1145 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -680,7 +680,7 @@ public class Keyboard {
a.recycle();
if (resourceId == 0) {
if (LatinImeLogger.sDBG)
- throw new RuntimeException("touchPositionCorrectionData is not defined");
+ Log.e(TAG, "touchPositionCorrectionData is not defined");
return;
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index d95c3b3af..edce4c6e8 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -39,16 +39,14 @@ public class KeyboardId {
public static final int MODE_NUMBER = 5;
public static final int ELEMENT_ALPHABET = 0;
- /* TODO: Implement alphabet variant shift keyboard.
- public static final int ELEMENT_ALPHABET_MANUAL_TEMPORARY_SHIFT = 1;
- public static final int ELEMENT_ALPHABET_AUTOMATIC_TEMPORARY_SHIFT = 2;
- public static final int ELEMENT_ALPHABET_SHIFT_LOCK = 3;
- public static final int ELEMENT_ALPHABET_SHIFT_LOCK_SHIFT = 4;
- */
+ public static final int ELEMENT_ALPHABET_MANUAL_SHIFTED = 1;
+ public static final int ELEMENT_ALPHABET_AUTOMATIC_SHIFTED = 2;
+ public static final int ELEMENT_ALPHABET_SHIFT_LOCKED = 3;
+ public static final int ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED = 4;
public static final int ELEMENT_SYMBOLS = 5;
- public static final int ELEMENT_SYMBOLS_SHIFT = 6;
+ public static final int ELEMENT_SYMBOLS_SHIFTED = 6;
public static final int ELEMENT_PHONE = 7;
- public static final int ELEMENT_PHONE_SHIFT = 8;
+ public static final int ELEMENT_PHONE_SHIFTED = 8;
public static final int ELEMENT_NUMBER = 9;
private static final int F2KEY_MODE_NONE = 0;
@@ -60,7 +58,7 @@ public class KeyboardId {
public final int mOrientation;
public final int mWidth;
public final int mMode;
- public final int mElementState;
+ public final int mElement;
private final int mInputType;
private final int mImeOptions;
private final boolean mSettingsKeyEnabled;
@@ -70,14 +68,14 @@ public class KeyboardId {
private final int mHashCode;
- public KeyboardId(int elementState, Locale locale, int orientation, int width, int mode,
+ public KeyboardId(int element, Locale locale, int orientation, int width, int mode,
int inputType, int imeOptions, boolean settingsKeyEnabled, boolean clobberSettingsKey,
boolean shortcutKeyEnabled, boolean hasShortcutKey) {
this.mLocale = locale;
this.mOrientation = orientation;
this.mWidth = width;
this.mMode = mode;
- this.mElementState = elementState;
+ this.mElement = element;
this.mInputType = inputType;
this.mImeOptions = imeOptions;
this.mSettingsKeyEnabled = settingsKeyEnabled;
@@ -91,7 +89,7 @@ public class KeyboardId {
private static int hashCode(KeyboardId id) {
return Arrays.hashCode(new Object[] {
id.mOrientation,
- id.mElementState,
+ id.mElement,
id.mMode,
id.mWidth,
id.navigateAction(),
@@ -109,7 +107,7 @@ public class KeyboardId {
if (other == this)
return true;
return other.mOrientation == this.mOrientation
- && other.mElementState == this.mElementState
+ && other.mElement == this.mElement
&& other.mMode == this.mMode
&& other.mWidth == this.mWidth
&& other.navigateAction() == this.navigateAction()
@@ -123,19 +121,19 @@ public class KeyboardId {
}
public boolean isAlphabetKeyboard() {
- return mElementState < ELEMENT_SYMBOLS;
+ return mElement < ELEMENT_SYMBOLS;
}
public boolean isSymbolsKeyboard() {
- return mElementState == ELEMENT_SYMBOLS || mElementState == ELEMENT_SYMBOLS_SHIFT;
+ return mElement == ELEMENT_SYMBOLS || mElement == ELEMENT_SYMBOLS_SHIFTED;
}
public boolean isPhoneKeyboard() {
- return mElementState == ELEMENT_PHONE || mElementState == ELEMENT_PHONE_SHIFT;
+ return mElement == ELEMENT_PHONE || mElement == ELEMENT_PHONE_SHIFTED;
}
public boolean isPhoneShiftKeyboard() {
- return mElementState == ELEMENT_PHONE_SHIFT;
+ return mElement == ELEMENT_PHONE_SHIFTED;
}
public boolean navigateAction() {
@@ -190,7 +188,7 @@ public class KeyboardId {
@Override
public String toString() {
return String.format("[%s %s %s%d %s %s %s%s%s%s%s%s%s]",
- elementStateToString(mElementState),
+ elementToString(mElement),
mLocale,
(mOrientation == 1 ? "port" : "land"), mWidth,
modeName(mMode),
@@ -213,19 +211,17 @@ public class KeyboardId {
&& TextUtils.equals(a.privateImeOptions, b.privateImeOptions);
}
- public static String elementStateToString(int elementState) {
- switch (elementState) {
+ public static String elementToString(int element) {
+ switch (element) {
case ELEMENT_ALPHABET: return "alphabet";
- /* TODO: Implement alphabet variant shift keyboard.
- case ELEMENT_ALPHABET_MANUAL_TEMPORARY_SHIFT: return "alphabetManualTemporaryShift";
- case ELEMENT_ALPHABET_AUTOMATIC_TEMPORARY_SHIFT: return "alphabetAutomaticTemporaryShift";
- case ELEMENT_ALPHABET_SHIFT_LOCK: return "alphabetShiftLock";
- case ELEMENT_ALPHABET_SHIFT_LOCK_SHIFT: return "alphabetShiftLockShift";
- */
+ case ELEMENT_ALPHABET_MANUAL_SHIFTED: return "alphabetManualShifted";
+ case ELEMENT_ALPHABET_AUTOMATIC_SHIFTED: return "alphabetAutomaticShifted";
+ case ELEMENT_ALPHABET_SHIFT_LOCKED: return "alphabetShiftLocked";
+ case ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED: return "alphabetShiftLockShifted";
case ELEMENT_SYMBOLS: return "symbols";
- case ELEMENT_SYMBOLS_SHIFT: return "symbolsShift";
+ case ELEMENT_SYMBOLS_SHIFTED: return "symbolsShifted";
case ELEMENT_PHONE: return "phone";
- case ELEMENT_PHONE_SHIFT: return "phoneShift";
+ case ELEMENT_PHONE_SHIFTED: return "phoneShifted";
case ELEMENT_NUMBER: return "number";
default: return null;
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
index 285252044..f4602b8fd 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
@@ -22,6 +22,7 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.util.Log;
+import android.util.TypedValue;
import android.util.Xml;
import android.view.inputmethod.EditorInfo;
@@ -54,10 +55,12 @@ public class KeyboardSet {
private static final String TAG_KEYBOARD_SET = TAG;
private static final String TAG_ELEMENT = "Element";
+ private static final int ELEMENT_KEYBOARD_AUTO_GENERATE_FROM_ALPHABET = 1;
+
private final Context mContext;
private final Params mParams;
- private static class Params {
+ static class Params {
int mMode;
int mInputType;
int mImeOptions;
@@ -104,16 +107,18 @@ public class KeyboardSet {
}
private Keyboard getKeyboard(boolean isSymbols, boolean isShift) {
- final int elementState = Builder.getElementState(mParams.mMode, isSymbols, isShift);
- final int xmlId = mParams.mElementKeyboards.get(elementState);
- final KeyboardId id = Builder.getKeyboardId(elementState, isSymbols, mParams);
+ final int element = KeyboardSet.getElement(mParams.mMode, isSymbols, isShift);
+ // TODO: If xmlId is ELEMENT_KEYBOARD_AUTO_GENERATE_FROM_ALPHABET, auto generate the
+ // keyboard based on base main alphabet keyboard considering element.
+ final int xmlId = mParams.mElementKeyboards.get(element);
+ final KeyboardId id = KeyboardSet.getKeyboardId(element, isSymbols, mParams);
final Keyboard keyboard = getKeyboard(mContext, xmlId, id);
return keyboard;
}
public KeyboardId getMainKeyboardId() {
- final int elementState = Builder.getElementState(mParams.mMode, false, false);
- return Builder.getKeyboardId(elementState, false, mParams);
+ final int element = KeyboardSet.getElement(mParams.mMode, false, false);
+ return KeyboardSet.getKeyboardId(element, false, mParams);
}
private Keyboard getKeyboard(Context context, int xmlId, KeyboardId id) {
@@ -147,6 +152,30 @@ public class KeyboardSet {
return keyboard;
}
+ private static int getElement(int mode, boolean isSymbols, boolean isShift) {
+ switch (mode) {
+ case KeyboardId.MODE_PHONE:
+ return (isSymbols && isShift)
+ ? KeyboardId.ELEMENT_PHONE_SHIFTED : KeyboardId.ELEMENT_PHONE;
+ case KeyboardId.MODE_NUMBER:
+ return KeyboardId.ELEMENT_NUMBER;
+ default:
+ if (isSymbols) {
+ return isShift
+ ? KeyboardId.ELEMENT_SYMBOLS_SHIFTED : KeyboardId.ELEMENT_SYMBOLS;
+ }
+ return KeyboardId.ELEMENT_ALPHABET;
+ }
+ }
+
+ private static KeyboardId getKeyboardId(int element, boolean isSymbols, Params params) {
+ final boolean hasShortcutKey = params.mVoiceKeyEnabled
+ && (isSymbols != params.mVoiceKeyOnMain);
+ return new KeyboardId(element, params.mLocale, params.mOrientation, params.mWidth,
+ params.mMode, params.mInputType, params.mImeOptions, params.mSettingsKeyEnabled,
+ params.mNoSettingsKey, params.mVoiceKeyEnabled, hasShortcutKey);
+ }
+
public static class Builder {
private final Context mContext;
private final String mPackageName;
@@ -218,31 +247,6 @@ public class KeyboardSet {
return new KeyboardSet(mContext, mParams);
}
- // TODO: Move this method to KeyboardSet
- static KeyboardId getKeyboardId(int elementState, boolean isSymbols, Params params) {
- final boolean hasShortcutKey = params.mVoiceKeyEnabled
- && (isSymbols != params.mVoiceKeyOnMain);
- return new KeyboardId(elementState, params.mLocale, params.mOrientation, params.mWidth,
- params.mMode, params.mInputType, params.mImeOptions, params.mSettingsKeyEnabled,
- params.mNoSettingsKey, params.mVoiceKeyEnabled, hasShortcutKey);
- }
-
- // TODO: Move this method to KeyboardSet
- static int getElementState(int mode, boolean isSymbols, boolean isShift) {
- switch (mode) {
- case KeyboardId.MODE_PHONE:
- return (isSymbols && isShift)
- ? KeyboardId.ELEMENT_PHONE_SHIFT : KeyboardId.ELEMENT_PHONE;
- case KeyboardId.MODE_NUMBER:
- return KeyboardId.ELEMENT_NUMBER;
- default:
- if (isSymbols) {
- return isShift ? KeyboardId.ELEMENT_SYMBOLS_SHIFT : KeyboardId.ELEMENT_SYMBOLS;
- }
- return KeyboardId.ELEMENT_ALPHABET;
- }
- }
-
private void parseKeyboardSet(Resources res, int resId) throws XmlPullParserException,
IOException {
final XmlResourceParser parser = res.getXml(resId);
@@ -300,8 +304,14 @@ public class KeyboardSet {
final int elementName = a.getInt(
R.styleable.KeyboardSet_Element_elementName, 0);
- final int elementKeyboard = a.getResourceId(
- R.styleable.KeyboardSet_Element_elementKeyboard, 0);
+ final int index = R.styleable.KeyboardSet_Element_elementKeyboard;
+ final TypedValue v = a.peekValue(index);
+ final int elementKeyboard;
+ if (v.type == TypedValue.TYPE_REFERENCE) {
+ elementKeyboard = a.getResourceId(index, 0);
+ } else {
+ elementKeyboard = a.getInt(index, 0);
+ }
mParams.mElementKeyboards.put(elementName, elementKeyboard);
} finally {
a.recycle();
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index cb80d052e..1398bae2a 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -216,37 +216,53 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
return null;
}
- // Implements {@link KeyboardState.SwitchActions}.
- @Override
- public void setShifted(int shiftMode) {
+ /**
+ * Update keyboard shift state triggered by connected EditText status change.
+ */
+ public void updateShiftState() {
+ mState.onUpdateShiftState(mInputMethodService.getCurrentAutoCapsState());
+ }
+
+ public void onPressKey(int code) {
+ mState.onPressKey(code);
+ }
+
+ public void onReleaseKey(int code, boolean withSliding) {
+ mState.onReleaseKey(code, withSliding);
+ }
+
+ public void onCancelInput() {
+ mState.onCancelInput(isSinglePointer());
+ }
+
+ // TODO: Remove these constants.
+ private static final int ALPHABET_UNSHIFTED = 0;
+ private static final int ALPHABET_MANUAL_SHIFTED = 1;
+ private static final int ALPHABET_AUTOMATIC_SHIFTED = 2;
+ private static final int ALPHABET_SHIFT_LOCKED = 3;
+
+ // TODO: Remove this method.
+ private void updateAlphabetKeyboardShiftState(int shiftMode) {
mInputMethodService.mHandler.cancelUpdateShiftState();
Keyboard keyboard = getKeyboard();
if (keyboard == null)
return;
switch (shiftMode) {
- case AUTOMATIC_SHIFT:
- keyboard.setAutomaticTemporaryUpperCase();
+ case ALPHABET_UNSHIFTED:
+ keyboard.setShifted(false);
break;
- case MANUAL_SHIFT:
+ case ALPHABET_MANUAL_SHIFTED:
keyboard.setShifted(true);
break;
- case UNSHIFT:
- keyboard.setShifted(false);
+ case ALPHABET_AUTOMATIC_SHIFTED:
+ keyboard.setAutomaticTemporaryUpperCase();
+ break;
+ case ALPHABET_SHIFT_LOCKED:
+ keyboard.setShiftLocked(true);
break;
}
mKeyboardView.invalidateAllKeys();
- }
-
- // Implements {@link KeyboardState.SwitchActions}.
- @Override
- public void setShiftLocked(boolean shiftLocked) {
- mInputMethodService.mHandler.cancelUpdateShiftState();
- Keyboard keyboard = getKeyboard();
- if (keyboard == null)
- return;
- keyboard.setShiftLocked(shiftLocked);
- mKeyboardView.invalidateAllKeys();
- if (!shiftLocked) {
+ if (shiftMode != ALPHABET_SHIFT_LOCKED) {
// To be able to turn off caps lock by "double tap" on shift key, we should ignore
// the second tap of the "double tap" from now for a while because we just have
// already turned off caps lock above.
@@ -254,35 +270,38 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
}
}
- /**
- * Update keyboard shift state triggered by connected EditText status change.
- */
- public void updateShiftState() {
- mState.onUpdateShiftState(mInputMethodService.getCurrentAutoCapsState());
- }
-
- public void onPressKey(int code) {
- mState.onPressKey(code);
+ // Implements {@link KeyboardState.SwitchActions}.
+ @Override
+ public void setAlphabetKeyboard() {
+ setKeyboard(mKeyboardSet.getMainKeyboard());
+ updateAlphabetKeyboardShiftState(ALPHABET_UNSHIFTED);
}
- public void onReleaseKey(int code, boolean withSliding) {
- mState.onReleaseKey(code, withSliding);
+ // Implements {@link KeyboardState.SwitchActions}.
+ @Override
+ public void setAlphabetManualShiftedKeyboard() {
+ setKeyboard(mKeyboardSet.getMainKeyboard());
+ updateAlphabetKeyboardShiftState(ALPHABET_MANUAL_SHIFTED);
}
- public void onCancelInput() {
- mState.onCancelInput(isSinglePointer());
+ // Implements {@link KeyboardState.SwitchActions}.
+ @Override
+ public void setAlphabetAutomaticShiftedKeyboard() {
+ setKeyboard(mKeyboardSet.getMainKeyboard());
+ updateAlphabetKeyboardShiftState(ALPHABET_AUTOMATIC_SHIFTED);
}
// Implements {@link KeyboardState.SwitchActions}.
@Override
- public void setSymbolsKeyboard() {
- setKeyboard(mKeyboardSet.getSymbolsKeyboard());
+ public void setAlphabetShiftLockedKeyboard() {
+ setKeyboard(mKeyboardSet.getMainKeyboard());
+ updateAlphabetKeyboardShiftState(ALPHABET_SHIFT_LOCKED);
}
// Implements {@link KeyboardState.SwitchActions}.
@Override
- public void setAlphabetKeyboard() {
- setKeyboard(mKeyboardSet.getMainKeyboard());
+ public void setSymbolsKeyboard() {
+ setKeyboard(mKeyboardSet.getSymbolsKeyboard());
}
// Implements {@link KeyboardState.SwitchActions}.
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
index babf600a6..38c31adce 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -40,16 +40,12 @@ public class KeyboardState {
public interface SwitchActions {
public void setAlphabetKeyboard();
-
- public static final int UNSHIFT = 0;
- public static final int MANUAL_SHIFT = 1;
- public static final int AUTOMATIC_SHIFT = 2;
- public void setShifted(int shiftMode);
-
- public void setShiftLocked(boolean shiftLocked);
-
+ public void setAlphabetManualShiftedKeyboard();
+ public void setAlphabetAutomaticShiftedKeyboard();
+ public void setAlphabetShiftLockedKeyboard();
+ // TODO: Add this.
+ //public void setAlphabetShiftLockShiftedKeyboard();
public void setSymbolsKeyboard();
-
public void setSymbolsShiftedKeyboard();
/**
@@ -63,14 +59,14 @@ public class KeyboardState {
private ShiftKeyState mShiftKeyState = new ShiftKeyState("Shift");
private ModifierKeyState mSymbolKeyState = new ModifierKeyState("Symbol");
+ // TODO: Merge {@link #mSwitchState}, {@link #mIsAlphabetMode}, {@link #mAlphabetShiftState},
+ // {@link #mIsSymbolShifted}, {@link #mPrevMainKeyboardWasShiftLocked}, and
+ // {@link #mPrevSymbolsKeyboardWasShifted} into single state variable.
private static final int SWITCH_STATE_ALPHA = 0;
private static final int SWITCH_STATE_SYMBOL_BEGIN = 1;
private static final int SWITCH_STATE_SYMBOL = 2;
- // The following states are used only on the distinct multi-touch panel devices.
private static final int SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL = 3;
private static final int SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE = 4;
- private static final int SWITCH_STATE_CHORDING_ALPHA = 5;
- private static final int SWITCH_STATE_CHORDING_SYMBOL = 6;
private int mSwitchState = SWITCH_STATE_ALPHA;
private String mLayoutSwitchBackSymbols;
@@ -88,6 +84,7 @@ public class KeyboardState {
public boolean mIsShiftLocked;
public boolean mIsShifted;
+ @Override
public String toString() {
if (!mIsValid) return "INVALID";
if (mIsAlphabetMode) {
@@ -155,7 +152,7 @@ public class KeyboardState {
if (state.mIsAlphabetMode) {
setShiftLocked(state.mIsShiftLocked);
if (!state.mIsShiftLocked) {
- setShifted(state.mIsShifted ? SwitchActions.MANUAL_SHIFT : SwitchActions.UNSHIFT);
+ setShifted(state.mIsShifted ? MANUAL_SHIFT : UNSHIFT);
}
}
}
@@ -165,30 +162,58 @@ public class KeyboardState {
return mAlphabetShiftState.isShiftLocked();
}
+ private static final int UNSHIFT = 0;
+ private static final int MANUAL_SHIFT = 1;
+ private static final int AUTOMATIC_SHIFT = 2;
+
private void setShifted(int shiftMode) {
if (DEBUG_ACTION) {
- Log.d(TAG, "setShifted: shiftMode=" + shiftModeToString(shiftMode));
+ Log.d(TAG, "setShifted: shiftMode=" + shiftModeToString(shiftMode) + " " + this);
+ }
+ if (!mIsAlphabetMode) return;
+ final int prevShiftMode;
+ if (mAlphabetShiftState.isAutomaticTemporaryUpperCase()) {
+ prevShiftMode = AUTOMATIC_SHIFT;
+ } else if (mAlphabetShiftState.isManualTemporaryUpperCase()) {
+ prevShiftMode = MANUAL_SHIFT;
+ } else {
+ prevShiftMode = UNSHIFT;
}
switch (shiftMode) {
- case SwitchActions.AUTOMATIC_SHIFT:
+ case AUTOMATIC_SHIFT:
mAlphabetShiftState.setAutomaticTemporaryUpperCase();
+ if (shiftMode != prevShiftMode) {
+ mSwitchActions.setAlphabetAutomaticShiftedKeyboard();
+ }
break;
- case SwitchActions.MANUAL_SHIFT:
+ case MANUAL_SHIFT:
mAlphabetShiftState.setShifted(true);
+ if (shiftMode != prevShiftMode) {
+ mSwitchActions.setAlphabetManualShiftedKeyboard();
+ }
break;
- case SwitchActions.UNSHIFT:
+ case UNSHIFT:
mAlphabetShiftState.setShifted(false);
+ if (shiftMode != prevShiftMode) {
+ mSwitchActions.setAlphabetKeyboard();
+ }
break;
}
- mSwitchActions.setShifted(shiftMode);
}
private void setShiftLocked(boolean shiftLocked) {
if (DEBUG_ACTION) {
- Log.d(TAG, "setShiftLocked: shiftLocked=" + shiftLocked);
+ Log.d(TAG, "setShiftLocked: shiftLocked=" + shiftLocked + " " + this);
+ }
+ if (!mIsAlphabetMode) return;
+ if (shiftLocked && (!mAlphabetShiftState.isShiftLocked()
+ || mAlphabetShiftState.isShiftLockShifted())) {
+ mSwitchActions.setAlphabetShiftLockedKeyboard();
+ }
+ if (!shiftLocked && mAlphabetShiftState.isShiftLocked()) {
+ mSwitchActions.setAlphabetKeyboard();
}
mAlphabetShiftState.setShiftLocked(shiftLocked);
- mSwitchActions.setShiftLocked(shiftLocked);
}
private void toggleAlphabetAndSymbols() {
@@ -276,8 +301,7 @@ public class KeyboardState {
if (code == Keyboard.CODE_SHIFT) {
onReleaseShift(withSliding);
} else if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
- // TODO: Make use of withSliding instead of relying on mSwitchState.
- onReleaseSymbol();
+ onReleaseSymbol(withSliding);
}
}
@@ -287,11 +311,16 @@ public class KeyboardState {
mSwitchState = SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL;
}
- private void onReleaseSymbol() {
- // Switch back to the previous keyboard mode if the user chords the mode change key and
- // another key, then releases the mode change key.
- if (mSwitchState == SWITCH_STATE_CHORDING_ALPHA) {
+ private void onReleaseSymbol(boolean withSliding) {
+ if (mSymbolKeyState.isChording()) {
+ // Switch back to the previous keyboard mode if the user chords the mode change key and
+ // another key, then releases the mode change key.
toggleAlphabetAndSymbols();
+ } else if (!withSliding) {
+ // If the mode change key is being released without sliding, we should forget the
+ // previous symbols keyboard shift state and simply switch back to symbols layout
+ // (never symbols shifted) next time the mode gets changed to symbols layout.
+ mPrevSymbolsKeyboardWasShifted = false;
}
mSymbolKeyState.onRelease();
}
@@ -300,24 +329,18 @@ public class KeyboardState {
if (DEBUG_EVENT) {
Log.d(TAG, "onUpdateShiftState: autoCaps=" + autoCaps + " " + this);
}
- onUpdateShiftStateInternal(autoCaps);
+ updateAlphabetShiftState(autoCaps);
}
- private void onUpdateShiftStateInternal(boolean autoCaps) {
- if (mIsAlphabetMode) {
- if (!mAlphabetShiftState.isShiftLocked() && !mShiftKeyState.isIgnoring()) {
- if (mShiftKeyState.isReleasing() && autoCaps) {
- // Only when shift key is releasing, automatic temporary upper case will be set.
- setShifted(SwitchActions.AUTOMATIC_SHIFT);
- } else {
- setShifted(mShiftKeyState.isMomentary()
- ? SwitchActions.MANUAL_SHIFT : SwitchActions.UNSHIFT);
- }
+ private void updateAlphabetShiftState(boolean autoCaps) {
+ if (!mIsAlphabetMode) return;
+ if (!mAlphabetShiftState.isShiftLocked() && !mShiftKeyState.isIgnoring()) {
+ if (mShiftKeyState.isReleasing() && autoCaps) {
+ // Only when shift key is releasing, automatic temporary upper case will be set.
+ setShifted(AUTOMATIC_SHIFT);
+ } else {
+ setShifted(mShiftKeyState.isChording() ? MANUAL_SHIFT : UNSHIFT);
}
- } else {
- // In symbol keyboard mode, we should clear shift key state because only alphabet
- // keyboard has shift key.
- mSymbolKeyState.onRelease();
}
}
@@ -326,12 +349,12 @@ public class KeyboardState {
if (mAlphabetShiftState.isShiftLocked()) {
// Shift key is pressed while caps lock state, we will treat this state as shifted
// caps lock state and mark as if shift key pressed while normal state.
- setShifted(SwitchActions.MANUAL_SHIFT);
+ setShifted(MANUAL_SHIFT);
mShiftKeyState.onPress();
} else if (mAlphabetShiftState.isAutomaticTemporaryUpperCase()) {
// Shift key is pressed while automatic temporary upper case, we have to move to
// manual temporary upper case.
- setShifted(SwitchActions.MANUAL_SHIFT);
+ setShifted(MANUAL_SHIFT);
mShiftKeyState.onPress();
} else if (mAlphabetShiftState.isShiftedOrShiftLocked()) {
// In manual upper case state, we just record shift key has been pressing while
@@ -339,7 +362,7 @@ public class KeyboardState {
mShiftKeyState.onPressOnShifted();
} else {
// In base layout, chording or manual temporary upper case mode is started.
- setShifted(SwitchActions.MANUAL_SHIFT);
+ setShifted(MANUAL_SHIFT);
mShiftKeyState.onPress();
}
} else {
@@ -353,13 +376,17 @@ public class KeyboardState {
private void onReleaseShift(boolean withSliding) {
if (mIsAlphabetMode) {
final boolean isShiftLocked = mAlphabetShiftState.isShiftLocked();
- if (mShiftKeyState.isMomentary()) {
- // After chording input while normal state.
+ if (mShiftKeyState.isChording()) {
if (mAlphabetShiftState.isShiftLockShifted()) {
+ // After chording input while caps lock state.
setShiftLocked(true);
} else {
- setShifted(SwitchActions.UNSHIFT);
+ // After chording input while normal state.
+ setShifted(UNSHIFT);
}
+ } else if (mAlphabetShiftState.isShiftLockShifted() && withSliding) {
+ // In caps lock state, shift has been pressed and slid out to other key.
+ setShiftLocked(true);
} else if (isShiftLocked && !mAlphabetShiftState.isShiftLockShifted()
&& (mShiftKeyState.isPressing() || mShiftKeyState.isPressingOnShifted())
&& !withSliding) {
@@ -370,17 +397,17 @@ public class KeyboardState {
} else if (mAlphabetShiftState.isShiftedOrShiftLocked()
&& mShiftKeyState.isPressingOnShifted() && !withSliding) {
// Shift has been pressed without chording while shifted state.
- setShifted(SwitchActions.UNSHIFT);
+ setShifted(UNSHIFT);
} else if (mAlphabetShiftState.isManualTemporaryUpperCaseFromAuto()
&& mShiftKeyState.isPressing() && !withSliding) {
// Shift has been pressed without chording while manual temporary upper case
// transited from automatic temporary upper case.
- setShifted(SwitchActions.UNSHIFT);
+ setShifted(UNSHIFT);
}
} else {
// In symbol mode, switch back to the previous keyboard mode if the user chords the
// shift key and another key, then releases the shift key.
- if (mSwitchState == SWITCH_STATE_CHORDING_SYMBOL) {
+ if (mShiftKeyState.isChording()) {
toggleShiftInSymbols();
}
}
@@ -436,12 +463,6 @@ public class KeyboardState {
switch (mSwitchState) {
case SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL:
- // Only distinct multi touch devices can be in this state.
- // On non-distinct multi touch devices, mode change key is handled by
- // {@link LatinIME#onCodeInput}, not by {@link LatinIME#onPress} and
- // {@link LatinIME#onRelease}. So, on such devices, {@link #mSwitchState} starts
- // from {@link #SWITCH_STATE_SYMBOL_BEGIN}, or {@link #SWITCH_STATE_ALPHA}, not from
- // {@link #SWITCH_STATE_MOMENTARY}.
if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
// Detected only the mode change key has been pressed, and then released.
if (mIsAlphabetMode) {
@@ -455,10 +476,6 @@ public class KeyboardState {
// If the user cancels the sliding input, switching back to the previous keyboard
// mode is handled by {@link #onCancelInput}.
toggleAlphabetAndSymbols();
- } else {
- // Chording input is being started. The keyboard mode will be switched back to the
- // previous mode in {@link onReleaseSymbol} when the mode change key is released.
- mSwitchState = SWITCH_STATE_CHORDING_ALPHA;
}
break;
case SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE:
@@ -470,10 +487,6 @@ public class KeyboardState {
// symbol mode and slid to other key, then released the finger.
toggleShiftInSymbols();
mSwitchState = SWITCH_STATE_SYMBOL;
- } else {
- // Chording input is being started. The keyboard mode will be switched back to the
- // previous mode in {@link onReleaseShift} when the shift key is released.
- mSwitchState = SWITCH_STATE_CHORDING_SYMBOL;
}
break;
case SWITCH_STATE_SYMBOL_BEGIN:
@@ -487,7 +500,6 @@ public class KeyboardState {
}
break;
case SWITCH_STATE_SYMBOL:
- case SWITCH_STATE_CHORDING_SYMBOL:
// Switch back to alpha keyboard mode if user types one or more non-space/enter
// characters followed by a space/enter or a quote character.
if (isSpaceCharacter(code) || isLayoutSwitchBackCharacter(code)) {
@@ -498,15 +510,15 @@ public class KeyboardState {
// If the code is a letter, update keyboard shift state.
if (Keyboard.isLetterCode(code)) {
- onUpdateShiftStateInternal(autoCaps);
+ updateAlphabetShiftState(autoCaps);
}
}
private static String shiftModeToString(int shiftMode) {
switch (shiftMode) {
- case SwitchActions.UNSHIFT: return "UNSHIFT";
- case SwitchActions.MANUAL_SHIFT: return "MANUAL";
- case SwitchActions.AUTOMATIC_SHIFT: return "AUTOMATIC";
+ case UNSHIFT: return "UNSHIFT";
+ case MANUAL_SHIFT: return "MANUAL";
+ case AUTOMATIC_SHIFT: return "AUTOMATIC";
default: return null;
}
}
@@ -518,8 +530,6 @@ public class KeyboardState {
case SWITCH_STATE_SYMBOL: return "SYMBOL";
case SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL: return "MOMENTARY-ALPHA-SYMBOL";
case SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE: return "MOMENTARY-SYMBOL-MORE";
- case SWITCH_STATE_CHORDING_ALPHA: return "CHORDING-ALPHA";
- case SWITCH_STATE_CHORDING_SYMBOL: return "CHORDING-SYMBOL";
default: return null;
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/ModifierKeyState.java b/java/src/com/android/inputmethod/keyboard/internal/ModifierKeyState.java
index f95c91636..b39b97720 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/ModifierKeyState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/ModifierKeyState.java
@@ -19,12 +19,12 @@ package com.android.inputmethod.keyboard.internal;
import android.util.Log;
/* package */ class ModifierKeyState {
- protected static final String TAG = "ModifierKeyState";
+ protected static final String TAG = ModifierKeyState.class.getSimpleName();
protected static final boolean DEBUG = false;
protected static final int RELEASING = 0;
protected static final int PRESSING = 1;
- protected static final int MOMENTARY = 2;
+ protected static final int CHORDING = 2;
protected final String mName;
protected int mState = RELEASING;
@@ -50,7 +50,7 @@ import android.util.Log;
public void onOtherKeyPressed() {
final int oldState = mState;
if (oldState == PRESSING)
- mState = MOMENTARY;
+ mState = CHORDING;
if (DEBUG)
Log.d(TAG, mName + ".onOtherKeyPressed: " + toString(oldState) + " > " + this);
}
@@ -63,8 +63,8 @@ import android.util.Log;
return mState == RELEASING;
}
- public boolean isMomentary() {
- return mState == MOMENTARY;
+ public boolean isChording() {
+ return mState == CHORDING;
}
@Override
@@ -76,7 +76,7 @@ import android.util.Log;
switch (state) {
case RELEASING: return "RELEASING";
case PRESSING: return "PRESSING";
- case MOMENTARY: return "MOMENTARY";
+ case CHORDING: return "CHORDING";
default: return "UNKNOWN";
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/ShiftKeyState.java b/java/src/com/android/inputmethod/keyboard/internal/ShiftKeyState.java
index 6f54b4f23..edb40c8e7 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/ShiftKeyState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/ShiftKeyState.java
@@ -30,7 +30,7 @@ import android.util.Log;
public void onOtherKeyPressed() {
int oldState = mState;
if (oldState == PRESSING) {
- mState = MOMENTARY;
+ mState = CHORDING;
} else if (oldState == PRESSING_ON_SHIFTED) {
mState = IGNORING;
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 94c47bdc9..31cbc4ee3 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -203,9 +203,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private WordComposer mWordComposer = new WordComposer();
private int mCorrectionMode;
+
// Keep track of the last selection range to decide if we need to show word alternatives
- private int mLastSelectionStart;
- private int mLastSelectionEnd;
+ private static final int NOT_A_CURSOR_POSITION = -1;
+ private int mLastSelectionStart = NOT_A_CURSOR_POSITION;
+ private int mLastSelectionEnd = NOT_A_CURSOR_POSITION;
// Whether we are expecting an onUpdateSelection event to fire. If it does when we don't
// "expect" it, it means the user actually moved the cursor.
@@ -391,7 +393,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// Working variables for the following methods.
private boolean mIsOrientationChanging;
- private boolean mPendingSuccesiveImsCallback;
+ private boolean mPendingSuccessiveImsCallback;
private boolean mHasPendingStartInput;
private boolean mHasPendingFinishInputView;
private boolean mHasPendingFinishInput;
@@ -432,7 +434,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
if (mIsOrientationChanging && restarting) {
// This is the first onStartInput after orientation changed.
mIsOrientationChanging = false;
- mPendingSuccesiveImsCallback = true;
+ mPendingSuccessiveImsCallback = true;
}
final LatinIME latinIme = getOuterInstance();
executePendingImsCallback(latinIme, editorInfo, restarting);
@@ -446,9 +448,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// Typically this is the second onStartInputView after orientation changed.
resetPendingImsCallback();
} else {
- if (mPendingSuccesiveImsCallback) {
+ if (mPendingSuccessiveImsCallback) {
// This is the first onStartInputView after orientation changed.
- mPendingSuccesiveImsCallback = false;
+ mPendingSuccessiveImsCallback = false;
resetPendingImsCallback();
sendMessageDelayed(obtainMessage(MSG_PENDING_IMS_CALLBACK),
PENDING_IMS_CALLBACK_DURATION);
@@ -1401,9 +1403,29 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// inconsistent with backspacing after selecting other suggestions.
restartSuggestionsOnManuallyPickedTypedWord(ic);
} else {
- ic.deleteSurroundingText(1, 0);
- if (mDeleteCount > DELETE_ACCELERATE_AT) {
- ic.deleteSurroundingText(1, 0);
+ // Here we must check whether there is a selection. If so we should remove the
+ // selected text, otherwise we should just delete the character before the cursor.
+ if (mLastSelectionStart != mLastSelectionEnd) {
+ final int lengthToDelete = mLastSelectionEnd - mLastSelectionStart;
+ ic.setSelection(mLastSelectionEnd, mLastSelectionEnd);
+ ic.deleteSurroundingText(lengthToDelete, 0);
+ } else {
+ if (NOT_A_CURSOR_POSITION == mLastSelectionEnd) {
+ // We don't know whether there is a selection or not. We just send a false
+ // hardware key event and let TextView sort it out for us. The problem
+ // here is, this is asynchronous with respect to the input connection
+ // batch edit, so it may flicker. But this only ever happens if backspace
+ // is pressed just after the IME is invoked, and then again only once.
+ // TODO: add an API call that gets the selection indices. This is available
+ // to the IME in the general case via onUpdateSelection anyway, and would
+ // allow us to remove this race condition.
+ sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
+ } else {
+ ic.deleteSurroundingText(1, 0);
+ }
+ if (mDeleteCount > DELETE_ACCELERATE_AT) {
+ ic.deleteSurroundingText(1, 0);
+ }
}
if (isSuggestionsRequested()) {
restartSuggestionsOnWordBeforeCursorIfAtEndOfWord(ic);