Bug 840409 part.2 Move nsIMM32Handler::IsDoingKakuteiUndo() to widget::IMEContext r=jimm
authorMasayuki Nakano <masayuki@d-toybox.com>
Mon, 25 Feb 2013 13:00:05 +0900
changeset 134055 0de41d77f14793b696a6ae988d6e89670b231eeb
parent 134054 990ce017ec914e443c89ec85a21e4987461d7fb3
child 134056 104f94cc779bdab8d2f40e200d5c9e53651c4782
push id336
push userakeybl@mozilla.com
push dateMon, 17 Jun 2013 22:53:19 +0000
treeherdermozilla-release@574a39cdf657 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm
bugs840409
milestone22.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 840409 part.2 Move nsIMM32Handler::IsDoingKakuteiUndo() to widget::IMEContext r=jimm
widget/windows/WinIMEHandler.cpp
widget/windows/WinIMEHandler.h
widget/windows/nsIMM32Handler.cpp
widget/windows/nsIMM32Handler.h
widget/windows/nsWindow.cpp
--- a/widget/windows/WinIMEHandler.cpp
+++ b/widget/windows/WinIMEHandler.cpp
@@ -42,10 +42,45 @@ IMEHandler::Terminate()
     nsTextStore::Terminate();
     sIsInTSFMode = false;
   }
 #endif // #ifdef NS_ENABLE_TSF
 
   nsIMM32Handler::Terminate();
 }
 
+// static
+bool
+IMEHandler::IsDoingKakuteiUndo(HWND aWnd)
+{
+  // Following message pattern is caused by "Kakutei-Undo" of ATOK or WXG:
+  // ---------------------------------------------------------------------------
+  // WM_KEYDOWN              * n (wParam = VK_BACK, lParam = 0x1)
+  // WM_KEYUP                * 1 (wParam = VK_BACK, lParam = 0xC0000001) # ATOK
+  // WM_IME_STARTCOMPOSITION * 1 (wParam = 0x0, lParam = 0x0)
+  // WM_IME_COMPOSITION      * 1 (wParam = 0x0, lParam = 0x1BF)
+  // WM_CHAR                 * n (wParam = VK_BACK, lParam = 0x1)
+  // WM_KEYUP                * 1 (wParam = VK_BACK, lParam = 0xC00E0001)
+  // ---------------------------------------------------------------------------
+  // This doesn't match usual key message pattern such as:
+  //   WM_KEYDOWN -> WM_CHAR -> WM_KEYDOWN -> WM_CHAR -> ... -> WM_KEYUP
+  // See following bugs for the detail.
+  // https://bugzilla.mozilla.gr.jp/show_bug.cgi?id=2885 (written in Japanese)
+  // https://bugzilla.mozilla.org/show_bug.cgi?id=194559 (written in English)
+  MSG startCompositionMsg, compositionMsg, charMsg;
+  return ::PeekMessageW(&startCompositionMsg, aWnd,
+                        WM_IME_STARTCOMPOSITION, WM_IME_STARTCOMPOSITION,
+                        PM_NOREMOVE | PM_NOYIELD) &&
+         ::PeekMessageW(&compositionMsg, aWnd, WM_IME_COMPOSITION,
+                        WM_IME_COMPOSITION, PM_NOREMOVE | PM_NOYIELD) &&
+         ::PeekMessageW(&charMsg, aWnd, WM_CHAR, WM_CHAR,
+                        PM_NOREMOVE | PM_NOYIELD) &&
+         startCompositionMsg.wParam == 0x0 &&
+         startCompositionMsg.lParam == 0x0 &&
+         compositionMsg.wParam == 0x0 &&
+         compositionMsg.lParam == 0x1BF &&
+         charMsg.wParam == VK_BACK && charMsg.lParam == 0x1 &&
+         startCompositionMsg.time <= compositionMsg.time &&
+         compositionMsg.time <= charMsg.time;
+}
+
 } // namespace widget
 } // namespace mozilla
--- a/widget/windows/WinIMEHandler.h
+++ b/widget/windows/WinIMEHandler.h
@@ -2,32 +2,40 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef WinIMEHandler_h_
 #define WinIMEHandler_h_
 
 #include "nscore.h"
+#include <windows.h>
 
 namespace mozilla {
 namespace widget {
 
 /**
  * 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 MOZ_FINAL
 {
 public:
   static void Initialize();
   static void Terminate();
 
+  /**
+   * "Kakutei-Undo" of ATOK or WXG (both of them are Japanese IME) causes
+   * strange WM_KEYDOWN/WM_KEYUP/WM_CHAR message pattern.  So, when this
+   * returns true, the caller needs to be careful for processing the messages.
+   */
+  static bool IsDoingKakuteiUndo(HWND aWnd);
+
 private:
 #ifdef NS_ENABLE_TSF
   static bool sIsInTSFMode;
 #endif // #ifdef NS_ENABLE_TSF
 };
 
 } // namespace widget
 } // namespace mozilla
--- a/widget/windows/nsIMM32Handler.cpp
+++ b/widget/windows/nsIMM32Handler.cpp
@@ -102,51 +102,16 @@ nsIMM32Handler::IsTopLevelWindowOfCompos
   if (!gIMM32Handler || !gIMM32Handler->mComposingWindow) {
     return false;
   }
   HWND wnd = gIMM32Handler->mComposingWindow->GetWindowHandle();
   return WinUtils::GetTopLevelHWND(wnd, true) == aWindow->GetWindowHandle();
 }
 
 /* static */ bool
-nsIMM32Handler::IsDoingKakuteiUndo(HWND aWnd)
-{
-  // This message pattern is "Kakutei-Undo" on ATOK and WXG.
-  // In this case, the message queue has following messages:
-  // ---------------------------------------------------------------------------
-  // WM_KEYDOWN              * n (wParam = VK_BACK, lParam = 0x1)
-  // WM_KEYUP                * 1 (wParam = VK_BACK, lParam = 0xC0000001) # ATOK
-  // WM_IME_STARTCOMPOSITION * 1 (wParam = 0x0, lParam = 0x0)
-  // WM_IME_COMPOSITION      * 1 (wParam = 0x0, lParam = 0x1BF)
-  // WM_CHAR                 * n (wParam = VK_BACK, lParam = 0x1)
-  // WM_KEYUP                * 1 (wParam = VK_BACK, lParam = 0xC00E0001)
-  // ---------------------------------------------------------------------------
-  // This message pattern does not match to the above case;
-  // i.e.,WM_KEYDOWN -> WM_CHAR -> WM_KEYDOWN -> WM_CHAR.
-  // For more information of this problem:
-  // https://bugzilla.mozilla.gr.jp/show_bug.cgi?id=2885 (written in Japanese)
-  // https://bugzilla.mozilla.org/show_bug.cgi?id=194559 (written in English)
-  MSG imeStartCompositionMsg, imeCompositionMsg, charMsg;
-  return ::PeekMessageW(&imeStartCompositionMsg, aWnd,
-                        WM_IME_STARTCOMPOSITION, WM_IME_STARTCOMPOSITION,
-                        PM_NOREMOVE | PM_NOYIELD) &&
-         ::PeekMessageW(&imeCompositionMsg, aWnd, WM_IME_COMPOSITION,
-                        WM_IME_COMPOSITION, PM_NOREMOVE | PM_NOYIELD) &&
-         ::PeekMessageW(&charMsg, aWnd, WM_CHAR, WM_CHAR,
-                        PM_NOREMOVE | PM_NOYIELD) &&
-         imeStartCompositionMsg.wParam == 0x0 &&
-         imeStartCompositionMsg.lParam == 0x0 &&
-         imeCompositionMsg.wParam == 0x0 &&
-         imeCompositionMsg.lParam == 0x1BF &&
-         charMsg.wParam == VK_BACK && charMsg.lParam == 0x1 &&
-         imeStartCompositionMsg.time <= imeCompositionMsg.time &&
-         imeCompositionMsg.time <= charMsg.time;
-}
-
-/* static */ bool
 nsIMM32Handler::ShouldDrawCompositionStringOurselves()
 {
   // If current IME has special UI or its composition window should not
   // positioned to caret position, we should now draw composition string
   // ourselves.
   return !(sIMEProperty & IME_PROP_SPECIAL_UI) &&
           (sIMEProperty & IME_PROP_AT_CARET);
 }
--- a/widget/windows/nsIMM32Handler.h
+++ b/widget/windows/nsIMM32Handler.h
@@ -78,18 +78,16 @@ public:
   {
     return IsComposingOnOurEditor() || IsComposingOnPlugin();
   }
   static bool IsComposingOn(nsWindow* aWindow)
   {
     return IsComposing() && IsComposingWindow(aWindow);
   }
 
-  static bool IsDoingKakuteiUndo(HWND aWnd);
-
   static bool CanOptimizeKeyAndIMEMessages(MSG *aNextKeyOrIMEMessage);
 
 #ifdef DEBUG
   /**
    * IsIMEAvailable() returns TRUE when current keyboard layout has IME.
    * Otherwise, FALSE.
    */
   static bool IsIMEAvailable() { return sIsIME; }
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -6605,17 +6605,17 @@ LRESULT nsWindow::OnKeyDown(const MSG &a
         RemoveMessageAndDispatchPluginEvent(WM_KEYFIRST, WM_KEYLAST);
         anyCharMessagesRemoved = true;
 
         gotMsg = ::PeekMessageW (&msg, mWnd, WM_KEYFIRST, WM_KEYLAST, PM_NOREMOVE | PM_NOYIELD);
       }
     }
 
     if (!anyCharMessagesRemoved && DOMKeyCode == NS_VK_BACK &&
-        nsIMM32Handler::IsDoingKakuteiUndo(mWnd)) {
+        IMEHandler::IsDoingKakuteiUndo(mWnd)) {
       NS_ASSERTION(!aFakeCharMessage,
                    "We shouldn't be touching the real msg queue");
       RemoveMessageAndDispatchPluginEvent(WM_CHAR, WM_CHAR);
     }
   }
   else if (gotMsg &&
            (aFakeCharMessage ||
             msg.message == WM_CHAR || msg.message == WM_SYSCHAR || msg.message == WM_DEADCHAR)) {