Bug 1395876 - Initialize TSF modules after we create first normal window r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 08 Sep 2017 16:26:54 +0900
changeset 662209 b8346f493421d5559a53994fe6e51dedd64066eb
parent 662089 a5f163da8a9be5d2e86138c57d59be69723b5457
child 730785 01553c9c8abe3cf18464c1aaa89fd3b0cda5d01b
push id78995
push usermasayuki@d-toybox.com
push dateMon, 11 Sep 2017 07:16:53 +0000
reviewersm_kato
bugs1395876, 1341915
milestone57.0a1
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
widget/windows/WinIMEHandler.cpp
widget/windows/WinIMEHandler.h
widget/windows/nsWindow.cpp
--- 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();