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

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

Issue 759033002: Handle accent keys from physical keyboards. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: addressed review comments and moved common dead-key code to public static method Created 6 years 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 19bcb89d1ecde85d5ac9d5fce66f463b7e10e045..092ffbee345c5ffeb93623e852d05c5e1920f9ca 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,14 @@ 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);
+ }
+
+ 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 +401,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 +427,43 @@ public class AdapterInputConnection extends BaseInputConnection {
return true;
}
}
- mImeAdapter.translateAndSendNativeEvents(event);
+ mImeAdapter.translateAndSendNativeEvents(event, mPendingAccent);
+
+ // 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;
+
+ if ((unicodeChar & KeyCharacterMap.COMBINING_ACCENT) != 0) {
+ pendingAccent = 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;
+ }
+ }
+
+ if (event.getAction() == KeyEvent.ACTION_UP) {
+ // Forget accent after release of key being accented.
+ pendingAccent = NO_ACCENT;
+ }
+ }
+
+ mPendingAccent = pendingAccent;
return true;
}
@@ -448,6 +505,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