Bug 1511752 - Make IMContextWrapper::OnKeyEvent() treat GDK_KEY_PRESS event without any key information in a dead key sequence as synthesized by current keyboard layout for asynchronous handling r=m_kato

Some keyboard layouts which have dead keys may handle dead key composition
asynchronously.  In this case, they don't rely on IME like iBus/Fcitx.

As far as I've tested, German (QWERTY) keyboard layout is one of such
keyboard layout.  This returns true when gtk_im_context_filter_keypress()
is called for a base character input (like "a").  Then, it synthesizes
GDK_KEY_PRESS event without any key information such as:
> { type=GDK_KEY_PRESS, keyval=(null), unicode=0x0, state=, time=0,
>   hardware_keycode=0, group=0 }
So, this is not marked as IBUS_IGNORED_MASK nor FcitxKeyState_IgnoredMask
by IME, but we should ignore this event since we should've already dispatched
"keydown" event for the preceding "a" key event, and anyway "keydown" event
for the synthesized event does not make sense for any web apps.

This patch makes IMContextWrapper::OnKeyEvent() ignore such key event, i.e.,
when it's in a dead key sequence, and GDK_KEY_PRESS does not have enough
information, e.g., hardware_keycode shouldn't be 0 especially for printable
keys.  Therefore, this patch make it check only hardware_keycode value and
gdk_keyval_to_unicode(aEvent->keyval) value.

If some keyboard layouts would send the original key event as is, we would
need to do more, but currently, this is enough and safe to land this timing.

Differential Revision: https://phabricator.services.mozilla.com/D13656

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Masayuki Nakano 2018-12-03 15:15:13 +00:00
parent 194724b389
commit 2406aed7f3

View File

@ -842,8 +842,19 @@ KeyHandlingState IMContextWrapper::OnKeyEvent(
// ibus won't send back key press events in a dead key sequcne.
if (mMaybeInDeadKeySequence && aEvent->type == GDK_KEY_PRESS) {
maybeHandledAsynchronously = false;
isUnexpectedAsyncEvent = isHandlingAsyncEvent;
break;
if (isHandlingAsyncEvent) {
isUnexpectedAsyncEvent = true;
break;
}
// Some keyboard layouts which have dead keys may send
// "empty" key event to make us call
// gtk_im_context_filter_keypress() to commit composed
// character during a GDK_KEY_PRESS event dispatching.
if (!gdk_keyval_to_unicode(aEvent->keyval) &&
!aEvent->hardware_keycode) {
isUnexpectedAsyncEvent = true;
break;
}
}
// ibus handles key events synchronously if focused editor is
// <input type="password"> or |ime-mode: disabled;|.
@ -878,8 +889,19 @@ KeyHandlingState IMContextWrapper::OnKeyEvent(
// fcitx won't send back key press events in a dead key sequcne.
if (mMaybeInDeadKeySequence && aEvent->type == GDK_KEY_PRESS) {
maybeHandledAsynchronously = false;
isUnexpectedAsyncEvent = isHandlingAsyncEvent;
break;
if (isHandlingAsyncEvent) {
isUnexpectedAsyncEvent = true;
break;
}
// Some keyboard layouts which have dead keys may send
// "empty" key event to make us call
// gtk_im_context_filter_keypress() to commit composed
// character during a GDK_KEY_PRESS event dispatching.
if (!gdk_keyval_to_unicode(aEvent->keyval) &&
!aEvent->hardware_keycode) {
isUnexpectedAsyncEvent = true;
break;
}
}
// fcitx handles key events asynchronously even if focused