From 6cad7266283aad5bb724dcbeb7c2cf0d1e0d8709 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Fri, 11 Dec 2015 15:15:57 +0900 Subject: [PATCH] Bug 1179632 part.1 native IME context should not be stored in InputContext but should be able to retrieve with nsIWidget::GetNativeData() r=smaug --- dom/events/TextComposition.cpp | 4 +-- dom/ipc/PBrowser.ipdl | 3 +- dom/ipc/TabParent.cpp | 5 +--- dom/ipc/TabParent.h | 3 +- widget/IMEData.h | 13 ++++---- widget/PuppetWidget.cpp | 8 +++-- widget/android/nsWindow.cpp | 7 +++-- widget/cocoa/nsChildView.mm | 18 ++++++----- widget/cocoa/nsCocoaWindow.h | 10 ------- widget/cocoa/nsCocoaWindow.mm | 14 +++++++++ widget/gonk/nsWindow.cpp | 5 ++-- widget/gtk/nsWindow.cpp | 14 +++++---- widget/nsIWidget.h | 7 ++++- widget/qt/nsWindow.cpp | 8 ++--- widget/uikit/nsWindow.mm | 5 +++- widget/windows/IMMHandler.cpp | 24 +++++++++++++++ widget/windows/IMMHandler.h | 20 +++++++------ widget/windows/WinIMEHandler.cpp | 51 ++++++++++++++++++-------------- widget/windows/WinIMEHandler.h | 4 +-- widget/windows/nsWindow.cpp | 4 ++- widget/windows/nsWindow.h | 6 ++++ 21 files changed, 146 insertions(+), 87 deletions(-) diff --git a/dom/events/TextComposition.cpp b/dom/events/TextComposition.cpp index 534390f06faf..3a55963db35c 100644 --- a/dom/events/TextComposition.cpp +++ b/dom/events/TextComposition.cpp @@ -40,7 +40,7 @@ TextComposition::TextComposition(nsPresContext* aPresContext, , mNode(aNode) , mTabParent(aTabParent) , mNativeContext( - aCompositionEvent->widget->GetInputContext().mNativeIMEContext) + aCompositionEvent->widget->GetNativeData(NS_NATIVE_IME_CONTEXT)) , mCompositionStartOffset(0) , mCompositionTargetOffset(0) , mIsSynthesizedForTests(aCompositionEvent->mFlags.mIsSynthesizedForTests) @@ -69,7 +69,7 @@ TextComposition::Destroy() bool TextComposition::MatchesNativeContext(nsIWidget* aWidget) const { - return mNativeContext == aWidget->GetInputContext().mNativeIMEContext; + return mNativeContext == aWidget->GetNativeData(NS_NATIVE_IME_CONTEXT); } bool diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index 0628bed4d2b2..19217197092a 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -296,8 +296,7 @@ parent: nsCString[] disabledCommands); prio(urgent) sync GetInputContext() returns (int32_t IMEEnabled, - int32_t IMEOpen, - intptr_t NativeIMEContext); + int32_t IMEOpen); prio(urgent) async SetInputContext(int32_t IMEEnabled, int32_t IMEOpen, diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index 8262561e5c56..5c30387886e0 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -2363,21 +2363,18 @@ TabParent::RecvSetPluginFocused(const bool& aFocused) bool TabParent::RecvGetInputContext(int32_t* aIMEEnabled, - int32_t* aIMEOpen, - intptr_t* aNativeIMEContext) + int32_t* aIMEOpen) { nsCOMPtr widget = GetWidget(); if (!widget) { *aIMEEnabled = IMEState::DISABLED; *aIMEOpen = IMEState::OPEN_STATE_NOT_SUPPORTED; - *aNativeIMEContext = 0; return true; } InputContext context = widget->GetInputContext(); *aIMEEnabled = static_cast(context.mIMEState.mEnabled); *aIMEOpen = static_cast(context.mIMEState.mOpen); - *aNativeIMEContext = reinterpret_cast(context.mNativeIMEContext); return true; } diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index 2a74190b04c9..193f833447de 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -196,8 +196,7 @@ public: nsString* aCommitted) override; virtual bool RecvSetPluginFocused(const bool& aFocused) override; virtual bool RecvGetInputContext(int32_t* aIMEEnabled, - int32_t* aIMEOpen, - intptr_t* aNativeIMEContext) override; + int32_t* aIMEOpen) override; virtual bool RecvSetInputContext(const int32_t& aIMEEnabled, const int32_t& aIMEOpen, const nsString& aType, diff --git a/widget/IMEData.h b/widget/IMEData.h index b49fe9afdbe3..9ad091599c4b 100644 --- a/widget/IMEData.h +++ b/widget/IMEData.h @@ -223,11 +223,15 @@ struct IMEState final } }; +// NS_ONLY_ONE_NATIVE_IME_CONTEXT is a special value of native IME context. +// If there can be only one IME composition in a process, this can be used. +#define NS_ONLY_ONE_NATIVE_IME_CONTEXT \ + (reinterpret_cast(static_cast(-1))) + struct InputContext final { InputContext() - : mNativeIMEContext(nullptr) - , mOrigin(XRE_IsParentProcess() ? ORIGIN_MAIN : ORIGIN_CONTENT) + : mOrigin(XRE_IsParentProcess() ? ORIGIN_MAIN : ORIGIN_CONTENT) , mMayBeIMEUnaware(false) { } @@ -248,11 +252,6 @@ struct InputContext final /* A hint for the action that is performed when the input is submitted */ nsString mActionHint; - /* Native IME context for the widget. This doesn't come from the argument of - SetInputContext(). If there is only one context in the process, this may - be nullptr. */ - void* mNativeIMEContext; - /** * mOrigin indicates whether this focus event refers to main or remote * content. diff --git a/widget/PuppetWidget.cpp b/widget/PuppetWidget.cpp index 8135dfd49478..21e0df76b793 100644 --- a/widget/PuppetWidget.cpp +++ b/widget/PuppetWidget.cpp @@ -675,11 +675,10 @@ PuppetWidget::GetInputContext() InputContext context; if (mTabChild) { int32_t enabled, open; - intptr_t nativeIMEContext; - mTabChild->SendGetInputContext(&enabled, &open, &nativeIMEContext); + // TODO: This is too expensive. PuppetWidget should cache IMEState. + mTabChild->SendGetInputContext(&enabled, &open); context.mIMEState.mEnabled = static_cast(enabled); context.mIMEState.mOpen = static_cast(open); - context.mNativeIMEContext = reinterpret_cast(nativeIMEContext); } return context; } @@ -1121,6 +1120,9 @@ PuppetWidget::GetNativeData(uint32_t aDataType) case NS_NATIVE_DISPLAY: // These types are ignored (see bug 1183828). break; + case NS_NATIVE_IME_CONTEXT: + // TODO: Implement this in next patch. + return nullptr; case NS_NATIVE_WINDOW: case NS_NATIVE_PLUGIN_PORT: case NS_NATIVE_GRAPHIC: diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index 8720e325ca28..78245096d37b 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -1263,6 +1263,11 @@ nsWindow::GetNativeData(uint32_t aDataType) case NS_NATIVE_WIDGET: return (void *) this; + + case NS_NATIVE_IME_CONTEXT: + // We assume that there is only one context per process on Android + return NS_ONLY_ONE_NATIVE_IME_CONTEXT; + } return nullptr; @@ -2244,8 +2249,6 @@ nsWindow::Natives::GetInputContext() { InputContext context = mInputContext; context.mIMEState.mOpen = IMEState::OPEN_STATE_NOT_SUPPORTED; - // We assume that there is only one context per process on Android - context.mNativeIMEContext = nullptr; return context; } diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index fef65107af29..22d7fc756fcb 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -684,6 +684,17 @@ void* nsChildView::GetNativeData(uint32_t aDataType) case NS_NATIVE_OFFSETY: retVal = 0; break; + + case NS_NATIVE_IME_CONTEXT: + retVal = [mView inputContext]; + // If input context isn't available on this widget, we should set |this| + // instead of nullptr since if this returns nullptr, IMEStateManager + // cannot manage composition with TextComposition instance. Although, + // this case shouldn't occur. + if (NS_WARN_IF(!retVal)) { + retVal = this; + } + break; } return retVal; @@ -1769,13 +1780,6 @@ nsChildView::GetInputContext() mInputContext.mIMEState.mOpen = IMEState::CLOSED; break; } - mInputContext.mNativeIMEContext = [mView inputContext]; - // If input context isn't available on this widget, we should set |this| - // instead of nullptr since nullptr means that the platform has only one - // context per process. - if (!mInputContext.mNativeIMEContext) { - mInputContext.mNativeIMEContext = this; - } return mInputContext; } diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h index 9bb38318d500..4b75ffac6890 100644 --- a/widget/cocoa/nsCocoaWindow.h +++ b/widget/cocoa/nsCocoaWindow.h @@ -365,16 +365,6 @@ public: const InputContextAction& aAction) override; NS_IMETHOD_(InputContext) GetInputContext() override { - NSView* view = mWindow ? [mWindow contentView] : nil; - if (view) { - mInputContext.mNativeIMEContext = [view inputContext]; - } - // If inputContext isn't available on this window, returns this window's - // pointer since nullptr means the platform has only one context per - // process. - if (!mInputContext.mNativeIMEContext) { - mInputContext.mNativeIMEContext = this; - } return mInputContext; } NS_IMETHOD_(bool) ExecuteNativeKeyBinding( diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm index 481ab77fe2d4..9febd6dfbb5a 100644 --- a/widget/cocoa/nsCocoaWindow.mm +++ b/widget/cocoa/nsCocoaWindow.mm @@ -592,6 +592,20 @@ void* nsCocoaWindow::GetNativeData(uint32_t aDataType) // and it doesn't matter so just return nullptr. NS_ERROR("Requesting NS_NATIVE_GRAPHIC on a top-level window!"); break; + case NS_NATIVE_IME_CONTEXT: { + NSView* view = mWindow ? [mWindow contentView] : nil; + if (view) { + retVal = [view inputContext]; + } + // If inputContext isn't available on this window, return this window's + // pointer instead of nullptr since if this returns nullptr, + // IMEStateManager cannot manage composition with TextComposition + // instance. Although, this case shouldn't occur. + if (NS_WARN_IF(!retVal)) { + retVal = this; + } + break; + } } return retVal; diff --git a/widget/gonk/nsWindow.cpp b/widget/gonk/nsWindow.cpp index d2bd45e7b153..2dfb234a0765 100644 --- a/widget/gonk/nsWindow.cpp +++ b/widget/gonk/nsWindow.cpp @@ -539,6 +539,9 @@ nsWindow::GetNativeData(uint32_t aDataType) return mScreen->GetNativeWindow(); case NS_NATIVE_OPENGL_CONTEXT: return mScreen->GetGLContext().take(); + case NS_NATIVE_IME_CONTEXT: + // There is only one IME context on Gonk. + return NS_ONLY_ONE_NATIVE_IME_CONTEXT; } return nullptr; @@ -582,8 +585,6 @@ nsWindow::SetInputContext(const InputContext& aContext, NS_IMETHODIMP_(InputContext) nsWindow::GetInputContext() { - // There is only one IME context on Gonk. - mInputContext.mNativeIMEContext = nullptr; return mInputContext; } diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index ef82a47629c3..3d1a355d60a2 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -1737,6 +1737,15 @@ nsWindow::GetNativeData(uint32_t aDataType) return (void *) GDK_WINDOW_XID(gdk_window_get_toplevel(mGdkWindow)); case NS_NATIVE_PLUGIN_OBJECT_PTR: return (void *) mPluginNativeWindow; + case NS_NATIVE_IME_CONTEXT: + // If IME context isn't available on this widget, we should set |this| + // instead of nullptr since if we return nullptr, IMEStateManager + // cannot manage composition with TextComposition instance. Although, + // this case shouldn't occur. + if (NS_WARN_IF(!mIMContext)) { + return this; + } + return mIMContext.get(); default: NS_WARNING("nsWindow::GetNativeData called with bad value"); return nullptr; @@ -6295,13 +6304,8 @@ nsWindow::GetInputContext() if (!mIMContext) { context.mIMEState.mEnabled = IMEState::DISABLED; context.mIMEState.mOpen = IMEState::OPEN_STATE_NOT_SUPPORTED; - // If IME context isn't available on this widget, we should set |this| - // instead of nullptr since nullptr means that the platform has only one - // context per process. - context.mNativeIMEContext = this; } else { context = mIMContext->GetInputContext(); - context.mNativeIMEContext = mIMContext; } return context; } diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index ae565f24cc57..8a328ef9a8f3 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -104,7 +104,12 @@ typedef void* nsNativeWidget; #define NS_NATIVE_SHAREABLE_WINDOW 11 #define NS_NATIVE_OPENGL_CONTEXT 12 // See RegisterPluginWindowForRemoteUpdates -#define NS_NATIVE_PLUGIN_ID 13 +#define NS_NATIVE_PLUGIN_ID 13 +// This is available only with GetNativeData(). Anybody shouldn't access this +// pointer as a valid pointer since the result may be special value like +// NS_ONLY_ONE_NATIVE_IME_CONTEXT. So, the result is just an identifier of +// distinguishing a text composition is caused by which native IME context. +#define NS_NATIVE_IME_CONTEXT 14 #ifdef XP_MACOSX #define NS_NATIVE_PLUGIN_PORT_QD 100 #define NS_NATIVE_PLUGIN_PORT_CG 101 diff --git a/widget/qt/nsWindow.cpp b/widget/qt/nsWindow.cpp index f2224e6d7a5a..69250b31f2ff 100644 --- a/widget/qt/nsWindow.cpp +++ b/widget/qt/nsWindow.cpp @@ -664,6 +664,10 @@ nsWindow::GetNativeData(uint32_t aDataType) case NS_NATIVE_SHELLWIDGET: { break; } + case NS_NATIVE_IME_CONTEXT: + // Our qt widget looks like using only one context per process. + // However, it's better to set the context's pointer. + return qApp->inputMethod(); default: NS_WARNING("nsWindow::GetNativeData called with bad value"); return nullptr; @@ -716,10 +720,6 @@ NS_IMETHODIMP_(InputContext) nsWindow::GetInputContext() { mInputContext.mIMEState.mOpen = IMEState::OPEN_STATE_NOT_SUPPORTED; - // Our qt widget looks like using only one context per process. - // However, it's better to set the context's pointer. - mInputContext.mNativeIMEContext = qApp->inputMethod(); - return mInputContext; } diff --git a/widget/uikit/nsWindow.mm b/widget/uikit/nsWindow.mm index 00433291ad41..354969683bfb 100644 --- a/widget/uikit/nsWindow.mm +++ b/widget/uikit/nsWindow.mm @@ -836,7 +836,6 @@ nsWindow::SetInputContext(const InputContext& aContext, NS_IMETHODIMP_(mozilla::widget::InputContext) nsWindow::GetInputContext() { - mInputContext.mNativeIMEContext = nullptr; return mInputContext; } @@ -879,6 +878,10 @@ void* nsWindow::GetNativeData(uint32_t aDataType) case NS_NATIVE_PLUGIN_PORT: // not implemented break; + + case NS_NATIVE_IME_CONTEXT: + retVal = NS_ONLY_ONE_NATIVE_IME_CONTEXT; + break; } return retVal; diff --git a/widget/windows/IMMHandler.cpp b/widget/windows/IMMHandler.cpp index 0064cd293002..0d4bfcf996da 100644 --- a/widget/windows/IMMHandler.cpp +++ b/widget/windows/IMMHandler.cpp @@ -186,6 +186,30 @@ IMEContext::IMEContext(nsWindow* aWindow) { } +void +IMEContext::Init(HWND aWnd) +{ + Clear(); + mWnd = aWnd; + mIMC = ::ImmGetContext(mWnd); +} + +void +IMEContext::Init(nsWindow* aWindow) +{ + Init(aWindow->GetWindowHandle()); +} + +void +IMEContext::Clear() +{ + if (mWnd && mIMC) { + ::ImmReleaseContext(mWnd, mIMC); + } + mWnd = nullptr; + mIMC = nullptr; +} + /****************************************************************************** * IMMHandler ******************************************************************************/ diff --git a/widget/windows/IMMHandler.h b/widget/windows/IMMHandler.h index 7b908ecfc74d..8bd3bda4ca64 100644 --- a/widget/windows/IMMHandler.h +++ b/widget/windows/IMMHandler.h @@ -26,15 +26,18 @@ struct MSGResult; class IMEContext final { public: + IMEContext() + : mWnd(nullptr) + , mIMC(nullptr) + { + } + explicit IMEContext(HWND aWnd); explicit IMEContext(nsWindow* aWindow); ~IMEContext() { - if (mIMC) { - ::ImmReleaseContext(mWnd, mIMC); - mIMC = nullptr; - } + Clear(); } HIMC get() const @@ -42,6 +45,10 @@ public: return mIMC; } + void Init(HWND aWnd); + void Init(nsWindow* aWindow); + void Clear(); + bool IsValid() const { return !!mIMC; @@ -90,11 +97,6 @@ public: } protected: - IMEContext() - { - MOZ_CRASH("Don't create IMEContext without window handle"); - } - IMEContext(const IMEContext& aOther) { MOZ_CRASH("Don't copy IMEContext"); diff --git a/widget/windows/WinIMEHandler.cpp b/widget/windows/WinIMEHandler.cpp index 520ad5eb72d3..a2e766d1ed52 100644 --- a/widget/windows/WinIMEHandler.cpp +++ b/widget/windows/WinIMEHandler.cpp @@ -94,8 +94,31 @@ IMEHandler::Terminate() // static void* -IMEHandler::GetNativeData(uint32_t aDataType) +IMEHandler::GetNativeData(nsWindow* aWindow, uint32_t aDataType) { + if (aDataType == NS_NATIVE_IME_CONTEXT) { +#ifdef NS_ENABLE_TSF + if (IsTSFAvailable()) { + return TSFTextStore::GetThreadManager(); + } +#endif // #ifdef NS_ENABLE_TSF + IMEContext context(aWindow); + if (context.IsValid()) { + return context.get(); + } + // If IMC isn't associated with the window, IME is disabled on the window + // now. In such case, we should return default IMC instead. + const IMEContext& defaultIMC = aWindow->DefaultIMC(); + if (defaultIMC.IsValid()) { + return defaultIMC.get(); + } + // If there is no default IMC, we should return the pointer to the window + // since if we return nullptr, IMEStateManager cannot manage composition + // with TextComposition instance. This is possible if no IME is installed, + // but composition may occur with dead key sequence. + return aWindow; + } + #ifdef NS_ENABLE_TSF void* result = TSFTextStore::GetNativeData(aDataType); if (!result || !(*(static_cast(result)))) { @@ -380,14 +403,11 @@ IMEHandler::SetInputContext(nsWindow* aWindow, bool open = (adjustOpenState && aInputContext.mIMEState.mOpen == IMEState::OPEN); - aInputContext.mNativeIMEContext = nullptr; - #ifdef NS_ENABLE_TSF // Note that even while a plugin has focus, we need to notify TSF of that. if (sIsInTSFMode) { TSFTextStore::SetInputContext(aWindow, aInputContext, aAction); if (IsTSFAvailable()) { - aInputContext.mNativeIMEContext = TSFTextStore::GetThreadManager(); if (sIsIMMEnabled) { // Associate IME context for IMM-IMEs. AssociateIMEContext(aWindow, enable); @@ -413,15 +433,6 @@ IMEHandler::SetInputContext(nsWindow* aWindow, if (adjustOpenState) { context.SetOpenState(open); } - - if (aInputContext.mNativeIMEContext) { - return; - } - - // The old InputContext must store the default IMC or old TextStore. - // When IME context is disassociated from the window, use it. - aInputContext.mNativeIMEContext = enable ? - static_cast(context.get()) : oldInputContext.mNativeIMEContext; } // static @@ -452,8 +463,6 @@ IMEHandler::InitInputContext(nsWindow* aWindow, InputContext& aInputContext) TSFTextStore::SetInputContext(aWindow, aInputContext, InputContextAction(InputContextAction::CAUSE_UNKNOWN, InputContextAction::GOT_FOCUS)); - aInputContext.mNativeIMEContext = TSFTextStore::GetThreadManager(); - MOZ_ASSERT(aInputContext.mNativeIMEContext); // IME context isn't necessary in pure TSF mode. if (!sIsIMMEnabled) { AssociateIMEContext(aWindow, false); @@ -462,15 +471,11 @@ IMEHandler::InitInputContext(nsWindow* aWindow, InputContext& aInputContext) } #endif // #ifdef NS_ENABLE_TSF - // NOTE: mNativeIMEContext may be null if IMM module isn't installed. +#ifdef DEBUG + // NOTE: IMC may be null if IMM module isn't installed. IMEContext context(aWindow); - aInputContext.mNativeIMEContext = static_cast(context.get()); - MOZ_ASSERT(aInputContext.mNativeIMEContext || !CurrentKeyboardLayoutHasIME()); - // If no IME context is available, we should set the widget's pointer since - // nullptr indicates there is only one context per process on the platform. - if (!aInputContext.mNativeIMEContext) { - aInputContext.mNativeIMEContext = static_cast(aWindow); - } + MOZ_ASSERT(context.IsValid() || !CurrentKeyboardLayoutHasIME()); +#endif // #ifdef DEBUG } #ifdef DEBUG diff --git a/widget/windows/WinIMEHandler.h b/widget/windows/WinIMEHandler.h index c3e1d30b6a65..2b6514500a30 100644 --- a/widget/windows/WinIMEHandler.h +++ b/widget/windows/WinIMEHandler.h @@ -34,9 +34,9 @@ public: static void Terminate(); /** - * Returns TSF related native data. + * Returns TSF related native data or native IME context. */ - static void* GetNativeData(uint32_t aDataType); + static void* GetNativeData(nsWindow* aWindow, uint32_t aDataType); /** * ProcessRawKeyMessage() message is called before calling TranslateMessage() diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index a94e007a337d..86d8102403e4 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -656,6 +656,7 @@ nsWindow::Create(nsIWidget* aParent, NOTIFY_FOR_THIS_SESSION); NS_ASSERTION(wtsRegistered, "WTSRegisterSessionNotification failed!\n"); + mDefaultIMC.Init(this); IMEHandler::InitInputContext(this, mInputContext); // If the internal variable set by the config.trim_on_minimize pref has not @@ -3149,10 +3150,11 @@ void* nsWindow::GetNativeData(uint32_t aDataType) return (void*)::GetDC(mWnd); #endif + case NS_NATIVE_IME_CONTEXT: case NS_NATIVE_TSF_THREAD_MGR: case NS_NATIVE_TSF_CATEGORY_MGR: case NS_NATIVE_TSF_DISPLAY_ATTR_MGR: - return IMEHandler::GetNativeData(aDataType); + return IMEHandler::GetNativeData(this, aDataType); default: break; diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h index 6afd9287b592..814461af89f3 100644 --- a/widget/windows/nsWindow.h +++ b/widget/windows/nsWindow.h @@ -44,6 +44,8 @@ #include "nsIDOMMouseEvent.h" #include "nsIIdleServiceInternal.h" +#include "IMMHandler.h" + /** * Forward class definitions */ @@ -71,6 +73,7 @@ class nsWindow : public nsWindowBase typedef mozilla::widget::TaskbarWindowPreview TaskbarWindowPreview; typedef mozilla::widget::NativeKey NativeKey; typedef mozilla::widget::MSGResult MSGResult; + typedef mozilla::widget::IMEContext IMEContext; public: nsWindow(); @@ -292,6 +295,8 @@ public: bool CaptureWidgetOnScreen(RefPtr aDT); + const IMEContext& DefaultIMC() const { return mDefaultIMC; } + protected: virtual ~nsWindow(); @@ -472,6 +477,7 @@ protected: HWND mTransitionWnd; WNDPROC mPrevWndProc; HBRUSH mBrush; + IMEContext mDefaultIMC; bool mIsTopWidgetWindow; bool mInDtor; bool mIsVisible;