Bug 1395876 - Initialize TSF modules after we create first normal window r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 08 Sep 2017 16:26:54 +0900
changeset 429514 86465f8cfaf3404b7ed15f7a2f74b9e2e54f8121
parent 429513 c65dfa68df8da69f30e8f58715383de179a51397
child 429515 8c9d50f961f55d6c144cbbedfa94a6126ea0dab7
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs1395876, 1341915
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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();