Bug 1300003 part.5 Remove odd WM_CHAR messages which are caused by ATOK or WXG (both of them are Japanese IME) r=m_kato
NativeKey removes odd WM_CHAR messages which are caused by ATOK or WXG if the user tries to do "Kakutei-Undo" (meaning "undo the last commit") after dispatching eKeyDown event. However, NativeKey should remove them from the queue first because there are some problems: * If focus is moved during dispatching an eKeyDown event, we'll fail to remove the messages from the queue. * If dispatching eKeyDown advance native event loop due to entering to a modal loop or dosing synchronous XHR, the message pattern is broken before removing the odd messages from the queue. After removing the odd char messages, NativeKey should store them with mRemovedOddCharMsgs because NativeKey needs to dispatch them to focused windowless plugin. Note that this patch also fixes a bug of the loop to remove the odd WM_CHAR messages. Old code removes only one WM_CHAR messages, but we need to remove all WM_CHAR messages before WM_KEYUP. This must be a regression. MozReview-Commit-ID: I60bcIx2SFS
This commit is contained in:
@@ -1112,6 +1112,8 @@ NativeKey::NativeKey(nsWindowBase* aWidget,
|
||||
mCommittedCharsAndModifiers.Append(ch, mModKeyState.GetModifiers());
|
||||
}
|
||||
}
|
||||
// Remove odd char messages if there are.
|
||||
RemoveFollowingOddCharMessages();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1281,6 +1283,47 @@ NativeKey::IsIMEDoingKakuteiUndo() const
|
||||
compositionMsg.time <= charMsg.time;
|
||||
}
|
||||
|
||||
void
|
||||
NativeKey::RemoveFollowingOddCharMessages()
|
||||
{
|
||||
MOZ_ASSERT(IsKeyDownMessage());
|
||||
|
||||
// If the keydown message is synthesized for automated tests, there is
|
||||
// nothing to do here.
|
||||
if (mFakeCharMsgs) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If there are some following char messages before another key message,
|
||||
// there is nothing to do here.
|
||||
if (!mFollowingCharMsgs.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the handling key isn't Backspace, there is nothing to do here.
|
||||
if (mOriginalVirtualKeyCode != VK_BACK) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we don't see the odd message pattern, there is nothing to do here.
|
||||
if (!IsIMEDoingKakuteiUndo()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, we need to remove odd WM_CHAR messages for ATOK or WXG (both
|
||||
// of them are Japanese IME).
|
||||
MSG msg;
|
||||
while (WinUtils::PeekMessage(&msg, mMsg.hwnd, WM_CHAR, WM_CHAR,
|
||||
PM_REMOVE | PM_NOYIELD)) {
|
||||
if (msg.message != WM_CHAR) {
|
||||
MOZ_RELEASE_ASSERT(msg.message == WM_NULL,
|
||||
"Unexpected message was removed");
|
||||
continue;
|
||||
}
|
||||
mRemovedOddCharMsgs.AppendElement(msg);
|
||||
}
|
||||
}
|
||||
|
||||
UINT
|
||||
NativeKey::GetScanCodeWithExtendedFlag() const
|
||||
{
|
||||
@@ -2350,9 +2393,7 @@ NativeKey::DispatchPluginEventsAndDiscardsCharMessages() const
|
||||
MOZ_ASSERT(IsKeyDownMessage());
|
||||
MOZ_ASSERT(!IsKeyMessageOnPlugin());
|
||||
|
||||
bool anyCharMessagesRemoved = false;
|
||||
for (size_t i = 0; i < mFollowingCharMsgs.Length(); ++i) {
|
||||
anyCharMessagesRemoved = true;
|
||||
MOZ_RELEASE_ASSERT(!mWidget->Destroyed(),
|
||||
"NativeKey tries to dispatch a plugin event on destroyed widget");
|
||||
mWidget->DispatchPluginEvent(mFollowingCharMsgs[i]);
|
||||
@@ -2361,23 +2402,15 @@ NativeKey::DispatchPluginEventsAndDiscardsCharMessages() const
|
||||
}
|
||||
}
|
||||
|
||||
if (!mFakeCharMsgs && !anyCharMessagesRemoved &&
|
||||
mDOMKeyCode == NS_VK_BACK && IsIMEDoingKakuteiUndo()) {
|
||||
// This is for a hack for ATOK and WXG. So, PeekMessage() must scceed!
|
||||
MSG msg;
|
||||
while (WinUtils::PeekMessage(&msg, mMsg.hwnd, WM_CHAR, WM_CHAR,
|
||||
PM_REMOVE | PM_NOYIELD)) {
|
||||
if (msg.message != WM_CHAR) {
|
||||
MOZ_RELEASE_ASSERT(msg.message == WM_NULL,
|
||||
"Unexpected message was removed");
|
||||
continue;
|
||||
}
|
||||
MOZ_RELEASE_ASSERT(!mWidget->Destroyed(),
|
||||
"NativeKey tries to dispatch a plugin event on destroyed widget");
|
||||
mWidget->DispatchPluginEvent(msg);
|
||||
return mWidget->Destroyed();
|
||||
// Dispatch odd char messages which are caused by ATOK or WXG (both of them
|
||||
// are Japanese IME) and removed by RemoveFollowingOddCharMessages().
|
||||
for (size_t i = 0; i < mRemovedOddCharMsgs.Length(); ++i) {
|
||||
MOZ_RELEASE_ASSERT(!mWidget->Destroyed(),
|
||||
"NativeKey tries to dispatch a plugin event on destroyed widget");
|
||||
mWidget->DispatchPluginEvent(mRemovedOddCharMsgs[i]);
|
||||
if (mWidget->Destroyed() || IsFocusedWindowChanged()) {
|
||||
return true;
|
||||
}
|
||||
MOZ_CRASH("NativeKey failed to get WM_CHAR for ATOK or WXG");
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user