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

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

Issue 846053002: Handle accent keys from physical keyboards. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2214
Patch Set: Created 5 years, 11 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
« no previous file with comments | « no previous file | content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/public/android/java/src/org/chromium/content/browser/input/AdapterInputConnection.java
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/AdapterInputConnection.java b/content/public/android/java/src/org/chromium/content/browser/input/AdapterInputConnection.java
index 1eafc6afdaf7464861ff5d3891e1be27fbc9e2b7..972c0824452b2bd85487b71a65fa1cd4d1a55903 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/AdapterInputConnection.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/AdapterInputConnection.java
@@ -10,6 +10,7 @@ import android.text.InputType;
import android.text.Selection;
import android.text.TextUtils;
import android.util.Log;
+import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.BaseInputConnection;
@@ -27,6 +28,7 @@ import org.chromium.base.VisibleForTesting;
public class AdapterInputConnection extends BaseInputConnection {
private static final String TAG = "AdapterInputConnection";
private static final boolean DEBUG = false;
+ private static final int NO_ACCENT = 0;
/**
* Selection value should be -1 if not known. See EditorInfo.java for details.
*/
@@ -39,6 +41,7 @@ public class AdapterInputConnection extends BaseInputConnection {
private boolean mSingleLine;
private int mNumNestedBatchEdits = 0;
+ private int mPendingAccent;
private int mLastUpdateSelectionStart = INVALID_SELECTION;
private int mLastUpdateSelectionEnd = INVALID_SELECTION;
@@ -125,6 +128,16 @@ public class AdapterInputConnection extends BaseInputConnection {
updateSelectionIfRequired();
}
+ public static int maybeAddAccentToCharacter(int accentChar, int unicodeChar) {
+ if (accentChar != NO_ACCENT) {
+ int combinedChar = KeyEvent.getDeadChar(accentChar, unicodeChar);
+ if (combinedChar != 0) {
+ return combinedChar;
+ }
+ }
+ return unicodeChar;
+ }
+
/**
* Updates the AdapterInputConnection's internal representation of the text being edited and
* its selection and composition properties. The resulting Editable is accessible through the
@@ -215,6 +228,8 @@ public class AdapterInputConnection extends BaseInputConnection {
mLastUpdateSelectionEnd = selectionEnd;
mLastUpdateCompositionStart = compositionStart;
mLastUpdateCompositionEnd = compositionEnd;
+ // Change in selection or cursor position invalidates any pending accent.
+ mPendingAccent = NO_ACCENT;
}
/**
@@ -368,6 +383,22 @@ public class AdapterInputConnection extends BaseInputConnection {
if (DEBUG) {
Log.w(TAG, "sendKeyEvent [" + event.getAction() + "] [" + event.getKeyCode() + "]");
}
+
+ // Short-cut modifier keys so they're not affected by accents.
+ if (KeyEvent.isModifierKey(event.getKeyCode())) {
+ return mImeAdapter.translateAndSendNativeEvents(event, NO_ACCENT);
+ }
+
+ // Some keys we just want to pass events straight through. This allows
+ // proper "repeating key" behavior with physical keyboards.
+ int eventKeyCode = event.getKeyCode();
+ if (eventKeyCode == KeyEvent.KEYCODE_DEL || eventKeyCode == KeyEvent.KEYCODE_FORWARD_DEL) {
+ mPendingAccent = 0;
+ return mImeAdapter.translateAndSendNativeEvents(event, NO_ACCENT);
+ }
+
+ int unicodeChar = event.getUnicodeChar();
+
// If this is a key-up, and backspace/del or if the key has a character representation,
// need to update the underlying Editable (i.e. the local representation of the text
// being edited).
@@ -378,26 +409,24 @@ public class AdapterInputConnection extends BaseInputConnection {
} else if (event.getKeyCode() == KeyEvent.KEYCODE_FORWARD_DEL) {
deleteSurroundingText(0, 1);
return true;
- } else {
- int unicodeChar = event.getUnicodeChar();
- if (unicodeChar != 0) {
- int selectionStart = Selection.getSelectionStart(mEditable);
- int selectionEnd = Selection.getSelectionEnd(mEditable);
- if (selectionStart > selectionEnd) {
- int temp = selectionStart;
- selectionStart = selectionEnd;
- selectionEnd = temp;
- }
- mEditable.replace(selectionStart, selectionEnd,
- Character.toString((char) unicodeChar));
+ } else if (unicodeChar != 0) {
+ int selectionStart = Selection.getSelectionStart(mEditable);
+ int selectionEnd = Selection.getSelectionEnd(mEditable);
+ if (selectionStart > selectionEnd) {
+ int temp = selectionStart;
+ selectionStart = selectionEnd;
+ selectionEnd = temp;
}
+ int combinedChar = maybeAddAccentToCharacter(mPendingAccent, unicodeChar);
+ mEditable.replace(selectionStart, selectionEnd,
+ Character.toString((char) combinedChar));
}
} else if (event.getAction() == KeyEvent.ACTION_DOWN) {
// TODO(aurimas): remove this workaround when crbug.com/278584 is fixed.
if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
beginBatchEdit();
finishComposingText();
- mImeAdapter.translateAndSendNativeEvents(event);
+ mImeAdapter.translateAndSendNativeEvents(event, 0);
endBatchEdit();
return true;
} else if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
@@ -406,7 +435,46 @@ public class AdapterInputConnection extends BaseInputConnection {
return true;
}
}
- mImeAdapter.translateAndSendNativeEvents(event);
+
+ // Physical keyboards also have their events come through here though not
+ // by BaseInputConnection. In order to support "accent" key sequences
+ // such as "~n" or "^o" we have to record that one has been pressed
+ // and, if an accentable letter follows, delete the accent glyph and
+ // insert the composed character.
+
+ // Copy class variable to local because class version may get indirectly
+ // cleared by the deleteSurroundingText() call below.
+ int pendingAccent = mPendingAccent;
+ int nextAccent = mPendingAccent;
+
+ if ((unicodeChar & KeyCharacterMap.COMBINING_ACCENT) != 0) {
+ pendingAccent = NO_ACCENT;
+ nextAccent = unicodeChar & KeyCharacterMap.COMBINING_ACCENT_MASK;
+ } else if (pendingAccent != NO_ACCENT) {
+ if (event.getAction() == KeyEvent.ACTION_DOWN) {
+ int combined = KeyEvent.getDeadChar(pendingAccent, unicodeChar);
+ if (combined != 0) {
+ // Previous accent combines with new character to create
+ // a new accented character. First delete the displayed
+ // accent so it appears overwritten by the composition.
+ super.deleteSurroundingText(1, 0);
+ mImeAdapter.deleteSurroundingText(1, 0);
+ } else {
+ // Previous accent doesn't combine with this character
+ // so assume both are completely independent.
+ pendingAccent = NO_ACCENT;
+ nextAccent = NO_ACCENT;
+ }
+ }
+
+ if (event.getAction() == KeyEvent.ACTION_UP) {
+ // Forget accent after release of key being accented.
+ nextAccent = NO_ACCENT;
+ }
+ }
+
+ mImeAdapter.translateAndSendNativeEvents(event, pendingAccent);
+ mPendingAccent = nextAccent;
return true;
}
@@ -448,6 +516,7 @@ public class AdapterInputConnection extends BaseInputConnection {
if (DEBUG) Log.w(TAG, "restartInput");
getInputMethodManagerWrapper().restartInput(mInternalView);
mNumNestedBatchEdits = 0;
+ mPendingAccent = NO_ACCENT;
}
/**
« no previous file with comments | « no previous file | content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698