зеркало из https://github.com/mozilla/pjs.git
Bug 687717 - Send key events rather than committing single-character composition strings. r=blassey r=masayuki a=blocking-fennec
--HG-- extra : rebase_source : 7ddc8b05e7a93917b9a20a665f5c958370d91bb0
This commit is contained in:
Родитель
79273b6638
Коммит
254b7db74e
|
@ -56,6 +56,7 @@ import android.text.style.ForegroundColorSpan;
|
|||
import android.text.style.UnderlineSpan;
|
||||
import android.util.Log;
|
||||
import android.util.LogPrinter;
|
||||
import android.view.KeyCharacterMap;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.BaseInputConnection;
|
||||
|
@ -98,6 +99,8 @@ public class GeckoInputConnection
|
|||
|
||||
// Is a composition active?
|
||||
private int mCompositionStart = NO_COMPOSITION_STRING;
|
||||
private boolean mCommittingText;
|
||||
private KeyCharacterMap mKeyCharacterMap;
|
||||
private Editable mEditable;
|
||||
private Editable.Factory mEditableFactory;
|
||||
private boolean mBatchMode;
|
||||
|
@ -140,7 +143,9 @@ public class GeckoInputConnection
|
|||
|
||||
@Override
|
||||
public boolean commitText(CharSequence text, int newCursorPosition) {
|
||||
mCommittingText = true;
|
||||
replaceText(text, newCursorPosition, false);
|
||||
mCommittingText = false;
|
||||
|
||||
if (hasCompositionString()) {
|
||||
if (DEBUG) Log.d(LOGTAG, ". . . commitText: endComposition");
|
||||
|
@ -564,15 +569,27 @@ public class GeckoInputConnection
|
|||
endComposition();
|
||||
}
|
||||
|
||||
if (count == 1 && s.charAt(start) == '\n') {
|
||||
CharSequence changedText = s.subSequence(start, start + count);
|
||||
if (changedText.length() == 1) {
|
||||
char changedChar = changedText.charAt(0);
|
||||
|
||||
// Some IMEs (e.g. SwiftKey X) send a string with '\n' when Enter is pressed
|
||||
// Such string cannot be handled by Gecko, so we convert it to a key press instead
|
||||
if (DEBUG) Log.d(LOGTAG, ". . . onTextChanged: Typed <Enter>");
|
||||
processKeyDown(KeyEvent.KEYCODE_ENTER, new KeyEvent(KeyEvent.ACTION_DOWN,
|
||||
KeyEvent.KEYCODE_ENTER), false);
|
||||
processKeyUp(KeyEvent.KEYCODE_ENTER, new KeyEvent(KeyEvent.ACTION_UP,
|
||||
KeyEvent.KEYCODE_ENTER), false);
|
||||
return;
|
||||
if (changedChar == '\n') {
|
||||
processKeyDown(KeyEvent.KEYCODE_ENTER, new KeyEvent(KeyEvent.ACTION_DOWN,
|
||||
KeyEvent.KEYCODE_ENTER), false);
|
||||
processKeyUp(KeyEvent.KEYCODE_ENTER, new KeyEvent(KeyEvent.ACTION_UP,
|
||||
KeyEvent.KEYCODE_ENTER), false);
|
||||
return;
|
||||
}
|
||||
|
||||
// If we are committing a single character and didn't have an active composition string,
|
||||
// we can send Gecko keydown/keyup events instead of composition events.
|
||||
if (mCommittingText && !hasCompositionString() && synthesizeKeyEvents(changedChar)) {
|
||||
// Block this thread until all pending events are processed
|
||||
GeckoAppShell.geckoEventSync();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasCompositionString()) {
|
||||
|
@ -590,7 +607,7 @@ public class GeckoInputConnection
|
|||
GeckoEvent.createIMEEvent(GeckoEvent.IME_SET_SELECTION, start, before));
|
||||
}
|
||||
|
||||
sendTextToGecko(s.subSequence(start, start + count), start + count);
|
||||
sendTextToGecko(changedText, start + count);
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, ". . . onTextChanged: IME_SET_SELECTION, start=" + (start + count)
|
||||
|
@ -609,6 +626,40 @@ public class GeckoInputConnection
|
|||
GeckoAppShell.geckoEventSync();
|
||||
}
|
||||
|
||||
private boolean synthesizeKeyEvents(char inputChar) {
|
||||
if (mKeyCharacterMap == null) {
|
||||
mKeyCharacterMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
|
||||
}
|
||||
|
||||
// Synthesize VKB key events that could plausibly generate the input character.
|
||||
char[] inputChars = { inputChar };
|
||||
KeyEvent[] events = mKeyCharacterMap.getEvents(inputChars);
|
||||
if (events == null) {
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "synthesizeKeyEvents: char '" + inputChar
|
||||
+ "' has no virtual key mapping");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean sentKeyEvents = false;
|
||||
|
||||
for (KeyEvent event : events) {
|
||||
if (!KeyEvent.isModifierKey(event.getKeyCode())) {
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "synthesizeKeyEvents: char '" + inputChar
|
||||
+ "' -> action=" + event.getAction()
|
||||
+ ", keyCode=" + event.getKeyCode()
|
||||
+ ", UnicodeChar='" + (char) event.getUnicodeChar() + "'");
|
||||
}
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createKeyEvent(event));
|
||||
sentKeyEvents = true;
|
||||
}
|
||||
}
|
||||
|
||||
return sentKeyEvents;
|
||||
}
|
||||
|
||||
private void endComposition() {
|
||||
if (DEBUG) Log.d(LOGTAG, "IME: endComposition: IME_COMPOSITION_END");
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
|
|
Загрузка…
Ссылка в новой задаче