Support multi-touch only when device has distinct multi-touch panel
Bug: 2973373 Change-Id: I9871c09ec8c1c2aa945d97392e61ee1ec585baefmain
parent
a8d9702fc4
commit
c8b9afe037
|
@ -365,6 +365,10 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
}
|
||||
}
|
||||
|
||||
public boolean hasDistinctMultitouch() {
|
||||
return mInputView != null && mInputView.hasDistinctMultitouch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates state machine to figure out when to automatically switch back to alpha mode.
|
||||
* Returns true if the keyboard needs to switch back
|
||||
|
|
|
@ -1135,7 +1135,9 @@ public class LatinIME extends InputMethodService
|
|||
LatinImeLogger.logOnDelete();
|
||||
break;
|
||||
case Keyboard.KEYCODE_SHIFT:
|
||||
// Shift key is handled in onPress().
|
||||
// Shift key is handled in onPress() when device has distinct multi-touch panel.
|
||||
if (!mKeyboardSwitcher.hasDistinctMultitouch())
|
||||
handleShift();
|
||||
break;
|
||||
case Keyboard.KEYCODE_CANCEL:
|
||||
if (!isShowingOptionDialog()) {
|
||||
|
@ -1935,7 +1937,7 @@ public class LatinIME extends InputMethodService
|
|||
List<CharSequence> suggestions = mWordToSuggestions.get(selectedWord);
|
||||
// If the first letter of touching is capitalized, make all the suggestions
|
||||
// start with a capital letter.
|
||||
if (Character.isUpperCase((char) touching.word.charAt(0))) {
|
||||
if (Character.isUpperCase(touching.word.charAt(0))) {
|
||||
for (int i = 0; i < suggestions.size(); i++) {
|
||||
String origSugg = (String) suggestions.get(i);
|
||||
String capsSugg = origSugg.toUpperCase().charAt(0)
|
||||
|
@ -2196,7 +2198,7 @@ public class LatinIME extends InputMethodService
|
|||
public void onPress(int primaryCode) {
|
||||
vibrate();
|
||||
playKeyClick(primaryCode);
|
||||
if (primaryCode == Keyboard.KEYCODE_SHIFT) {
|
||||
if (mKeyboardSwitcher.hasDistinctMultitouch() && primaryCode == Keyboard.KEYCODE_SHIFT) {
|
||||
mShiftKeyState.onPress();
|
||||
handleShift();
|
||||
} else if (primaryCode == Keyboard.KEYCODE_MODE_CHANGE) {
|
||||
|
@ -2210,7 +2212,7 @@ public class LatinIME extends InputMethodService
|
|||
// Reset any drag flags in the keyboard
|
||||
((LatinKeyboard) mKeyboardSwitcher.getInputView().getKeyboard()).keyReleased();
|
||||
//vibrate();
|
||||
if (primaryCode == Keyboard.KEYCODE_SHIFT) {
|
||||
if (mKeyboardSwitcher.hasDistinctMultitouch() && primaryCode == Keyboard.KEYCODE_SHIFT) {
|
||||
if (mShiftKeyState.isMomentary())
|
||||
resetShift();
|
||||
mShiftKeyState.onRelease();
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package com.android.inputmethod.latin;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
|
@ -204,6 +205,8 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
|
|||
private final ArrayList<PointerTracker> mPointerTrackers = new ArrayList<PointerTracker>();
|
||||
private final PointerQueue mPointerQueue = new PointerQueue();
|
||||
private final float mDebounceHysteresis;
|
||||
private final boolean mHasDistinctMultitouch;
|
||||
private int mOldPointerCount = 1;
|
||||
|
||||
protected KeyDetector mKeyDetector = new ProximityKeyDetector();
|
||||
|
||||
|
@ -508,6 +511,9 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
|
|||
final boolean ignoreMultitouch = true;
|
||||
mGestureDetector = new GestureDetector(getContext(), listener, null, ignoreMultitouch);
|
||||
mGestureDetector.setIsLongpressEnabled(false);
|
||||
|
||||
mHasDistinctMultitouch = context.getPackageManager()
|
||||
.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT);
|
||||
}
|
||||
|
||||
public void setOnKeyboardActionListener(OnKeyboardActionListener listener) {
|
||||
|
@ -563,6 +569,14 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
|
|||
return mKeyboard;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the device has distinct multi-touch panel.
|
||||
* @return true if the device has distinct multi-touch panel.
|
||||
*/
|
||||
public boolean hasDistinctMultitouch() {
|
||||
return mHasDistinctMultitouch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the state of the shift key of the keyboard, if any.
|
||||
* @param shifted whether or not to enable the state of the shift key
|
||||
|
@ -1090,7 +1104,7 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
|
|||
// Create pointer trackers until we can get 'id+1'-th tracker, if needed.
|
||||
for (int i = pointers.size(); i <= id; i++) {
|
||||
final PointerTracker tracker =
|
||||
new PointerTracker(i, mHandler, mKeyDetector, this);
|
||||
new PointerTracker(i, mHandler, mKeyDetector, this, mHasDistinctMultitouch);
|
||||
if (keys != null)
|
||||
tracker.setKeyboard(keys, mDebounceHysteresis);
|
||||
if (listener != null)
|
||||
|
@ -1107,6 +1121,13 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
|
|||
final int action = me.getActionMasked();
|
||||
final long eventTime = me.getEventTime();
|
||||
|
||||
// TODO: cleanup this code into a multi-touch to single-touch event converter class?
|
||||
// If the device does not have distinct multi-touch support panel, ignore all multi-touch
|
||||
// events except a transition from/to single-touch.
|
||||
if (!mHasDistinctMultitouch && pointerCount > 1 && mOldPointerCount > 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Track the last few movements to look for spurious swipes.
|
||||
mSwipeTracker.addMovement(me);
|
||||
|
||||
|
@ -1138,6 +1159,34 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
|
|||
// Up event will pass through.
|
||||
}
|
||||
|
||||
// TODO: cleanup this code into a multi-touch to single-touch event converter class?
|
||||
// Translate mutli-touch event to single-touch events on the device that has no distinct
|
||||
// multi-touch panel.
|
||||
if (!mHasDistinctMultitouch) {
|
||||
// Use only main (id=0) pointer tracker.
|
||||
PointerTracker tracker = getPointerTracker(0);
|
||||
int index = me.getActionIndex();
|
||||
int x = (int)me.getX(index);
|
||||
int y = (int)me.getY(index);
|
||||
int oldPointerCount = mOldPointerCount;
|
||||
if (pointerCount == 1 && oldPointerCount == 2) {
|
||||
// Multi-touch to single touch transition.
|
||||
// Send a down event for the latest pointer.
|
||||
tracker.onDownEvent(x, y, eventTime);
|
||||
} else if (pointerCount == 2 && oldPointerCount == 1) {
|
||||
// Single-touch to multi-touch transition.
|
||||
// Send an up event for the last pointer.
|
||||
tracker.onUpEvent(tracker.getLastX(), tracker.getLastY(), eventTime);
|
||||
} else if (pointerCount == 1 && oldPointerCount == 1) {
|
||||
tracker.onTouchEvent(action, x, y, eventTime);
|
||||
} else {
|
||||
Log.w(TAG, "Unknown touch panel behavior: pointer count is " + pointerCount
|
||||
+ " (old " + oldPointerCount + ")");
|
||||
}
|
||||
mOldPointerCount = pointerCount;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (action == MotionEvent.ACTION_MOVE) {
|
||||
for (int index = 0; index < pointerCount; index++) {
|
||||
int x = (int)me.getX(index);
|
||||
|
|
|
@ -22,12 +22,13 @@ import com.android.inputmethod.latin.LatinKeyboardBaseView.UIHandler;
|
|||
import android.inputmethodservice.Keyboard;
|
||||
import android.inputmethodservice.Keyboard.Key;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
public class PointerTracker {
|
||||
private static final String TAG = "PointerTracker";
|
||||
private static final boolean DEBUG = false;
|
||||
private static final boolean DEBUG_MOVE = DEBUG && true;
|
||||
private static final boolean DEBUG_MOVE = false;
|
||||
|
||||
public interface UIProxy {
|
||||
public void invalidateKey(Key key);
|
||||
|
@ -51,6 +52,7 @@ public class PointerTracker {
|
|||
private final UIHandler mHandler;
|
||||
private final KeyDetector mKeyDetector;
|
||||
private OnKeyboardActionListener mListener;
|
||||
private final boolean mHasDistinctMultitouch;
|
||||
|
||||
private Key[] mKeys;
|
||||
private int mKeyDebounceThresholdSquared = -1;
|
||||
|
@ -85,13 +87,15 @@ public class PointerTracker {
|
|||
// pressed key
|
||||
private int mPreviousKey = NOT_A_KEY;
|
||||
|
||||
public PointerTracker(int id, UIHandler handler, KeyDetector keyDetector, UIProxy proxy) {
|
||||
public PointerTracker(int id, UIHandler handler, KeyDetector keyDetector, UIProxy proxy,
|
||||
boolean hasDistinctMultitouch) {
|
||||
if (proxy == null || handler == null || keyDetector == null)
|
||||
throw new NullPointerException();
|
||||
mPointerId = id;
|
||||
mProxy = proxy;
|
||||
mHandler = handler;
|
||||
mKeyDetector = keyDetector;
|
||||
mHasDistinctMultitouch = hasDistinctMultitouch;
|
||||
resetMultiTap();
|
||||
}
|
||||
|
||||
|
@ -146,6 +150,25 @@ public class PointerTracker {
|
|||
mKeyAlreadyProcessed = true;
|
||||
}
|
||||
|
||||
public void onTouchEvent(int action, int x, int y, long eventTime) {
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
onMoveEvent(x, y, eventTime);
|
||||
break;
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
onDownEvent(x, y, eventTime);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
onUpEvent(x, y, eventTime);
|
||||
break;
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
onCancelEvent(x, y, eventTime);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void onDownEvent(int x, int y, long eventTime) {
|
||||
int keyIndex = mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
|
||||
mCurrentKey = keyIndex;
|
||||
|
@ -242,7 +265,7 @@ public class PointerTracker {
|
|||
showKeyPreviewAndUpdateKey(NOT_A_KEY);
|
||||
// If we're not on a repeating key (which sends on a DOWN event)
|
||||
if (!wasInKeyRepeat) {
|
||||
detectAndSendKey(mCurrentKey, (int)x, (int)y, eventTime);
|
||||
detectAndSendKey(mCurrentKey, x, y, eventTime);
|
||||
}
|
||||
if (isValidKeyIndex(keyIndex))
|
||||
mProxy.invalidateKey(mKeys[keyIndex]);
|
||||
|
@ -355,7 +378,10 @@ public class PointerTracker {
|
|||
|
||||
private void showKeyPreviewAndUpdateKey(int keyIndex) {
|
||||
updateKey(keyIndex);
|
||||
if (!isModifier())
|
||||
// The modifier key, such as shift key, should not be shown as preview when multi-touch is
|
||||
// supported. On thge other hand, if multi-touch is not supported, the modifier key should
|
||||
// be shown as preview.
|
||||
if (!isModifier() || !mHasDistinctMultitouch)
|
||||
mProxy.showPreview(keyIndex, this);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue