Bug 1395876 - Initialize TSF modules after we create first normal window r?m_kato
Currently, we initialize TSF modules when there is only message window (this
started from
bug 1341915). At this time, QQ Input (Simplified Chinese TIP)
fails to initialize itself.
Therefore, we should put off to initialize TSF modules after creating first
normal window. Then, initialize its IMC and input context for the window.
IMEHandler::InitInputContext() should be called when each normal window is
created. Therefore, calling Initialize() from it can guarantee there is
at least one normal window when Initialize() is called.
MozReview-Commit-ID: IfR4y3pYv6J
--- a/widget/windows/WinIMEHandler.cpp
+++ b/widget/windows/WinIMEHandler.cpp
@@ -498,16 +498,32 @@ IMEHandler::AssociateIMEContext(nsWindow
}
context.Disassociate();
}
// static
void
IMEHandler::InitInputContext(nsWindow* aWindow, InputContext& aInputContext)
{
+ MOZ_ASSERT(aWindow);
+ MOZ_ASSERT(aWindow->GetWindowHandle(),
+ "IMEHandler::SetInputContext() requires non-nullptr HWND");
+
+ static bool sInitialized = false;
+ if (!sInitialized) {
+ sInitialized = true;
+ // Some TIPs like QQ Input (Simplified Chinese) may need normal window
+ // (i.e., windows except message window) when initializing themselves.
+ // Therefore, we need to initialize TSF/IMM modules after first normal
+ // window is created. InitInputContext() should be called immediately
+ // after creating each normal window, so, here is a good place to
+ // initialize these modules.
+ Initialize();
+ }
+
// For a11y, the default enabled state should be 'enabled'.
aInputContext.mIMEState.mEnabled = IMEState::ENABLED;
#ifdef NS_ENABLE_TSF
if (sIsInTSFMode) {
TSFTextStore::SetInputContext(aWindow, aInputContext,
InputContextAction(InputContextAction::CAUSE_UNKNOWN,
InputContextAction::WIDGET_CREATED));
--- a/widget/windows/WinIMEHandler.h
+++ b/widget/windows/WinIMEHandler.h
@@ -25,18 +25,26 @@ struct MSGResult;
/**
* IMEHandler class is a mediator class. On Windows, there are two IME API
* sets: One is IMM which is legacy API set. The other is TSF which is modern
* API set. By using this class, non-IME handler classes don't need to worry
* that we're in which mode.
*/
class IMEHandler final
{
+private:
+ /**
+ * Initialize() initializes both TSF modules and IMM modules. Some TIPs
+ * may require a normal window (i.e., not message window) belonging to
+ * this process. Therefore, this is called immediately after first normal
+ * window is created.
+ */
+ static void Initialize();
+
public:
- static void Initialize();
static void Terminate();
/**
* Returns TSF related native data or native IME context.
*/
static void* GetNativeData(nsWindow* aWindow, uint32_t aDataType);
/**
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -650,17 +650,16 @@ nsWindow::nsWindow(bool aIsChildWindow)
if (!sInstanceCount) {
// Global app registration id for Win7 and up. See
// WinTaskbar.cpp for details.
mozilla::widget::WinTaskbar::RegisterAppUserModelID();
KeyboardLayout::GetInstance()->OnLayoutChange(::GetKeyboardLayout(0));
#if defined(ACCESSIBILITY)
mozilla::TIPMessageHandler::Initialize();
#endif // defined(ACCESSIBILITY)
- IMEHandler::Initialize();
if (SUCCEEDED(::OleInitialize(nullptr))) {
sIsOleInitialized = TRUE;
}
NS_ASSERTION(sIsOleInitialized, "***** OLE is not initialized!\n");
MouseScrollHandler::Initialize();
// Init theme data
nsUXThemeData::UpdateNativeThemeInfo();
RedirectedKeyDownMessageManager::Forget();