Bug 840409 part.11 Implement nsIMEContext::AssociateDefaultContext() and nsIMEContext::Disassociate() r=jimm

This commit is contained in:
Masayuki Nakano 2013-02-25 13:00:06 +09:00
parent 2ee4532858
commit b2cf4616f0
5 changed files with 52 additions and 47 deletions

View File

@ -196,6 +196,14 @@ IMEHandler::GetOpenState(nsWindow* aWindow)
return IMEContext.GetOpenState();
}
// static
void
IMEHandler::OnDestroyWindow(nsWindow* aWindow)
{
nsIMEContext IMEContext(aWindow->GetWindowHandle());
IMEContext.AssociateDefaultContext();
}
#ifdef DEBUG
// static
bool

View File

@ -73,6 +73,11 @@ public:
static void SetOpenState(nsWindow* aWindow, bool aOpen);
static bool GetOpenState(nsWindow* aWindow);
/**
* Called when the window is destroying.
*/
static void OnDestroyWindow(nsWindow* aWindow);
/**
* "Kakutei-Undo" of ATOK or WXG (both of them are Japanese IME) causes
* strange WM_KEYDOWN/WM_KEYUP/WM_CHAR message pattern. So, when this

View File

@ -214,19 +214,19 @@ nsIMM32Handler::CommitComposition(nsWindow* aWindow, bool aForce)
return;
}
bool associated = aWindow->AssociateDefaultIMC(true);
nsIMEContext IMEContext(aWindow->GetWindowHandle());
bool associated = IMEContext.AssociateDefaultContext();
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
("IMM32: CommitComposition, associated=%s\n",
associated ? "YES" : "NO"));
nsIMEContext IMEContext(aWindow->GetWindowHandle());
if (IMEContext.IsValid()) {
::ImmNotifyIME(IMEContext.get(), NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
::ImmNotifyIME(IMEContext.get(), NI_COMPOSITIONSTR, CPS_CANCEL, 0);
}
if (associated) {
aWindow->AssociateDefaultIMC(false);
IMEContext.Disassociate();
}
}
@ -245,18 +245,18 @@ nsIMM32Handler::CancelComposition(nsWindow* aWindow, bool aForce)
return;
}
bool associated = aWindow->AssociateDefaultIMC(true);
nsIMEContext IMEContext(aWindow->GetWindowHandle());
bool associated = IMEContext.AssociateDefaultContext();
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
("IMM32: CancelComposition, associated=%s\n",
associated ? "YES" : "NO"));
nsIMEContext IMEContext(aWindow->GetWindowHandle());
if (IMEContext.IsValid()) {
::ImmNotifyIME(IMEContext.get(), NI_COMPOSITIONSTR, CPS_CANCEL, 0);
}
if (associated) {
aWindow->AssociateDefaultIMC(false);
IMEContext.Disassociate();
}
}

View File

@ -61,6 +61,32 @@ public:
return (::ImmGetOpenStatus(mIMC) != FALSE);
}
bool AssociateDefaultContext()
{
// We assume that there is only default IMC, no new IMC has been created.
if (mIMC) {
return false;
}
if (!::ImmAssociateContextEx(mWnd, NULL, IACE_DEFAULT)) {
return false;
}
mIMC = ::ImmGetContext(mWnd);
return (mIMC != NULL);
}
bool Disassociate()
{
if (!mIMC) {
return false;
}
if (!::ImmAssociateContextEx(mWnd, NULL, 0)) {
return false;
}
::ImmReleaseContext(mWnd, mIMC);
mIMC = NULL;
return true;
}
protected:
nsIMEContext()
{

View File

@ -7200,8 +7200,7 @@ void nsWindow::OnDestroy()
CaptureRollupEvents(nullptr, false);
}
// Restore the IM context.
AssociateDefaultIMC(true);
IMEHandler::OnDestroyWindow(this);
// Turn off mouse trails if enabled.
MouseTrailer* mtrailer = nsToolkit::gMouseTrailer;
@ -7403,12 +7402,15 @@ nsWindow::SetInputContext(const InputContext& aContext,
bool enable = (mInputContext.mIMEState.mEnabled == IMEState::ENABLED ||
mInputContext.mIMEState.mEnabled == IMEState::PLUGIN);
AssociateDefaultIMC(enable);
nsIMEContext IMEContext(mWnd);
if (enable) {
nsIMEContext IMEContext(mWnd);
IMEContext.AssociateDefaultContext();
mInputContext.mNativeIMEContext = static_cast<void*>(IMEContext.get());
} else if (!mOnDestroyCalled) {
// Don't disassociate the context after the window is destroyed.
IMEContext.Disassociate();
}
// Restore the latest associated context when we cannot get actual context.
if (!mInputContext.mNativeIMEContext) {
mInputContext.mNativeIMEContext = nativeIMEContext;
@ -7479,42 +7481,6 @@ nsWindow::GetIMEUpdatePreference()
return IMEHandler::GetUpdatePreference();
}
bool nsWindow::AssociateDefaultIMC(bool aAssociate)
{
nsIMEContext IMEContext(mWnd);
if (aAssociate) {
BOOL ret = ::ImmAssociateContextEx(mWnd, NULL, IACE_DEFAULT);
#ifdef DEBUG
// Note that if IME isn't available with current keyboard layout,
// IMM might not be installed on the system such as English Windows.
// On such system, IMM APIs always fail.
NS_ASSERTION(ret || !IMEHandler::CurrentKeyboardLayoutHasIME(),
"ImmAssociateContextEx failed to restore default IMC");
if (ret) {
nsIMEContext newIMEContext(mWnd);
NS_ASSERTION(!IMEContext.get() || newIMEContext.get() == IMEContext.get(),
"Unknown IMC had been associated");
}
#endif
return ret && !IMEContext.get();
}
if (mOnDestroyCalled) {
// If OnDestroy() has been called, we shouldn't disassociate the default
// IMC at destroying the window.
return false;
}
if (!IMEContext.get()) {
return false; // already disassociated
}
BOOL ret = ::ImmAssociateContextEx(mWnd, NULL, 0);
NS_ASSERTION(ret, "ImmAssociateContextEx failed to disassociate the IMC");
return ret != FALSE;
}
#ifdef ACCESSIBILITY
#ifdef DEBUG_WMGETOBJECT