mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-24 21:58:06 +00:00
Bug 466487 ATOK (Japanese IME) fails to eat key message r=jimm
This commit is contained in:
parent
af4be9fe4f
commit
ef41c4154d
@ -42,6 +42,7 @@
|
||||
#include "nsThreadUtils.h"
|
||||
#include "WinTaskbar.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIMM32Handler.h"
|
||||
|
||||
// For skidmark code
|
||||
#include <windows.h>
|
||||
@ -81,7 +82,7 @@ static BOOL PeekKeyAndIMEMessage(LPMSG msg, HWND hwnd)
|
||||
MSG msg1, msg2, *lpMsg;
|
||||
BOOL b1, b2;
|
||||
b1 = ::PeekMessageW(&msg1, NULL, WM_KEYFIRST, WM_IME_KEYLAST, PM_NOREMOVE);
|
||||
b2 = ::PeekMessageW(&msg2, NULL, WM_IME_SETCONTEXT, WM_IME_KEYUP, PM_NOREMOVE);
|
||||
b2 = ::PeekMessageW(&msg2, NULL, NS_WM_IMEFIRST, NS_WM_IMELAST, PM_NOREMOVE);
|
||||
if (b1 || b2) {
|
||||
if (b1 && b2) {
|
||||
if (msg1.time < msg2.time)
|
||||
@ -92,6 +93,9 @@ static BOOL PeekKeyAndIMEMessage(LPMSG msg, HWND hwnd)
|
||||
lpMsg = &msg1;
|
||||
else
|
||||
lpMsg = &msg2;
|
||||
if (!nsIMM32Handler::CanOptimizeKeyAndIMEMessages(lpMsg)) {
|
||||
return false;
|
||||
}
|
||||
return ::PeekMessageW(msg, hwnd, lpMsg->message, lpMsg->message, PM_REMOVE);
|
||||
}
|
||||
|
||||
|
@ -90,6 +90,8 @@ static UINT sWM_MSIME_MOUSE = 0; // mouse message for MSIME 98/2000
|
||||
|
||||
PRPackedBool nsIMM32Handler::sIsComposingOnPlugin = PR_FALSE;
|
||||
PRPackedBool nsIMM32Handler::sIsStatusChanged = PR_FALSE;
|
||||
PRPackedBool nsIMM32Handler::sIsIME = PR_TRUE;
|
||||
PRPackedBool nsIMM32Handler::sIsIMEOpening = PR_FALSE;
|
||||
|
||||
#ifndef WINCE
|
||||
UINT nsIMM32Handler::sCodePage = 0;
|
||||
@ -196,9 +198,10 @@ nsIMM32Handler::InitKeyboardLayout(HKL aKeyboardLayout)
|
||||
LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
|
||||
(PWSTR)&sCodePage, sizeof(sCodePage) / sizeof(WCHAR));
|
||||
sIMEProperty = ::ImmGetProperty(aKeyboardLayout, IGP_PROPERTY);
|
||||
sIsIME = ::ImmIsIME(aKeyboardLayout);
|
||||
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||
("IMM32: InitKeyboardLayout, aKeyboardLayout=%08x, sCodePage=%lu, sIMEProperty=%08x\n",
|
||||
aKeyboardLayout, sCodePage, sIMEProperty));
|
||||
("IMM32: InitKeyboardLayout, aKeyboardLayout=%08x, sCodePage=%lu, sIMEProperty=%08x sIsIME=%s\n",
|
||||
aKeyboardLayout, sCodePage, sIMEProperty, sIsIME ? "TRUE" : "FALSE"));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -212,6 +215,21 @@ nsIMM32Handler::GetKeyboardCodePage()
|
||||
#endif
|
||||
}
|
||||
|
||||
/* static */ PRBool
|
||||
nsIMM32Handler::CanOptimizeKeyAndIMEMessages(MSG *aNextKeyOrIMEMessage)
|
||||
{
|
||||
#ifdef WINCE
|
||||
return PR_TRUE;
|
||||
#else
|
||||
// If IME is opening right now, we shouldn't optimize the key and IME message
|
||||
// order because ATOK (Japanese IME of third party) has some problem with the
|
||||
// optimization. When it finishes opening completely, it eats all key
|
||||
// messages in the message queue. And it causes starting composition. So,
|
||||
// we shouldn't eat the key messages before ATOK.
|
||||
return !sIsIMEOpening;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// used for checking the lParam of WM_IME_COMPOSITION
|
||||
#define IS_COMPOSING_LPARAM(lParam) \
|
||||
@ -273,6 +291,21 @@ nsIMM32Handler::ProcessMessage(nsWindow* aWindow, UINT msg,
|
||||
// if the new window handle is not focused, probably, we should not start
|
||||
// the composition, however, such case should not be, it's just bad scenario.
|
||||
|
||||
if (sIsIMEOpening) {
|
||||
switch (msg) {
|
||||
case WM_INPUTLANGCHANGE:
|
||||
case WM_IME_STARTCOMPOSITION:
|
||||
case WM_IME_COMPOSITION:
|
||||
case WM_IME_ENDCOMPOSITION:
|
||||
case WM_IME_CHAR:
|
||||
case WM_IME_SELECT:
|
||||
case WM_IME_SETCONTEXT:
|
||||
// For safety, we should reset sIsIMEOpening when we receive unexpected
|
||||
// message.
|
||||
sIsIMEOpening = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (aWindow->PluginHasFocus()) {
|
||||
return ProcessMessageForPlugin(aWindow, msg, wParam, lParam, aRetValue,
|
||||
aEatMessage);
|
||||
@ -337,6 +370,8 @@ nsIMM32Handler::ProcessMessage(nsWindow* aWindow, UINT msg,
|
||||
case WM_IME_SETCONTEXT:
|
||||
aEatMessage = OnIMESetContext(aWindow, wParam, lParam);
|
||||
return PR_TRUE;
|
||||
case WM_KEYDOWN:
|
||||
return OnKeyDownEvent(aWindow, wParam, lParam, aEatMessage);
|
||||
default:
|
||||
return PR_FALSE;
|
||||
};
|
||||
@ -365,6 +400,20 @@ nsIMM32Handler::ProcessMessageForPlugin(nsWindow* aWindow, UINT msg,
|
||||
case WM_IME_ENDCOMPOSITION:
|
||||
sIsComposingOnPlugin = PR_FALSE;
|
||||
return PR_FALSE;
|
||||
case WM_IME_NOTIFY:
|
||||
if (wParam == IMN_SETOPENSTATUS) {
|
||||
// finished being opening
|
||||
sIsIMEOpening = PR_FALSE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
case WM_KEYDOWN:
|
||||
if (wParam == VK_PROCESSKEY) {
|
||||
// If we receive when IME isn't open, it means IME is opening right now.
|
||||
nsIMEContext IMEContext(aWindow->GetWindowHandle());
|
||||
sIsIMEOpening = IMEContext.IsValid() &&
|
||||
::ImmGetOpenStatus(IMEContext.get());
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
@ -543,6 +592,7 @@ nsIMM32Handler::OnIMENotify(nsWindow* aWindow,
|
||||
aWindow->GetWindowHandle()));
|
||||
break;
|
||||
case IMN_SETOPENSTATUS:
|
||||
sIsIMEOpening = PR_FALSE;
|
||||
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||
("IMM32: OnIMENotify, hWnd=%08x, IMN_SETOPENSTATUS\n",
|
||||
aWindow->GetWindowHandle()));
|
||||
@ -1675,3 +1725,25 @@ nsIMM32Handler::OnMouseEvent(nsWindow* aWindow, LPARAM lParam, int aAction)
|
||||
}
|
||||
|
||||
#endif // ENABLE_IME_MOUSE_HANDLING
|
||||
|
||||
/* static */ PRBool
|
||||
nsIMM32Handler::OnKeyDownEvent(nsWindow* aWindow, WPARAM wParam, LPARAM lParam,
|
||||
PRBool &aEatMessage)
|
||||
{
|
||||
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||
("IMM32: OnKeyDownEvent, hWnd=%08x, wParam=%08x, lParam=%08x\n",
|
||||
aWindow->GetWindowHandle(), wParam, lParam));
|
||||
aEatMessage = PR_FALSE;
|
||||
switch (wParam) {
|
||||
case VK_PROCESSKEY:
|
||||
// If we receive when IME isn't open, it means IME is opening right now.
|
||||
if (sIsIME) {
|
||||
nsIMEContext IMEContext(aWindow->GetWindowHandle());
|
||||
sIsIMEOpening =
|
||||
IMEContext.IsValid() && !::ImmGetOpenStatus(IMEContext.get());
|
||||
}
|
||||
return PR_FALSE;
|
||||
default:
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -61,6 +61,9 @@ struct nsIntRect;
|
||||
#define ENABLE_IME_MOUSE_HANDLING 1
|
||||
#endif // WINCE
|
||||
|
||||
#define NS_WM_IMEFIRST WM_IME_SETCONTEXT
|
||||
#define NS_WM_IMELAST WM_IME_KEYUP
|
||||
|
||||
class nsIMEContext
|
||||
{
|
||||
public:
|
||||
@ -123,6 +126,8 @@ public:
|
||||
|
||||
static void NotifyEndStatusChange() { sIsStatusChanged = PR_FALSE; }
|
||||
|
||||
static PRBool CanOptimizeKeyAndIMEMessages(MSG *aNextKeyOrIMEMessage);
|
||||
|
||||
protected:
|
||||
static void EnsureHandlerInstance();
|
||||
|
||||
@ -138,6 +143,14 @@ protected:
|
||||
nsIMM32Handler();
|
||||
~nsIMM32Handler();
|
||||
|
||||
// The result of following On*Event methods means "The message was processed,
|
||||
// don't process the message in the caller (nsWindow)".
|
||||
#ifdef ENABLE_IME_MOUSE_HANDLING
|
||||
PRBool OnMouseEvent(nsWindow* aWindow, LPARAM lParam, int aAction);
|
||||
#endif // ENABLE_IME_MOUSE_HANDLING
|
||||
static PRBool OnKeyDownEvent(nsWindow* aWindow, WPARAM wParam, LPARAM lParam,
|
||||
PRBool &aEatMessage);
|
||||
|
||||
// The result of On* methods mean "eat this message" when it's TRUE.
|
||||
PRBool OnIMEStartComposition(nsWindow* aWindow);
|
||||
PRBool OnIMEComposition(nsWindow* aWindow, WPARAM wParam, LPARAM lParam);
|
||||
@ -229,16 +242,13 @@ protected:
|
||||
|
||||
static PRPackedBool sIsComposingOnPlugin;
|
||||
static PRPackedBool sIsStatusChanged;
|
||||
static PRPackedBool sIsIME;
|
||||
static PRPackedBool sIsIMEOpening;
|
||||
|
||||
#ifndef WINCE
|
||||
static UINT sCodePage;
|
||||
static DWORD sIMEProperty;
|
||||
#endif // #ifndef WINCE
|
||||
|
||||
#ifdef ENABLE_IME_MOUSE_HANDLING
|
||||
PRBool OnMouseEvent(nsWindow* aWindow, LPARAM lParam, int aAction);
|
||||
#endif // ENABLE_IME_MOUSE_HANDLING
|
||||
|
||||
};
|
||||
|
||||
#endif // nsIMM32Handler_h__
|
||||
|
Loading…
x
Reference in New Issue
Block a user