Bug 842013 - Buffer IME key events and dispatch them at once; r=cpeterson

This commit is contained in:
Jim Chen 2013-03-29 10:54:01 -04:00
Родитель 45eeb64f4d
Коммит c64e638333
6 изменённых файлов: 40 добавлений и 15 удалений

Просмотреть файл

@ -225,9 +225,7 @@ final class GeckoEditable
break;
case Action.TYPE_REPLACE_TEXT:
// try key events first
if (sendCharKeyEvents(action)) {
break;
}
sendCharKeyEvents(action);
GeckoAppShell.sendEventToGecko(GeckoEvent.createIMEReplaceEvent(
action.mStart, action.mEnd, action.mSequence.toString()));
break;
@ -259,21 +257,19 @@ final class GeckoEditable
return keyEvents;
}
private boolean sendCharKeyEvents(Action action) {
private void sendCharKeyEvents(Action action) {
if (action.mSequence.length() == 0 ||
(action.mSequence instanceof Spannable &&
((Spannable)action.mSequence).nextSpanTransition(
-1, Integer.MAX_VALUE, null) < Integer.MAX_VALUE)) {
// Spans are not preserved when we use key events,
// so we need the sequence to not have any spans
return false;
return;
}
KeyEvent [] keyEvents = synthesizeKeyEvents(action.mSequence);
if (keyEvents == null) {
return false;
return;
}
GeckoAppShell.sendEventToGecko(
GeckoEvent.createIMESelectEvent(action.mStart, action.mEnd));
for (KeyEvent event : keyEvents) {
if (KeyEvent.isModifierKey(event.getKeyCode())) {
continue;
@ -284,12 +280,8 @@ final class GeckoEditable
if (DEBUG) {
Log.d(LOGTAG, "sending: " + event);
}
GeckoAppShell.sendEventToGecko(GeckoEvent.createKeyEvent(event, 0));
GeckoAppShell.sendEventToGecko(GeckoEvent.createIMEKeyEvent(event));
}
// use a IME_SYNCHRONIZE event to mimic a IME_REPLACE_TEXT event
GeckoAppShell.sendEventToGecko(
GeckoEvent.createIMEEvent(GeckoEvent.IME_SYNCHRONIZE));
return true;
}
void poll() {

Просмотреть файл

@ -61,6 +61,7 @@ public class GeckoEvent {
private static final int COMPOSITOR_PAUSE = 29;
private static final int COMPOSITOR_RESUME = 30;
private static final int NATIVE_GESTURE_EVENT = 31;
private static final int IME_KEY_EVENT = 32;
/**
* These DOM_KEY_LOCATION constants mirror the DOM KeyboardEvent's constants.
@ -481,6 +482,12 @@ public class GeckoEvent {
return event;
}
public static GeckoEvent createIMEKeyEvent(KeyEvent k) {
GeckoEvent event = new GeckoEvent(IME_KEY_EVENT);
event.initKeyEvent(k, 0);
return event;
}
public static GeckoEvent createIMEReplaceEvent(int start, int end,
String text) {
GeckoEvent event = new GeckoEvent(IME_EVENT);

Просмотреть файл

@ -517,6 +517,7 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jobject jobj)
break;
case KEY_EVENT:
case IME_KEY_EVENT:
mTime = jenv->GetLongField(jobj, jTimeField);
mMetaState = jenv->GetIntField(jobj, jMetaStateField);
mDomKeyLocation = jenv->GetIntField(jobj, jDomKeyLocationField);

Просмотреть файл

@ -780,10 +780,15 @@ public:
COMPOSITOR_PAUSE = 29,
COMPOSITOR_RESUME = 30,
NATIVE_GESTURE_EVENT = 31,
IME_KEY_EVENT = 32,
dummy_java_enum_list_end
};
enum {
// Internal Gecko events
IME_FLUSH_CHANGES = -2,
IME_UPDATE_CONTEXT = -1,
// Events from Java to Gecko
IME_SYNCHRONIZE = 0,
IME_REPLACE_TEXT = 1,
IME_SET_SELECTION = 2,
@ -791,8 +796,7 @@ public:
IME_UPDATE_COMPOSITION = 4,
IME_REMOVE_COMPOSITION = 5,
IME_ACKNOWLEDGE_FOCUS = 6,
IME_FLUSH_CHANGES = 7,
IME_UPDATE_CONTEXT = 8
dummy_ime_enum_list_end
};
};

Просмотреть файл

@ -876,6 +876,15 @@ nsWindow::OnGlobalAndroidEvent(AndroidGeckoEvent *ae)
}
break;
case AndroidGeckoEvent::IME_KEY_EVENT:
// Keys synthesized by Java IME code are saved in the mIMEKeyEvents
// array until the next IME_REPLACE_TEXT event, at which point
// these keys are dispatched in sequence.
if (win->mFocus) {
win->mFocus->mIMEKeyEvents.AppendElement(*ae);
}
break;
case AndroidGeckoEvent::COMPOSITOR_CREATE:
win->CreateLayerManager(ae->Width(), ae->Height());
break;
@ -1781,6 +1790,17 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *ae)
event.mExpandToClusterBoundary = false;
DispatchEvent(&event);
}
if (!mIMEKeyEvents.IsEmpty()) {
for (uint32_t i = 0; i < mIMEKeyEvents.Length(); i++) {
OnKeyEvent(&mIMEKeyEvents[i]);
}
mIMEKeyEvents.Clear();
FlushIMEChanges();
AndroidBridge::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT);
break;
}
{
nsCompositionEvent event(true, NS_COMPOSITION_START, this);
InitEvent(event, nullptr);

Просмотреть файл

@ -185,6 +185,7 @@ protected:
nsString mIMEComposingText;
nsAutoTArray<nsTextRange, 4> mIMERanges;
bool mIMEUpdatingContext;
nsAutoTArray<mozilla::AndroidGeckoEvent, 8> mIMEKeyEvents;
struct IMEChange {
int32_t mStart, mOldEnd, mNewEnd;