Bug 610829 Should associate default IMC at committing or canceling composition r=emk

This commit is contained in:
Masayuki Nakano 2011-07-07 21:02:07 +09:00
Родитель 4fb490d48a
Коммит ac4654e172
4 изменённых файлов: 86 добавлений и 15 удалений

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

@ -293,11 +293,21 @@ nsIMM32Handler::CommitComposition(nsWindow* aWindow, PRBool aForce)
if (!aForce && !IsComposingWindow(aWindow)) {
return;
}
PRBool associated = aWindow->AssociateDefaultIMC(PR_TRUE);
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(PR_FALSE);
}
}
/* static */ void
@ -314,10 +324,20 @@ nsIMM32Handler::CancelComposition(nsWindow* aWindow, PRBool aForce)
if (!aForce && !IsComposingWindow(aWindow)) {
return;
}
PRBool associated = aWindow->AssociateDefaultIMC(PR_TRUE);
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(PR_FALSE);
}
}
/* static */ PRBool

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

@ -131,6 +131,14 @@ public:
static PRBool CanOptimizeKeyAndIMEMessages(MSG *aNextKeyOrIMEMessage);
#ifdef DEBUG
/**
* IsIMEAvailable() returns TRUE when current keyboard layout has IME.
* Otherwise, FALSE.
*/
static PRBool IsIMEAvailable() { return sIsIME; }
#endif
// If aForce is TRUE, these methods doesn't check whether we have composition
// or not. If you don't set it to TRUE, these method doesn't commit/cancel
// the composition on uexpected window.

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

@ -370,7 +370,6 @@ nsWindow::nsWindow() : nsBaseWidget()
mWnd = nsnull;
mPaintDC = nsnull;
mPrevWndProc = nsnull;
mOldIMC = nsnull;
mNativeDragTarget = nsnull;
mInDtor = PR_FALSE;
mIsVisible = PR_FALSE;
@ -6669,7 +6668,7 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
static PRBool sRedirectedKeyDownEventPreventedDefault = PR_FALSE;
PRBool noDefault;
if (aFakeCharMessage || !IsRedirectedKeyDownMessage(aMsg)) {
HIMC oldIMC = mOldIMC;
nsIMEContext IMEContext(mWnd);
noDefault =
DispatchKeyEvent(NS_KEY_DOWN, 0, nsnull, DOMKeyCode, &aMsg, aModKeyState);
if (aEventDispatched) {
@ -6685,8 +6684,9 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
// application, we shouldn't redirect the message to it because the keydown
// message is processed by us, so, nobody shouldn't process it.
HWND focusedWnd = ::GetFocus();
if (!noDefault && !aFakeCharMessage && oldIMC && !mOldIMC && focusedWnd &&
!PluginHasFocus()) {
nsIMEContext newIMEContext(mWnd);
if (!noDefault && !aFakeCharMessage && focusedWnd && !PluginHasFocus() &&
!IMEContext.get() && newIMEContext.get()) {
RemoveNextCharMessage(focusedWnd);
INPUT keyinput;
@ -7315,11 +7315,8 @@ void nsWindow::OnDestroy()
CaptureRollupEvents(nsnull, nsnull, PR_FALSE, PR_TRUE);
}
// If IME is disabled, restore it.
if (mOldIMC) {
mOldIMC = ::ImmAssociateContext(mWnd, mOldIMC);
NS_ASSERTION(!mOldIMC, "Another IMC was associated");
}
// Restore the IM context.
AssociateDefaultIMC(PR_TRUE);
// Turn off mouse trails if enabled.
MouseTrailer* mtrailer = nsToolkit::gMouseTrailer;
@ -7958,11 +7955,7 @@ NS_IMETHODIMP nsWindow::SetInputMode(const IMEContext& aContext)
PRBool enable = (status == nsIWidget::IME_STATUS_ENABLED ||
status == nsIWidget::IME_STATUS_PLUGIN);
if (!enable != !mOldIMC)
return NS_OK;
mOldIMC = ::ImmAssociateContext(mWnd, enable ? mOldIMC : NULL);
NS_ASSERTION(!enable || !mOldIMC, "Another IMC was associated");
AssociateDefaultIMC(enable);
return NS_OK;
}
@ -8025,6 +8018,42 @@ nsWindow::OnIMESelectionChange(void)
}
#endif //NS_ENABLE_TSF
PRBool nsWindow::AssociateDefaultIMC(PRBool 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 || !nsIMM32Handler::IsIMEAvailable(),
"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 PR_FALSE;
}
if (!IMEContext.get()) {
return PR_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

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

@ -262,6 +262,21 @@ public:
*/
static void StartAllowingD3D9(bool aReinitialize);
/**
* AssociateDefaultIMC() associates or disassociates the default IMC for
* the window.
*
* @param aAssociate TRUE, associates the default IMC with the window.
* Otherwise, disassociates the default IMC from the
* window.
* @return TRUE if this method associated the default IMC with
* disassociated window or disassociated the default IMC
* from associated window.
* Otherwise, i.e., if this method did nothing actually,
* FALSE.
*/
PRBool AssociateDefaultIMC(PRBool aAssociate);
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
PRBool HasTaskbarIconBeenCreated() { return mHasTaskbarIconBeenCreated; }
// Called when either the nsWindow or an nsITaskbarTabPreview receives the noticiation that this window
@ -504,7 +519,6 @@ protected:
PRUint32 mBlurSuppressLevel;
DWORD_PTR mOldStyle;
DWORD_PTR mOldExStyle;
HIMC mOldIMC;
IMEContext mIMEContext;
nsNativeDragTarget* mNativeDragTarget;
HKL mLastKeyboardLayout;