Bug 892606 part.4 Don't handle non-keydown message as a part of dead key handling after keydown causes resetting dead key state r=jimm, a=akeybl
authorMasayuki Nakano <masayuki@d-toybox.com>
Mon, 19 Aug 2013 14:16:55 +0900
changeset 153785 19ef703669df94a59d75f7a0c1420d4a74008e06
parent 153784 c334e96a151e3d13ad5b5091abc7763c0b3e7848
child 153786 f4f854db61a5173a77f3a7a1e9a873c42b0d3ab5
push id2859
push userakeybl@mozilla.com
push dateMon, 16 Sep 2013 19:14:59 +0000
treeherdermozilla-beta@87d3c51cd2bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm, akeybl
bugs892606
milestone25.0a2
Bug 892606 part.4 Don't handle non-keydown message as a part of dead key handling after keydown causes resetting dead key state r=jimm, a=akeybl
widget/windows/KeyboardLayout.cpp
--- a/widget/windows/KeyboardLayout.cpp
+++ b/widget/windows/KeyboardLayout.cpp
@@ -18,16 +18,20 @@
 #include "WinUtils.h"
 #include "nsWindowDbg.h"
 #include "nsServiceManagerUtils.h"
 #include "nsPrintfCString.h"
 
 #include "nsIDOMKeyEvent.h"
 #include "nsIIdleServiceInternal.h"
 
+#ifdef MOZ_CRASHREPORTER
+#include "nsExceptionHandler.h"
+#endif
+
 #include "npapi.h"
 
 #include <windows.h>
 #include <winuser.h>
 #include <algorithm>
 
 #ifndef WINABLEAPI
 #include <winable.h>
@@ -1050,17 +1054,17 @@ NativeKey::NeedsToHandleWithoutFollowing
   // are not pressed, we don't need special handling for the key.
   if (!mModKeyState.IsControl() && !mModKeyState.IsAlt() &&
       !mModKeyState.IsWin()) {
     return false;
   }
 
   // If the key event causes dead key event, we don't need to dispatch keypress
   // event.
-  if (mIsDeadKey) {
+  if (mIsDeadKey && mCommittedCharsAndModifiers.IsEmpty()) {
     return false;
   }
 
   // Even if the key is a printable key, it might cause non-printable character
   // input with modifier key(s).
   return mIsPrintableKey;
 }
 
@@ -1491,28 +1495,43 @@ KeyboardLayout::InitNativeKey(NativeKey&
         mVirtualKeys[virtualKeyIndex].GetNativeUniChars(shiftState);
       NS_ASSERTION(deadChars.mLength == 1,
                    "dead key must generate only one character");
       aNativeKey.mKeyNameIndex =
         WidgetUtils::GetDeadKeyNameIndex(deadChars.mChars[0]);
       return;
     }
 
-    // Dead-key followed by another dead-key. Reset dead-key state and
-    // return both dead-key characters.
+    // Dead key followed by another dead key causes inputting both character.
+    // However, at keydown message handling, we need to forget the first
+    // dead key because there is no guarantee coming WM_KEYUP for the second
+    // dead key before next WM_KEYDOWN.  E.g., due to auto key repeat or
+    // pressing another dead key before releasing current key.  Therefore,
+    // we can set only a character for current key for keyup event.
+    if (mActiveDeadKey < 0) {
+      aNativeKey.mCommittedCharsAndModifiers =
+        mVirtualKeys[virtualKeyIndex].GetUniChars(shiftState);
+      return;
+    }
+
     int32_t activeDeadKeyIndex = GetKeyIndex(mActiveDeadKey);
-#ifdef DEBUG
     if (activeDeadKeyIndex < 0 || activeDeadKeyIndex >= NS_NUM_OF_KEYS) {
+#if defined(DEBUG) || defined(MOZ_CRASHREPORTER)
       nsPrintfCString warning("The virtual key index (%d) of mActiveDeadKey "
                               "(0x%02X) is not a printable key (virtualKey="
                               "0x%02X)",
                               activeDeadKeyIndex, mActiveDeadKey, virtualKey);
       NS_WARNING(warning.get());
+#ifdef MOZ_CRASHREPORTER
+      CrashReporter::AppendAppNotesToCrashReport(
+                       NS_LITERAL_CSTRING("\n") + warning);
+#endif // #ifdef MOZ_CRASHREPORTER
+#endif // #if defined(DEBUG) || defined(MOZ_CRASHREPORTER)
+      MOZ_CRASH("Trying to reference out of range of mVirtualKeys");
     }
-#endif
     UniCharsAndModifiers prevDeadChars =
       mVirtualKeys[activeDeadKeyIndex].GetUniChars(mDeadKeyShiftState);
     UniCharsAndModifiers newChars =
       mVirtualKeys[virtualKeyIndex].GetUniChars(shiftState);
     // But keypress events should be fired for each committed character.
     aNativeKey.mCommittedCharsAndModifiers = prevDeadChars + newChars;
     if (isKeyDown) {
       DeactivateDeadKeyState();