Bug 1306549 part.7 Create KeyboardLayout::MaybeInitNativeKeyAsDeadKey() r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 30 Sep 2016 16:06:00 +0900
changeset 316364 489e11449d8e62b1eee742090ad177762d9dab2d
parent 316363 9be247c306a1250c8416feb2f68d284a5e3f4942
child 316365 7dbd5e61db3794bfbe2c4bc0679ce565146bb90d
push id30770
push userkwierso@gmail.com
push dateWed, 05 Oct 2016 00:00:48 +0000
treeherdermozilla-central@3470e326025c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs1306549
milestone52.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 1306549 part.7 Create KeyboardLayout::MaybeInitNativeKeyAsDeadKey() r=m_kato This patch creates KeyboardLayout::MaybeInitNativeKeyAsDeadKey() for wrapping dead key handling code in KeyboardLayout::InitNativeKey(). This makes InitNativeKey() code simpler. Now, any developers must be able to understand what InitNativeKey() does easier than before fixing this bug. MozReview-Commit-ID: C59ESUXeTxU
widget/windows/KeyboardLayout.cpp
widget/windows/KeyboardLayout.h
--- a/widget/windows/KeyboardLayout.cpp
+++ b/widget/windows/KeyboardLayout.cpp
@@ -3651,106 +3651,133 @@ KeyboardLayout::InitNativeKey(NativeKey&
 
   MOZ_ASSERT(virtualKey != VK_PACKET,
     "At handling VK_PACKET, we shouldn't refer keyboard layout");
   MOZ_ASSERT(aNativeKey.mKeyNameIndex == KEY_NAME_INDEX_USE_STRING,
     "Printable key's key name index must be KEY_NAME_INDEX_USE_STRING");
 
   bool isKeyDown = aNativeKey.IsKeyDownMessage();
 
-  if (IsDeadKey(virtualKey, aModKeyState)) {
-    if ((isKeyDown && mActiveDeadKey < 0) ||
-        (!isKeyDown && mActiveDeadKey == virtualKey)) {
-      ActivateDeadKeyState(aNativeKey, aModKeyState);
-#ifdef DEBUG
-      UniCharsAndModifiers deadChars =
-        GetNativeUniCharsAndModifiers(virtualKey, aModKeyState);
-      MOZ_ASSERT(deadChars.mLength == 1,
-                 "dead key must generate only one character");
-#endif
-      // First dead key event doesn't generate characters.  Dead key should
-      // cause only keydown event and keyup event whose KeyboardEvent.key
-      // values are "Dead".
-      aNativeKey.mCommittedCharsAndModifiers.Clear();
-      aNativeKey.mKeyNameIndex = KEY_NAME_INDEX_Dead;
-      return;
-    }
-
-    // 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 =
-        GetUniCharsAndModifiers(virtualKey, aModKeyState);
-      return;
-    }
-
-    if (NS_WARN_IF(!IsPrintableCharKey(mActiveDeadKey))) {
-#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)",
-                              GetKeyIndex(mActiveDeadKey), 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");
-    }
-
-    // Dead key followed by another dead key may cause a composed character
-    // (e.g., "Russian - Mnemonic" keyboard layout's 's' -> 'c').
-    if (MaybeInitNativeKeyWithCompositeChar(aNativeKey, aModKeyState)) {
-      return;
-    }
-
-    // Otherwise, dead key followed by another dead key causes inputting both
-    // character.
-    UniCharsAndModifiers prevDeadChars =
-      GetUniCharsAndModifiers(mActiveDeadKey, mDeadKeyShiftState);
-    UniCharsAndModifiers newChars =
-      GetUniCharsAndModifiers(virtualKey, aModKeyState);
-    // But keypress events should be fired for each committed character.
-    aNativeKey.mCommittedCharsAndModifiers = prevDeadChars + newChars;
-    if (isKeyDown) {
-      DeactivateDeadKeyState();
-    }
+  // If it's a dead key, aNativeKey will be initialized by
+  // MaybeInitNativeKeyAsDeadKey().
+  if (MaybeInitNativeKeyAsDeadKey(aNativeKey, aModKeyState)) {
     return;
   }
 
+  // If it's in dead key handling and the pressed key causes a composite
+  // character, aNativeKey will be initialized by
+  // MaybeInitNativeKeyWithCompositeChar().
   if (MaybeInitNativeKeyWithCompositeChar(aNativeKey, aModKeyState)) {
     return;
   }
 
   UniCharsAndModifiers baseChars =
     GetUniCharsAndModifiers(virtualKey, aModKeyState);
+
+  // If the key press isn't related to any dead keys, initialize aNativeKey
+  // with the characters which should be caused by the key.
   if (mActiveDeadKey < 0) {
-    // No dead-keys are active. Just return the produced characters.
     aNativeKey.mCommittedCharsAndModifiers = baseChars;
     return;
   }
 
+  // Although, this shouldn't occur, if active dead key isn't a printable
+  // key, we cannot handle it because KeyboardLayout assumes that dead key
+  // is never mapped to non-printable keys (e.g., F4, etc).  Please be aware,
+  // it's possible, but we've not known such special keyboard layout yet.
+  if (NS_WARN_IF(!IsPrintableCharKey(mActiveDeadKey))) {
+    return;
+  }
+
+  // If the key doesn't cause a composite character with preceding dead key,
+  // initialize aNativeKey with the dead-key character followed by current
+  // key's character.
+  UniCharsAndModifiers deadChars =
+    GetUniCharsAndModifiers(mActiveDeadKey, mDeadKeyShiftState);
+  aNativeKey.mCommittedCharsAndModifiers = deadChars + baseChars;
+  if (isKeyDown) {
+    DeactivateDeadKeyState();
+  }
+}
+
+bool
+KeyboardLayout::MaybeInitNativeKeyAsDeadKey(
+                  NativeKey& aNativeKey,
+                  const ModifierKeyState& aModKeyState)
+{
+  uint8_t virtualKey = aNativeKey.mOriginalVirtualKeyCode;
+  if (!IsDeadKey(virtualKey, aModKeyState)) {
+    return false;
+  }
+
+  // If it's a keydown event but not in dead key sequence or it's a keyup
+  // event of a dead key which activated current dead key sequence,
+  // initialize aNativeKey as a dead key event.
+  if ((aNativeKey.IsKeyDownMessage() && mActiveDeadKey < 0) ||
+      (!aNativeKey.IsKeyDownMessage() && mActiveDeadKey == virtualKey)) {
+    ActivateDeadKeyState(aNativeKey, aModKeyState);
+#ifdef DEBUG
+    UniCharsAndModifiers deadChars =
+      GetNativeUniCharsAndModifiers(virtualKey, aModKeyState);
+    MOZ_ASSERT(deadChars.mLength == 1,
+               "dead key must generate only one character");
+#endif
+    // First dead key event doesn't generate characters.  Dead key should
+    // cause only keydown event and keyup event whose KeyboardEvent.key
+    // values are "Dead".
+    aNativeKey.mCommittedCharsAndModifiers.Clear();
+    aNativeKey.mKeyNameIndex = KEY_NAME_INDEX_Dead;
+    return true;
+  }
+
+  // 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 =
+      GetUniCharsAndModifiers(virtualKey, aModKeyState);
+    return true;
+  }
+
   if (NS_WARN_IF(!IsPrintableCharKey(mActiveDeadKey))) {
-    return;
-  }
-
-  // There is no valid dead-key and base character combination.
-  // Return dead-key character followed by base character.
-  UniCharsAndModifiers deadChars =
+#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)",
+                            GetKeyIndex(mActiveDeadKey), 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");
+  }
+
+  // Dead key followed by another dead key may cause a composed character
+  // (e.g., "Russian - Mnemonic" keyboard layout's 's' -> 'c').
+  if (MaybeInitNativeKeyWithCompositeChar(aNativeKey, aModKeyState)) {
+    return true;
+  }
+
+  // Otherwise, dead key followed by another dead key causes inputting both
+  // character.
+  UniCharsAndModifiers prevDeadChars =
     GetUniCharsAndModifiers(mActiveDeadKey, mDeadKeyShiftState);
+  UniCharsAndModifiers newChars =
+    GetUniCharsAndModifiers(virtualKey, aModKeyState);
   // But keypress events should be fired for each committed character.
-  aNativeKey.mCommittedCharsAndModifiers = deadChars + baseChars;
-  if (isKeyDown) {
+  aNativeKey.mCommittedCharsAndModifiers = prevDeadChars + newChars;
+  if (aNativeKey.IsKeyDownMessage()) {
     DeactivateDeadKeyState();
   }
+  return true;
 }
 
 bool
 KeyboardLayout::MaybeInitNativeKeyWithCompositeChar(
                   NativeKey& aNativeKey,
                   const ModifierKeyState& aModKeyState)
 {
   if (mActiveDeadKey < 0) {
--- a/widget/windows/KeyboardLayout.h
+++ b/widget/windows/KeyboardLayout.h
@@ -663,16 +663,37 @@ private:
    * WM_KEYUP.  This method is stateful.  This saves current dead key state at
    * WM_KEYDOWN.  Additionally, computes current inputted character(s) and set
    * them to the aNativeKey.
    */
   void InitNativeKey(NativeKey& aNativeKey,
                      const ModifierKeyState& aModKeyState);
 
   /**
+   * MaybeInitNativeKeyAsDeadKey() initializes aNativeKey only when aNativeKey
+   * is a dead key's event.
+   * When it's not in a dead key sequence, this activates the dead key state.
+   * When it's in a dead key sequence, this initializes aNativeKey with a
+   * composite character or a preceding dead char and a dead char which should
+   * be caused by aNativeKey.
+   * Returns true when this initializes aNativeKey.  Otherwise, false.
+   */
+  bool MaybeInitNativeKeyAsDeadKey(NativeKey& aNativeKey,
+                                   const ModifierKeyState& aModKeyState);
+
+  /**
+   * MaybeInitNativeKeyWithCompositeChar() may initialize aNativeKey with
+   * proper composite character when dead key produces a composite character.
+   * Otherwise, just returns false.
+   */
+  bool MaybeInitNativeKeyWithCompositeChar(
+         NativeKey& aNativeKey,
+         const ModifierKeyState& aModKeyState);
+
+  /**
    * See the comment of GetUniCharsAndModifiers() below.
    */
   UniCharsAndModifiers GetUniCharsAndModifiers(
                          uint8_t aVirtualKey,
                          VirtualKey::ShiftState aShiftState) const;
 
   /**
    * GetCompositeChar() returns a composite character with dead character
@@ -702,25 +723,16 @@ public:
   /**
    * IsSysKey() returns true if aVirtualKey with aModKeyState causes WM_SYSKEY*
    * or WM_SYS*CHAR messages.
    */
   bool IsSysKey(uint8_t aVirtualKey,
                 const ModifierKeyState& aModKeyState) const;
 
   /**
-   * MaybeInitNativeKeyWithCompositeChar() may initialize aNativeKey with
-   * proper composite character when dead key produces a composite character.
-   * Otherwise, just returns false.
-   */
-  bool MaybeInitNativeKeyWithCompositeChar(
-         NativeKey& aNativeKey,
-         const ModifierKeyState& aModKeyState);
-
-  /**
    * GetUniCharsAndModifiers() returns characters which are inputted by
    * aVirtualKey with aModKeyState.  This method isn't stateful.
    * Note that if the combination causes text input, the result's Ctrl and
    * Alt key state are never active.
    */
   UniCharsAndModifiers GetUniCharsAndModifiers(
                          uint8_t aVirtualKey,
                          const ModifierKeyState& aModKeyState) const