Fix inconsistency between pop-up preview key and input key
This issue is caused by three reasons. - In touch move event and while time debouncing is going on, wrong key is shown as pop-up preview. - There is no pop-up preview key shown when touch up event occurs and also showing pop-up preview message is unintentionally canceled. - In detectAndSendKey() method, nearby keys' primary codes are mistakenly sent as Key codes. This is the last of three changes to fix bug #2868304 Bug: 2868304 Change-Id: Ie482167b2ae2804fa1aa43ffb5067af47b7553f1main
parent
d0f4413f95
commit
820e4260cd
|
@ -197,7 +197,6 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
|
|
||||||
private KeyDebouncer mDebouncer;
|
private KeyDebouncer mDebouncer;
|
||||||
|
|
||||||
private int[] mKeyIndices = new int[12];
|
|
||||||
private GestureDetector mGestureDetector;
|
private GestureDetector mGestureDetector;
|
||||||
private int mPopupX;
|
private int mPopupX;
|
||||||
private int mPopupY;
|
private int mPopupY;
|
||||||
|
@ -273,6 +272,7 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
}
|
}
|
||||||
|
|
||||||
public void popupPreview(int keyIndex, long delay) {
|
public void popupPreview(int keyIndex, long delay) {
|
||||||
|
removeMessages(MSG_POPUP_PREVIEW);
|
||||||
sendMessageDelayed(obtainMessage(MSG_POPUP_PREVIEW, keyIndex, 0), delay);
|
sendMessageDelayed(obtainMessage(MSG_POPUP_PREVIEW, keyIndex, 0), delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -911,12 +911,12 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
mDirtyRect.setEmpty();
|
mDirtyRect.setEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getKeyIndices(int x, int y, int[] allKeys) {
|
private int getKeyIndexAndNearbyCodes(int x, int y, int[] allKeys) {
|
||||||
final Key[] keys = mKeys;
|
final Key[] keys = mKeys;
|
||||||
int primaryIndex = NOT_A_KEY;
|
int primaryIndex = NOT_A_KEY;
|
||||||
int closestKey = NOT_A_KEY;
|
int closestKey = NOT_A_KEY;
|
||||||
int closestKeyDist = mProximityThreshold + 1;
|
int closestKeyDist = mProximityThreshold + 1;
|
||||||
java.util.Arrays.fill(mDistances, Integer.MAX_VALUE);
|
Arrays.fill(mDistances, Integer.MAX_VALUE);
|
||||||
int [] nearestKeyIndices = mKeyboard.getNearestKeys(x, y);
|
int [] nearestKeyIndices = mKeyboard.getNearestKeys(x, y);
|
||||||
final int keyCount = nearestKeyIndices.length;
|
final int keyCount = nearestKeyIndices.length;
|
||||||
for (int i = 0; i < keyCount; i++) {
|
for (int i = 0; i < keyCount; i++) {
|
||||||
|
@ -947,10 +947,8 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
mDistances.length - j - nCodes);
|
mDistances.length - j - nCodes);
|
||||||
System.arraycopy(allKeys, j, allKeys, j + nCodes,
|
System.arraycopy(allKeys, j, allKeys, j + nCodes,
|
||||||
allKeys.length - j - nCodes);
|
allKeys.length - j - nCodes);
|
||||||
for (int c = 0; c < nCodes; c++) {
|
System.arraycopy(key.codes, 0, allKeys, j, nCodes);
|
||||||
allKeys[j + c] = key.codes[c];
|
Arrays.fill(mDistances, j, j + nCodes, dist);
|
||||||
mDistances[j + c] = dist;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -973,7 +971,7 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
//TextEntryState.keyPressedAt(key, x, y);
|
//TextEntryState.keyPressedAt(key, x, y);
|
||||||
int[] codes = new int[MAX_NEARBY_KEYS];
|
int[] codes = new int[MAX_NEARBY_KEYS];
|
||||||
Arrays.fill(codes, NOT_A_KEY);
|
Arrays.fill(codes, NOT_A_KEY);
|
||||||
getKeyIndices(x, y, codes);
|
getKeyIndexAndNearbyCodes(x, y, codes);
|
||||||
// Multi-tap
|
// Multi-tap
|
||||||
if (mInMultiTap) {
|
if (mInMultiTap) {
|
||||||
if (mTapCount != -1) {
|
if (mTapCount != -1) {
|
||||||
|
@ -983,6 +981,15 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
}
|
}
|
||||||
code = key.codes[mTapCount];
|
code = key.codes[mTapCount];
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Swap the first and second values in the codes array if the primary code is not
|
||||||
|
* the first value but the second value in the array. This happens when key
|
||||||
|
* debouncing is in effect.
|
||||||
|
*/
|
||||||
|
if (codes.length >= 2 && codes[0] != code && codes[1] == code) {
|
||||||
|
codes[1] = codes[0];
|
||||||
|
codes[0] = code;
|
||||||
|
}
|
||||||
mKeyboardActionListener.onKey(code, codes);
|
mKeyboardActionListener.onKey(code, codes);
|
||||||
mKeyboardActionListener.onRelease(code);
|
mKeyboardActionListener.onRelease(code);
|
||||||
}
|
}
|
||||||
|
@ -1024,13 +1031,12 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
}
|
}
|
||||||
// If key changed and preview is on ...
|
// If key changed and preview is on ...
|
||||||
if (oldKeyIndex != mCurrentKeyIndex && mShowPreview) {
|
if (oldKeyIndex != mCurrentKeyIndex && mShowPreview) {
|
||||||
|
if (keyIndex == NOT_A_KEY) {
|
||||||
mHandler.cancelPopupPreview();
|
mHandler.cancelPopupPreview();
|
||||||
if (previewPopup.isShowing()) {
|
if (previewPopup.isShowing()) {
|
||||||
if (keyIndex == NOT_A_KEY) {
|
|
||||||
mHandler.dismissPreview(DELAY_AFTER_PREVIEW);
|
mHandler.dismissPreview(DELAY_AFTER_PREVIEW);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
if (keyIndex != NOT_A_KEY) {
|
|
||||||
if (previewPopup.isShowing() && mPreviewText.getVisibility() == VISIBLE) {
|
if (previewPopup.isShowing() && mPreviewText.getVisibility() == VISIBLE) {
|
||||||
// Show right away, if it's already visible and finger is moving around
|
// Show right away, if it's already visible and finger is moving around
|
||||||
showKey(keyIndex);
|
showKey(keyIndex);
|
||||||
|
@ -1303,7 +1309,7 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
int touchY = (int) me.getY() + mVerticalCorrection - getPaddingTop();
|
int touchY = (int) me.getY() + mVerticalCorrection - getPaddingTop();
|
||||||
final int action = me.getAction();
|
final int action = me.getAction();
|
||||||
final long eventTime = me.getEventTime();
|
final long eventTime = me.getEventTime();
|
||||||
int keyIndex = getKeyIndices(touchX, touchY, null);
|
int keyIndex = getKeyIndexAndNearbyCodes(touchX, touchY, null);
|
||||||
mPossiblePoly = possiblePoly;
|
mPossiblePoly = possiblePoly;
|
||||||
|
|
||||||
// Track the last few movements to look for spurious swipes.
|
// Track the last few movements to look for spurious swipes.
|
||||||
|
@ -1381,12 +1387,19 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
mHandler.startLongPressTimer(me, LONGPRESS_TIMEOUT);
|
mHandler.startLongPressTimer(me, LONGPRESS_TIMEOUT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
showPreview(mCurrentKey);
|
/*
|
||||||
|
* While time debouncing is in effect, mCurrentKey holds the new key and mDebouncer
|
||||||
|
* holds the last key. At ACTION_UP event if time debouncing will be in effect
|
||||||
|
* eventually, the last key should be send as the result. For that situation
|
||||||
|
* mCurrentKey should not be showed as popup preview.
|
||||||
|
*/
|
||||||
|
showPreview(mDebouncer.isMinorTimeBounce() ? mDebouncer.getLastKey() : mCurrentKey);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MotionEvent.ACTION_UP:
|
case MotionEvent.ACTION_UP:
|
||||||
mHandler.cancelKeyTimersAndPopupPreview();
|
mHandler.cancelKeyTimersAndPopupPreview();
|
||||||
if (keyIndex == mCurrentKey) {
|
if (mDebouncer.isMinorMoveBounce(touchX, touchY, mKeys[keyIndex],
|
||||||
|
mKeys[mCurrentKey])) {
|
||||||
mDebouncer.updateTimeDebouncing(eventTime);
|
mDebouncer.updateTimeDebouncing(eventTime);
|
||||||
} else {
|
} else {
|
||||||
resetMultiTap();
|
resetMultiTap();
|
||||||
|
@ -1399,7 +1412,6 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
touchY = mDebouncer.getLastCodeY();
|
touchY = mDebouncer.getLastCodeY();
|
||||||
}
|
}
|
||||||
showPreview(NOT_A_KEY);
|
showPreview(NOT_A_KEY);
|
||||||
Arrays.fill(mKeyIndices, NOT_A_KEY);
|
|
||||||
// If we're not on a repeating key (which sends on a DOWN event)
|
// If we're not on a repeating key (which sends on a DOWN event)
|
||||||
if (mRepeatKeyIndex == NOT_A_KEY && !mMiniKeyboardOnScreen && !mAbortKey) {
|
if (mRepeatKeyIndex == NOT_A_KEY && !mMiniKeyboardOnScreen && !mAbortKey) {
|
||||||
detectAndSendKey(mCurrentKey, touchX, touchY, eventTime);
|
detectAndSendKey(mCurrentKey, touchX, touchY, eventTime);
|
||||||
|
@ -1407,6 +1419,7 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
|
||||||
invalidateKey(keyIndex);
|
invalidateKey(keyIndex);
|
||||||
mRepeatKeyIndex = NOT_A_KEY;
|
mRepeatKeyIndex = NOT_A_KEY;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MotionEvent.ACTION_CANCEL:
|
case MotionEvent.ACTION_CANCEL:
|
||||||
mHandler.cancelKeyTimersAndPopupPreview();
|
mHandler.cancelKeyTimersAndPopupPreview();
|
||||||
dismissPopupKeyboard();
|
dismissPopupKeyboard();
|
||||||
|
|
Loading…
Reference in New Issue