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 122859 0de41d77f14793b696a6ae988d6e89670b231eeb
parent 122858 990ce017ec914e443c89ec85a21e4987461d7fb3
child 122860 104f94cc779bdab8d2f40e200d5c9e53651c4782
push id1387
push userphilringnalda@gmail.com
push dateTue, 26 Feb 2013 22:32:56 +0000
treeherderfx-team@ad4cc4e97774 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm
bugs840409
milestone22.0a1
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)) {