Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Unified Diff: content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java

Issue 373523002: Send correct key-codes when doing composition events instead of always 0. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebased Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
index 73735e0cdd4183676469dc4f4eb327f4af1d42d0..470a0dae53340ec06af5910bf620485c122fcad6 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
@@ -116,6 +116,7 @@ public class ImeAdapter {
static int sModifierCtrl;
static int sModifierCapsLockOn;
static int sModifierNumLockOn;
+ static KeyCharacterMap sKeyCharacterMap;
private long mNativeImeAdapterAndroid;
private InputMethodManagerWrapper mInputMethodManagerWrapper;
@@ -124,6 +125,10 @@ public class ImeAdapter {
private final Handler mHandler;
private DelayedDismissInput mDismissInput = null;
private int mTextInputType;
+ private String mLastComposeText;
+
+ @VisibleForTesting
+ int mLastSyntheticKeyCode;
@VisibleForTesting
boolean mIsShowWithoutHideOutstanding = false;
@@ -317,6 +322,42 @@ public class ImeAdapter {
else return COMPOSITION_KEY_CODE;
}
+ private static int androidKeyCodeForCharacter(char chr) {
+ if (sKeyCharacterMap == null) {
+ sKeyCharacterMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
+ }
+ char[] chars = new char[1];
+ chars[0] = chr;
+ KeyEvent[] events = sKeyCharacterMap.getEvents(chars);
+ return events[0].getKeyCode();
+ }
+
+ @VisibleForTesting
+ public static int getTypedKeycodeGuess(String oldtext, String newtext) {
+ // Starting typing a new composition should add only a single character. Any composition
+ // beginning with text longer than that must come from something other than typing so
+ // return 0.
+ if (oldtext == null) {
+ if (newtext.length() == 1) {
+ return androidKeyCodeForCharacter(newtext.charAt(0));
+ } else {
+ return 0;
+ }
+ }
+
+ // The content has grown in length: assume the last character is the key that caused it.
+ if (newtext.length() > oldtext.length() && newtext.startsWith(oldtext))
+ return androidKeyCodeForCharacter(newtext.charAt(newtext.length() - 1));
+
+ // The content has shrunk in length: assume that backspace was pressed.
+ if (oldtext.length() > newtext.length() && oldtext.startsWith(newtext))
+ return KeyEvent.KEYCODE_DEL;
+
+ // The content is unchanged or has undergone a complex change (i.e. not a simple tail
+ // modification) so return an unknown key-code.
+ return 0;
+ }
+
void sendKeyEventWithKeyCode(int keyCode, int flags) {
long eventTime = SystemClock.uptimeMillis();
translateAndSendNativeEvents(new KeyEvent(eventTime, eventTime,
@@ -346,15 +387,22 @@ public class ImeAdapter {
sendKeyEventWithKeyCode(keyCode,
KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE);
} else {
- nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, sEventTypeRawKeyDown,
- timeStampMs, keyCode, 0);
+ keyCode = getTypedKeycodeGuess(mLastComposeText, textStr);
+ mLastComposeText = textStr;
+ mLastSyntheticKeyCode = keyCode;
+
+ if (keyCode != 0)
+ nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, sEventTypeRawKeyDown,
+ timeStampMs, keyCode, 0);
if (isCommit) {
nativeCommitText(mNativeImeAdapterAndroid, textStr);
+ mLastComposeText = null;
} else {
nativeSetComposingText(mNativeImeAdapterAndroid, text, textStr, newCursorPosition);
}
- nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, sEventTypeKeyUp,
- timeStampMs, keyCode, 0);
+ if (keyCode != 0)
+ nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, sEventTypeKeyUp,
+ timeStampMs, keyCode, 0);
}
return true;
@@ -362,7 +410,18 @@ public class ImeAdapter {
void finishComposingText() {
if (mNativeImeAdapterAndroid == 0) return;
+ /*int keyCode = mLastComposeText != null && mLastComposeText.length() == 1 ?
+ KeyEvent.KEYCODE_DEL : 0;
+ long timeStampMs = SystemClock.uptimeMillis();
+ mLastComposeText = null;
+
+ if (keyCode != 0)
+ nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, sEventTypeRawKeyDown,
+ timeStampMs, keyCode, 0);*/
nativeFinishComposingText(mNativeImeAdapterAndroid);
+ /*if (keyCode != 0)
+ nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, sEventTypeKeyUp,
+ timeStampMs, keyCode, 0);*/
}
boolean translateAndSendNativeEvents(KeyEvent event) {
@@ -408,15 +467,21 @@ public class ImeAdapter {
boolean deleteSurroundingText(int beforeLength, int afterLength) {
mViewEmbedder.onImeEvent(false);
if (mNativeImeAdapterAndroid == 0) return false;
- // Can't send the deletion key code yet because it will delete an extra char at the end.
- // Also the deleteSurroundingText message is not always ordered properly with key event
- // messages yet.
- // TODO(guohui): fix the ordering and send the deletion key code for single-char deletion.
- sendSyntheticKeyEvent(
- sEventTypeRawKeyDown, SystemClock.uptimeMillis(), KeyEvent.KEYCODE_UNKNOWN, 0);
+ int keyCode = beforeLength > 0 && afterLength == 0 ?
+ KeyEvent.KEYCODE_DEL : 0;
+ long timeStampMs = SystemClock.uptimeMillis();
+ mLastSyntheticKeyCode = keyCode;
+
+ // TODO(guohui): The ordering of the following three events is not maintained with the
+ // "delete" message typically arriving before the other two (which do arrive in order).
+ // It is possibly due to the processing of Key messages to begin/end other operations.
+ if (keyCode != 0)
+ nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, sEventTypeRawKeyDown,
guohui 2014/07/11 15:20:09 please see review comments in https://codereview.c
guohui 2014/07/11 19:00:37 just tried your patch locally, it suffered the sam
+ timeStampMs, keyCode, 0);
nativeDeleteSurroundingText(mNativeImeAdapterAndroid, beforeLength, afterLength);
- sendSyntheticKeyEvent(
- sEventTypeKeyUp, SystemClock.uptimeMillis(), KeyEvent.KEYCODE_UNKNOWN, 0);
+ if (keyCode != 0)
+ nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, sEventTypeKeyUp,
+ timeStampMs, keyCode, 0);
return true;
}
@@ -433,14 +498,15 @@ public class ImeAdapter {
}
/**
- * Send a request to the native counterpart to set compositing region to given indices.
+ * Send a request to the native counterpart to set composing region to given indices.
* @param start The start of the composition.
* @param end The end of the composition.
* @return Whether the native counterpart of ImeAdapter received the call.
*/
- boolean setComposingRegion(int start, int end) {
+ boolean setComposingRegion(CharSequence text, int start, int end) {
if (mNativeImeAdapterAndroid == 0) return false;
nativeSetComposingRegion(mNativeImeAdapterAndroid, start, end);
+ mLastComposeText = text != null ? text.toString() : null;
return true;
}
@@ -554,6 +620,7 @@ public class ImeAdapter {
@CalledByNative
private void cancelComposition() {
if (mInputConnection != null) mInputConnection.restartInput();
+ mLastComposeText = null;
}
@CalledByNative

Powered by Google App Engine
This is Rietveld 408576698