aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
authorTadashi G. Takaoka <takaoka@google.com>2012-01-31 15:54:48 +0900
committerTadashi G. Takaoka <takaoka@google.com>2012-01-31 18:06:54 +0900
commit0ed2d3a4491cb0f6142975a15b653be6079b6a4e (patch)
tree8e9044fa6e94eed065dc47f58cd5c7e61d05c87b /java/src
parent30964843db0c3c7892ca443a0513c9c36e8654d1 (diff)
downloadlatinime-0ed2d3a4491cb0f6142975a15b653be6079b6a4e.tar.gz
latinime-0ed2d3a4491cb0f6142975a15b653be6079b6a4e.tar.xz
latinime-0ed2d3a4491cb0f6142975a15b653be6079b6a4e.zip
Fix double tap shift key enable/disable shift locked mode
Bug: 5942452 Change-Id: I2c7b1605bceac2b2f929cd4d97c417ef15c6f754
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java19
-rw-r--r--java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java103
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTracker.java6
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java61
4 files changed, 80 insertions, 109 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 17ad45df0..d5ea76a2f 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -27,6 +27,7 @@ import android.view.View;
import android.view.inputmethod.EditorInfo;
import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
+import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
import com.android.inputmethod.keyboard.internal.KeyboardState;
import com.android.inputmethod.latin.DebugSettings;
import com.android.inputmethod.latin.InputView;
@@ -270,6 +271,24 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
mState.onUpdateShiftState(mInputMethodService.getCurrentAutoCapsState());
}
+ // Implements {@link KeyboardState.SwitchActions}.
+ @Override
+ public void startDoubleTapTimer() {
+ final LatinKeyboardView keyboardView = getKeyboardView();
+ if (keyboardView != null) {
+ final TimerProxy timer = keyboardView.getTimerProxy();
+ timer.startDoubleTapTimer();
+ }
+ }
+
+ // Implements {@link KeyboardState.SwitchActions}.
+ @Override
+ public boolean isInDoubleTapTimeout() {
+ final LatinKeyboardView keyboardView = getKeyboardView();
+ return (keyboardView != null)
+ ? keyboardView.getTimerProxy().isInDoubleTapTimeout() : false;
+ }
+
public boolean isInMomentarySwitchState() {
return mState.isInMomentarySwitchState();
}
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index 056aa255d..5aad67d49 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -29,7 +29,6 @@ import android.os.Message;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
-import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
@@ -64,8 +63,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
SuddenJumpingTouchEventHandler.ProcessMotionEvent {
private static final String TAG = LatinKeyboardView.class.getSimpleName();
- private static final boolean ENABLE_CAPSLOCK_BY_DOUBLETAP = true;
-
// TODO: Kill process when the usability study mode was changed.
private static final boolean ENABLE_USABILITY_STUDY_LOG = LatinImeLogger.sUsabilityStudy;
@@ -111,16 +108,13 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
private int mOldPointerCount = 1;
private Key mOldKey;
- // To detect double tap.
- protected GestureDetector mGestureDetector;
-
private final KeyTimerHandler mKeyTimerHandler;
private static class KeyTimerHandler extends StaticInnerHandlerWrapper<LatinKeyboardView>
implements TimerProxy {
private static final int MSG_REPEAT_KEY = 1;
private static final int MSG_LONGPRESS_KEY = 2;
- private static final int MSG_IGNORE_DOUBLE_TAP = 3;
+ private static final int MSG_DOUBLE_TAP = 3;
private static final int MSG_KEY_TYPED = 4;
private final int mKeyRepeatInterval;
@@ -184,70 +178,24 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
}
@Override
- public void cancelKeyTimers() {
- cancelKeyRepeatTimer();
- cancelLongPressTimer();
- removeMessages(MSG_IGNORE_DOUBLE_TAP);
- }
-
- public void startIgnoringDoubleTap() {
- sendMessageDelayed(obtainMessage(MSG_IGNORE_DOUBLE_TAP),
+ public void startDoubleTapTimer() {
+ sendMessageDelayed(obtainMessage(MSG_DOUBLE_TAP),
ViewConfiguration.getDoubleTapTimeout());
}
- public boolean isIgnoringDoubleTap() {
- return hasMessages(MSG_IGNORE_DOUBLE_TAP);
- }
-
- public void cancelAllMessages() {
- cancelKeyTimers();
+ @Override
+ public boolean isInDoubleTapTimeout() {
+ return hasMessages(MSG_DOUBLE_TAP);
}
- }
-
- class DoubleTapListener extends GestureDetector.SimpleOnGestureListener {
- private boolean mProcessingShiftDoubleTapEvent = false;
@Override
- public boolean onDoubleTap(MotionEvent firstDown) {
- final Keyboard keyboard = getKeyboard();
- if (ENABLE_CAPSLOCK_BY_DOUBLETAP && keyboard.mId.isAlphabetKeyboard()) {
- final int pointerIndex = firstDown.getActionIndex();
- final int id = firstDown.getPointerId(pointerIndex);
- final PointerTracker tracker = PointerTracker.getPointerTracker(
- id, LatinKeyboardView.this);
- final Key key = tracker.getKeyOn((int)firstDown.getX(), (int)firstDown.getY());
- // If the first down event is on shift key.
- if (key != null && key.isShift()) {
- mProcessingShiftDoubleTapEvent = true;
- return true;
- }
- }
- mProcessingShiftDoubleTapEvent = false;
- return false;
+ public void cancelKeyTimers() {
+ cancelKeyRepeatTimer();
+ cancelLongPressTimer();
}
- @Override
- public boolean onDoubleTapEvent(MotionEvent secondTap) {
- if (mProcessingShiftDoubleTapEvent
- && secondTap.getAction() == MotionEvent.ACTION_DOWN) {
- final MotionEvent secondDown = secondTap;
- final int pointerIndex = secondDown.getActionIndex();
- final int id = secondDown.getPointerId(pointerIndex);
- final PointerTracker tracker = PointerTracker.getPointerTracker(
- id, LatinKeyboardView.this);
- final Key key = tracker.getKeyOn((int)secondDown.getX(), (int)secondDown.getY());
- // If the second down event is also on shift key.
- if (key != null && key.isShift()) {
- // Detected a double tap on shift key. If we are in the ignoring double tap
- // mode, it means we have already turned off caps lock in
- // {@link KeyboardSwitcher#onReleaseShift} .
- onDoubleTapShiftKey(mKeyTimerHandler.isIgnoringDoubleTap());
- return true;
- }
- // Otherwise these events should not be handled as double tap.
- mProcessingShiftDoubleTapEvent = false;
- }
- return mProcessingShiftDoubleTapEvent;
+ public void cancelAllMessages() {
+ cancelKeyTimers();
}
}
@@ -303,11 +251,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
mTouchScreenRegulator = new SuddenJumpingTouchEventHandler(getContext(), this);
- final boolean ignoreMultitouch = true;
- mGestureDetector = new GestureDetector(
- getContext(), new DoubleTapListener(), null, ignoreMultitouch);
- mGestureDetector.setIsLongpressEnabled(false);
-
mHasDistinctMultitouch = context.getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT);
@@ -342,11 +285,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
PointerTracker.setParameters(mPointerTrackerParams);
}
- public void startIgnoringDoubleTap() {
- if (ENABLE_CAPSLOCK_BY_DOUBLETAP)
- mKeyTimerHandler.startIgnoringDoubleTap();
- }
-
public void setKeyboardActionListener(KeyboardActionListener listener) {
mKeyboardActionListener = listener;
PointerTracker.setKeyboardActionListener(listener);
@@ -451,17 +389,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
return onLongPress(parentKey, tracker);
}
- private void onDoubleTapShiftKey(final boolean ignore) {
- // 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) {
- invokeCustomRequest(LatinIME.CODE_HAPTIC_AND_AUDIO_FEEDBACK);
- } else {
- invokeCodeInput(Keyboard.CODE_CAPSLOCK);
- }
- }
-
// This default implementation returns a more keys panel.
protected MoreKeysPanel onCreateMoreKeysPanel(Key parentKey) {
if (parentKey.mMoreKeys == null)
@@ -595,14 +522,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
return true;
}
- // Gesture detector must be enabled only when mini-keyboard is not on the screen.
- if (mMoreKeysPanel == null && mGestureDetector != null
- && mGestureDetector.onTouchEvent(me)) {
- PointerTracker.dismissAllKeyPreviews();
- mKeyTimerHandler.cancelKeyTimers();
- return true;
- }
-
final long eventTime = me.getEventTime();
final int index = me.getActionIndex();
final int id = me.getPointerId(index);
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 4dac3474d..fc92a24a6 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -76,6 +76,8 @@ public class PointerTracker {
public void startKeyRepeatTimer(long delay, PointerTracker tracker);
public void startLongPressTimer(long delay, PointerTracker tracker);
public void cancelLongPressTimer();
+ public void startDoubleTapTimer();
+ public boolean isInDoubleTapTimeout();
public void cancelKeyTimers();
public static class Adapter implements TimerProxy {
@@ -90,6 +92,10 @@ public class PointerTracker {
@Override
public void cancelLongPressTimer() {}
@Override
+ public void startDoubleTapTimer() {}
+ @Override
+ public boolean isInDoubleTapTimeout() { return false; }
+ @Override
public void cancelKeyTimers() {}
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
index 4af4e3cdf..19c644d1f 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -51,6 +51,9 @@ public class KeyboardState {
* Request to call back {@link KeyboardState#onUpdateShiftState(boolean)}.
*/
public void requestUpdatingShiftState();
+
+ public void startDoubleTapTimer();
+ public boolean isInDoubleTapTimeout();
}
private final SwitchActions mSwitchActions;
@@ -75,6 +78,10 @@ public class KeyboardState {
private boolean mPrevMainKeyboardWasShiftLocked;
private boolean mPrevSymbolsKeyboardWasShifted;
+ // For handling double tap.
+ private boolean mIsInAlphabetUnshiftedFromShifted;
+ private boolean mIsInDoubleTapShiftKey;
+
private final SavedKeyboardState mSavedKeyboardState = new SavedKeyboardState();
static class SavedKeyboardState {
@@ -256,8 +263,7 @@ public class KeyboardState {
mSwitchActions.requestUpdatingShiftState();
}
- // TODO: Make this method private
- public void setSymbolsKeyboard() {
+ private void setSymbolsKeyboard() {
if (DEBUG_ACTION) {
Log.d(TAG, "setSymbolsKeyboard");
}
@@ -348,22 +354,35 @@ public class KeyboardState {
private void onPressShift() {
if (mIsAlphabetMode) {
- 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.
+ mIsInDoubleTapShiftKey = mSwitchActions.isInDoubleTapTimeout();
+ if (!mIsInDoubleTapShiftKey) {
+ // This is first tap.
+ mSwitchActions.startDoubleTapTimer();
+ }
+ if (mIsInDoubleTapShiftKey) {
+ if (mAlphabetShiftState.isManualShifted() || mIsInAlphabetUnshiftedFromShifted) {
+ // Shift key has been double tapped while in manual shifted or automatic
+ // shifted state.
+ setShiftLocked(true);
+ } else {
+ // Shift key has been double tapped while in normal state. This is the second
+ // tap to disable shift locked state, so just ignore this.
+ }
+ } else if (mAlphabetShiftState.isShiftLocked()) {
+ // Shift key is pressed while shift locked state, we will treat this state as
+ // shift lock shifted state and mark as if shift key pressed while normal state.
setShifted(SHIFT_LOCK_SHIFTED);
mShiftKeyState.onPress();
} else if (mAlphabetShiftState.isAutomaticShifted()) {
- // Shift key is pressed while automatic temporary upper case, we have to move to
- // manual temporary upper case.
+ // Shift key is pressed while automatic shifted, we have to move to manual shifted.
setShifted(MANUAL_SHIFT);
mShiftKeyState.onPress();
} else if (mAlphabetShiftState.isShiftedOrShiftLocked()) {
- // In manual upper case state, we just record shift key has been pressing while
+ // In manual shifted state, we just record shift key has been pressing while
// shifted state.
mShiftKeyState.onPressOnShifted();
} else {
- // In base layout, chording or manual temporary upper case mode is started.
+ // In base layout, chording or manual shifted mode is started.
setShifted(MANUAL_SHIFT);
mShiftKeyState.onPress();
}
@@ -378,33 +397,40 @@ public class KeyboardState {
private void onReleaseShift(boolean withSliding) {
if (mIsAlphabetMode) {
final boolean isShiftLocked = mAlphabetShiftState.isShiftLocked();
- if (mShiftKeyState.isChording()) {
+ mIsInAlphabetUnshiftedFromShifted = false;
+ if (mIsInDoubleTapShiftKey) {
+ // Double tap shift key has been handled in {@link #onPressShift}, so that just
+ // ignore this release shift key here.
+ mIsInDoubleTapShiftKey = false;
+ } else if (mShiftKeyState.isChording()) {
if (mAlphabetShiftState.isShiftLockShifted()) {
- // After chording input while caps lock state.
+ // After chording input while shift locked state.
setShiftLocked(true);
} else {
// 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.
+ // In shift locked state, shift has been pressed and slid out to other key.
setShiftLocked(true);
} else if (isShiftLocked && !mAlphabetShiftState.isShiftLockShifted()
&& (mShiftKeyState.isPressing() || mShiftKeyState.isPressingOnShifted())
&& !withSliding) {
// Shift has been long pressed, ignore this release.
} else if (isShiftLocked && !mShiftKeyState.isIgnoring() && !withSliding) {
- // Shift has been pressed without chording while caps lock state.
+ // Shift has been pressed without chording while shift locked state.
setShiftLocked(false);
} else if (mAlphabetShiftState.isShiftedOrShiftLocked()
&& mShiftKeyState.isPressingOnShifted() && !withSliding) {
// Shift has been pressed without chording while shifted state.
setShifted(UNSHIFT);
+ mIsInAlphabetUnshiftedFromShifted = true;
} else if (mAlphabetShiftState.isManualShiftedFromAutomaticShifted()
&& mShiftKeyState.isPressing() && !withSliding) {
- // Shift has been pressed without chording while manual temporary upper case
- // transited from automatic temporary upper case.
+ // Shift has been pressed without chording while manual shifted transited from
+ // automatic shifted
setShifted(UNSHIFT);
+ mIsInAlphabetUnshiftedFromShifted = true;
}
} else {
// In symbol mode, switch back to the previous keyboard mode if the user chords the
@@ -455,10 +481,11 @@ public class KeyboardState {
if (mIsAlphabetMode && code == Keyboard.CODE_CAPSLOCK) {
if (mAlphabetShiftState.isShiftLocked()) {
setShiftLocked(false);
- // Shift key is long pressed or double tapped while caps lock state, we will
- // toggle back to normal state. And mark as if shift key is released.
+ // Shift key is long pressed while shift locked state, we will toggle back to normal
+ // state. And mark as if shift key is released.
mShiftKeyState.onRelease();
} else {
+ // Shift key is long pressed while shift unloked state.
setShiftLocked(true);
}
}