Bug 1154183 part.2 eKeyDown event should have charCode value of following keypress event r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Sat, 19 Mar 2016 20:57:11 +0900
changeset 289948 b6bf385a7c2a84e72ce0caab657c082625381045
parent 289947 6e01f6bf3b982735e4c51ce0ed60862091648145
child 289949 024017da65648b6393ddf01126139bd7cb1b172d
push id30112
push usercbook@mozilla.com
push dateWed, 23 Mar 2016 15:25:32 +0000
treeherdermozilla-central@6202ade0e6d6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1154183
milestone48.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 1154183 part.2 eKeyDown event should have charCode value of following keypress event r=smaug MozReview-Commit-ID: 9duzKfCFPro
dom/base/TextInputProcessor.cpp
widget/TextEventDispatcher.cpp
widget/TextEvents.h
widget/WidgetEventImpl.cpp
widget/cocoa/TextInputHandler.mm
widget/gtk/nsGtkKeyUtils.cpp
widget/nsGUIEventIPC.h
widget/windows/KeyboardLayout.cpp
--- a/dom/base/TextInputProcessor.cpp
+++ b/dom/base/TextInputProcessor.cpp
@@ -707,17 +707,18 @@ TextInputProcessor::OnRemovedFrom(TextEv
 
 NS_IMETHODIMP_(void)
 TextInputProcessor::WillDispatchKeyboardEvent(
                       TextEventDispatcher* aTextEventDispatcher,
                       WidgetKeyboardEvent& aKeyboardEvent,
                       uint32_t aIndexOfKeypress,
                       void* aData)
 {
-  // TextInputProcessor doesn't set alternative char code.
+  // TextInputProcessor doesn't set alternative char code nor modify charCode
+  // even when Ctrl key is pressed.
 }
 
 nsresult
 TextInputProcessor::PrepareKeyboardEventToDispatch(
                       WidgetKeyboardEvent& aKeyboardEvent,
                       uint32_t aKeyFlags)
 {
   if (NS_WARN_IF(aKeyboardEvent.mCodeNameIndex == CODE_NAME_INDEX_USE_STRING)) {
--- a/widget/TextEventDispatcher.cpp
+++ b/widget/TextEventDispatcher.cpp
@@ -431,39 +431,44 @@ TextEventDispatcher::DispatchKeyboardEve
   if (aStatus == nsEventStatus_eConsumeNoDefault) {
     // If the key event should be dispatched as consumed event, marking it here.
     // This is useful to prevent double action.  E.g., when the key was already
     // handled by system, our chrome shouldn't handle it.
     keyEvent.mFlags.mDefaultPrevented = true;
   }
 
   // Corrects each member for the specific key event type.
-  if (aMessage == eKeyDown || aMessage == eKeyUp) {
-    MOZ_ASSERT(!aIndexOfKeypress,
-      "aIndexOfKeypress must be 0 for either eKeyDown or eKeyUp");
-    // charCode of keydown and keyup should be 0.
-    keyEvent.charCode = 0;
-  } else if (keyEvent.mKeyNameIndex != KEY_NAME_INDEX_USE_STRING) {
+  if (keyEvent.mKeyNameIndex != KEY_NAME_INDEX_USE_STRING) {
     MOZ_ASSERT(!aIndexOfKeypress,
-      "aIndexOfKeypress must be 0 for eKeyPress of non-printable key");
-    // If keypress event isn't caused by printable key, its charCode should
+      "aIndexOfKeypress must be 0 for non-printable key");
+    // If the keyboard event isn't caused by printable key, its charCode should
     // be 0.
-    keyEvent.charCode = 0;
+    keyEvent.SetCharCode(0);
   } else {
-    MOZ_RELEASE_ASSERT(
-      !aIndexOfKeypress || aIndexOfKeypress < keyEvent.mKeyValue.Length(),
-      "aIndexOfKeypress must be 0 - mKeyValue.Length() - 1");
-    keyEvent.keyCode = 0;
+    if (aMessage == eKeyDown || aMessage == eKeyUp) {
+      MOZ_RELEASE_ASSERT(!aIndexOfKeypress,
+        "aIndexOfKeypress must be 0 for either eKeyDown or eKeyUp");
+    } else {
+      MOZ_RELEASE_ASSERT(
+        !aIndexOfKeypress || aIndexOfKeypress < keyEvent.mKeyValue.Length(),
+        "aIndexOfKeypress must be 0 - mKeyValue.Length() - 1");
+    }
     wchar_t ch =
       keyEvent.mKeyValue.IsEmpty() ? 0 : keyEvent.mKeyValue[aIndexOfKeypress];
-    keyEvent.charCode = static_cast<uint32_t>(ch);
-    if (ch) {
-      keyEvent.mKeyValue.Assign(ch);
-    } else {
-      keyEvent.mKeyValue.Truncate();
+    keyEvent.SetCharCode(static_cast<uint32_t>(ch));
+    if (aMessage == eKeyPress) {
+      // keyCode of eKeyPress events of printable keys should be always 0.
+      keyEvent.keyCode = 0;
+      // eKeyPress events are dispatched for every character.
+      // So, each key value of eKeyPress events should be a character.
+      if (ch) {
+        keyEvent.mKeyValue.Assign(ch);
+      } else {
+        keyEvent.mKeyValue.Truncate();
+      }
     }
   }
   if (aMessage == eKeyUp) {
     // mIsRepeat of keyup event must be false.
     keyEvent.mIsRepeat = false;
   }
   // mIsComposing should be initialized later.
   keyEvent.mIsComposing = false;
@@ -475,19 +480,21 @@ TextEventDispatcher::DispatchKeyboardEve
     // If it's not a keyboard event for native key event, we should ensure that
     // mNativeKeyEvent and mPluginEvent are null/empty.
     keyEvent.mNativeKeyEvent = nullptr;
     keyEvent.mPluginEvent.Clear();
   }
   // TODO: Manage mUniqueId here.
 
   // Request the alternative char codes for the key event.
-  // XXX Currently, they are necessary only when the event is eKeyPress.
+  // eKeyDown also needs alternative char codes because nsXBLWindowKeyHandler
+  // needs to check if a following keypress event is reserved by chrome for
+  // stopping propagation of its preceding keydown event.
   keyEvent.alternativeCharCodes.Clear();
-  if (aMessage == eKeyPress &&
+  if ((aMessage == eKeyDown || aMessage == eKeyPress) &&
       (keyEvent.IsControl() || keyEvent.IsAlt() ||
        keyEvent.IsMeta() || keyEvent.IsOS())) {
     nsCOMPtr<TextEventDispatcherListener> listener =
       do_QueryReferent(mListener);
     if (listener) {
       DebugOnly<WidgetKeyboardEvent> original(keyEvent);
       listener->WillDispatchKeyboardEvent(this, keyEvent, aIndexOfKeypress,
                                           aData);
--- a/widget/TextEvents.h
+++ b/widget/TextEvents.h
@@ -99,16 +99,17 @@ class WidgetKeyboardEvent : public Widge
 private:
   friend class dom::PBrowserParent;
   friend class dom::PBrowserChild;
 
 protected:
   WidgetKeyboardEvent()
     : keyCode(0)
     , charCode(0)
+    , mPseudoCharCode(0)
     , location(nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD)
     , isChar(false)
     , mIsRepeat(false)
     , mIsComposing(false)
     , mKeyNameIndex(mozilla::KEY_NAME_INDEX_Unidentified)
     , mCodeNameIndex(CODE_NAME_INDEX_UNKNOWN)
     , mNativeKeyEvent(nullptr)
     , mUniqueId(0)
@@ -123,16 +124,17 @@ public:
   virtual WidgetKeyboardEvent* AsKeyboardEvent() override { return this; }
 
   WidgetKeyboardEvent(bool aIsTrusted, EventMessage aMessage,
                       nsIWidget* aWidget,
                       EventClassID aEventClassID = eKeyboardEventClass)
     : WidgetInputEvent(aIsTrusted, aMessage, aWidget, aEventClassID)
     , keyCode(0)
     , charCode(0)
+    , mPseudoCharCode(0)
     , location(nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD)
     , isChar(false)
     , mIsRepeat(false)
     , mIsComposing(false)
     , mKeyNameIndex(mozilla::KEY_NAME_INDEX_Unidentified)
     , mCodeNameIndex(CODE_NAME_INDEX_UNKNOWN)
     , mNativeKeyEvent(nullptr)
     , mUniqueId(0)
@@ -158,16 +160,20 @@ public:
   // A DOM keyCode value or 0.  If a keypress event whose charCode is 0, this
   // should be 0.
   uint32_t keyCode;
   // If the instance is a keypress event of a printable key, this is a UTF-16
   // value of the key.  Otherwise, 0.  This value must not be a control
   // character when some modifiers are active.  Then, this value should be an
   // unmodified value except Shift and AltGr.
   uint32_t charCode;
+  // mPseudoCharCode is valid only when mMessage is an eKeyDown event.
+  // This stores charCode value of keypress event which is fired with same
+  // key value and same modifier state.
+  uint32_t mPseudoCharCode;
   // One of nsIDOMKeyEvent::DOM_KEY_LOCATION_*
   uint32_t location;
   // OS translated Unicode chars which are used for accesskey and accelkey
   // handling. The handlers will try from first character to last character.
   nsTArray<AlternativeCharCode> alternativeCharCodes;
   // Indicates whether the event signifies a printable character
   bool isChar;
   // Indicates whether the event is generated by auto repeat or not.
@@ -204,16 +210,34 @@ public:
   // keyboard event.
   nsString mPluginTextEventString;
 #endif
 
   // If the key should cause keypress events, this returns true.
   // Otherwise, false.
   bool ShouldCauseKeypressEvents() const;
 
+  // charCode value of non-eKeyPress events is always 0.  However, if
+  // non-eKeyPress event has one or more alternative char code values,
+  // its first item should be the charCode value of following eKeyPress event.
+  // PseudoCharCode() returns charCode value for eKeyPress event,
+  // the first alternative char code value of non-eKeyPress event or 0.
+  uint32_t PseudoCharCode() const
+  {
+    return mMessage == eKeyPress ? charCode : mPseudoCharCode;
+  }
+  void SetCharCode(uint32_t aCharCode)
+  {
+    if (mMessage == eKeyPress) {
+      charCode = aCharCode;
+    } else {
+      mPseudoCharCode = aCharCode;
+    }
+  }
+
   void GetDOMKeyName(nsAString& aKeyName)
   {
     if (mKeyNameIndex == KEY_NAME_INDEX_USE_STRING) {
       aKeyName = mKeyValue;
       return;
     }
     GetDOMKeyName(mKeyNameIndex, aKeyName);
   }
@@ -287,16 +311,17 @@ public:
   static const char* GetCommandStr(Command aCommand);
 
   void AssignKeyEventData(const WidgetKeyboardEvent& aEvent, bool aCopyTargets)
   {
     AssignInputEventData(aEvent, aCopyTargets);
 
     keyCode = aEvent.keyCode;
     charCode = aEvent.charCode;
+    mPseudoCharCode = aEvent.mPseudoCharCode;
     location = aEvent.location;
     alternativeCharCodes = aEvent.alternativeCharCodes;
     isChar = aEvent.isChar;
     mIsRepeat = aEvent.mIsRepeat;
     mIsComposing = aEvent.mIsComposing;
     mKeyNameIndex = aEvent.mKeyNameIndex;
     mCodeNameIndex = aEvent.mCodeNameIndex;
     mKeyValue = aEvent.mKeyValue;
--- a/widget/WidgetEventImpl.cpp
+++ b/widget/WidgetEventImpl.cpp
@@ -478,41 +478,38 @@ IsCaseChangeableChar(uint32_t aChar)
 }
 
 void
 WidgetKeyboardEvent::GetShortcutKeyCandidates(
                        ShortcutKeyCandidateArray& aCandidates)
 {
   MOZ_ASSERT(aCandidates.IsEmpty(), "aCandidates must be empty");
 
-  if (mMessage != eKeyPress) {
-    return;
-  }
-
   // ShortcutKeyCandidate::mCharCode is a candidate charCode.
   // ShortcutKeyCandidate::mIgnoreShift means the mCharCode should be tried to
   // execute a command with/without shift key state. If this is TRUE, the
   // shifted key state should be ignored. Otherwise, don't ignore the state.
   // the priority of the charCodes are (shift key is not pressed):
-  //   0: charCode/false,
+  //   0: PseudoCharCode()/false,
   //   1: unshiftedCharCodes[0]/false, 2: unshiftedCharCodes[1]/false...
   // the priority of the charCodes are (shift key is pressed):
-  //   0: charCode/false,
+  //   0: PseudoCharCode()/false,
   //   1: shiftedCharCodes[0]/false, 2: shiftedCharCodes[0]/true,
   //   3: shiftedCharCodes[1]/false, 4: shiftedCharCodes[1]/true...
-  if (charCode) {
-    ShortcutKeyCandidate key(charCode, false);
+  uint32_t pseudoCharCode = PseudoCharCode();
+  if (pseudoCharCode) {
+    ShortcutKeyCandidate key(pseudoCharCode, false);
     aCandidates.AppendElement(key);
   }
 
   uint32_t len = alternativeCharCodes.Length();
   if (!IsShift()) {
     for (uint32_t i = 0; i < len; ++i) {
       uint32_t ch = alternativeCharCodes[i].mUnshiftedCharCode;
-      if (!ch || ch == charCode) {
+      if (!ch || ch == pseudoCharCode) {
         continue;
       }
       ShortcutKeyCandidate key(ch, false);
       aCandidates.AppendElement(key);
     }
     // If unshiftedCharCodes doesn't have numeric but shiftedCharCode has it,
     // this keyboard layout is AZERTY or similar layout, probably.
     // In this case, Accel+[0-9] should be accessible without shift key.
@@ -529,17 +526,17 @@ WidgetKeyboardEvent::GetShortcutKeyCandi
     }
   } else {
     for (uint32_t i = 0; i < len; ++i) {
       uint32_t ch = alternativeCharCodes[i].mShiftedCharCode;
       if (!ch) {
         continue;
       }
 
-      if (ch != charCode) {
+      if (ch != pseudoCharCode) {
         ShortcutKeyCandidate key(ch, false);
         aCandidates.AppendElement(key);
       }
 
       // If the char is an alphabet, the shift key state should not be
       // ignored. E.g., Ctrl+Shift+C should not execute Ctrl+C.
 
       // And checking the charCode is same as unshiftedCharCode too.
@@ -563,17 +560,17 @@ WidgetKeyboardEvent::GetShortcutKeyCandi
     }
   }
 
   // Special case for "Space" key.  With some keyboard layouts, "Space" with
   // or without Shift key causes non-ASCII space.  For such keyboard layouts,
   // we should guarantee that the key press works as an ASCII white space key
   // press.
   if (mCodeNameIndex == CODE_NAME_INDEX_Space &&
-      charCode != static_cast<uint32_t>(' ')) {
+      pseudoCharCode != static_cast<uint32_t>(' ')) {
     ShortcutKeyCandidate spaceKey(static_cast<uint32_t>(' '), false);
     aCandidates.AppendElement(spaceKey);
   }
 }
 
 void
 WidgetKeyboardEvent::GetAccessKeyCandidates(nsTArray<uint32_t>& aCandidates)
 {
--- a/widget/cocoa/TextInputHandler.mm
+++ b/widget/cocoa/TextInputHandler.mm
@@ -1053,16 +1053,24 @@ TISInputSourceWrapper::InitKeyEvent(NSEv
 void
 TISInputSourceWrapper::WillDispatchKeyboardEvent(
                          NSEvent* aNativeKeyEvent,
                          const nsAString* aInsertString,
                          WidgetKeyboardEvent& aKeyEvent)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
+  // Nothing to do here if the native key event is neither NSKeyDown nor
+  // NSKeyUp because accessing [aNativeKeyEvent characters] causes throwing
+  // an exception.
+  if ([aNativeKeyEvent type] != NSKeyDown &&
+      [aNativeKeyEvent type] != NSKeyUp) {
+    return;
+  }
+
   UInt32 kbType = GetKbdType();
 
   if (MOZ_LOG_TEST(gLog, LogLevel::Info)) {
     nsAutoString chars;
     nsCocoaUtils::GetStringForNSString([aNativeKeyEvent characters], chars);
     NS_ConvertUTF16toUTF8 utf8Chars(chars);
     char16_t uniChar = static_cast<char16_t>(aKeyEvent.charCode);
     MOZ_LOG(gLog, LogLevel::Info,
@@ -1074,32 +1082,26 @@ TISInputSourceWrapper::WillDispatchKeybo
        GetGeckoKeyEventType(aKeyEvent), aKeyEvent.charCode,
        uniChar ? NS_ConvertUTF16toUTF8(&uniChar, 1).get() : "",
        kbType, TrueOrFalse(IsOpenedIMEMode())));
   }
 
   nsAutoString insertStringForCharCode;
   ComputeInsertStringForCharCode(aNativeKeyEvent, aKeyEvent, aInsertString,
                                  insertStringForCharCode);
+
+  // The charCode was set from mKeyValue. However, for example, when Ctrl key
+  // is pressed, its value should indicate an ASCII character for backward
+  // compatibility rather than inputting character without the modifiers.
+  // Therefore, we need to modify charCode value here.
   uint32_t charCode =
     insertStringForCharCode.IsEmpty() ? 0 : insertStringForCharCode[0];
-  if (aKeyEvent.mMessage == eKeyPress) {
-    aKeyEvent.charCode = charCode;
-    aKeyEvent.isChar = true; // this is not a special key  XXX not used in XP
-  } else if (charCode) {
-    // If it's not a keypress event, we need to set alternative char code
-    // to charCode value for shortcut key event handlers.
-    AlternativeCharCode altCharCodes(0, 0);
-    if (!aKeyEvent.IsShift()) {
-      altCharCodes.mUnshiftedCharCode = charCode;
-    } else {
-      altCharCodes.mShiftedCharCode = charCode;
-    }
-    aKeyEvent.alternativeCharCodes.AppendElement(altCharCodes);
-  }
+  aKeyEvent.SetCharCode(charCode);
+  // this is not a special key  XXX not used in XP
+  aKeyEvent.isChar = (aKeyEvent.mMessage == eKeyPress);
 
   MOZ_LOG(gLog, LogLevel::Info,
     ("%p TISInputSourceWrapper::WillDispatchKeyboardEvent, "
      "aKeyEvent.keyCode=0x%X, aKeyEvent.charCode=0x%X",
      this, aKeyEvent.keyCode, aKeyEvent.charCode));
 
   TISInputSourceWrapper USLayout("com.apple.keylayout.US");
   bool isRomanKeyboardLayout = IsASCIICapable();
--- a/widget/gtk/nsGtkKeyUtils.cpp
+++ b/widget/gtk/nsGtkKeyUtils.cpp
@@ -1336,38 +1336,21 @@ KeymapWrapper::WillDispatchKeyboardEvent
     if (!charCode) {
         MOZ_LOG(gKeymapWrapperLog, LogLevel::Info,
             ("KeymapWrapper(%p): WillDispatchKeyboardEventInternal, "
              "keyCode=0x%02X, charCode=0x%08X",
              this, aKeyEvent.keyCode, aKeyEvent.charCode));
         return;
     }
 
-    AlternativeCharCode* firstAltCharCodes = nullptr;
-    if (aKeyEvent.mMessage == eKeyPress) {
-        // charCode of aKeyEvent is set from mKeyValue.  However, for backward
-        // compatibility, we may need to set it to other value, e.g., when
-        // Ctrl key is pressed.  Therefore, we need to overwrite the charCode
-        // here.
-        aKeyEvent.charCode = charCode;
-        MOZ_ASSERT(!aKeyEvent.keyCode);
-    } else {
-        MOZ_ASSERT(charCode);
-        // If it's not a keypress event, we need to set alternative char code
-        // to charCode value for shortcut key event handlers.
-        AlternativeCharCode altCharCodes(0, 0);
-        if (!aKeyEvent.IsShift()) {
-            altCharCodes.mUnshiftedCharCode = charCode;
-        } else {
-            altCharCodes.mShiftedCharCode = charCode;
-        }
-        MOZ_ASSERT(aKeyEvent.alternativeCharCodes.IsEmpty());
-        firstAltCharCodes =
-            aKeyEvent.alternativeCharCodes.AppendElement(altCharCodes);
-    }
+    // The charCode was set from mKeyValue. However, for example, when Ctrl key
+    // is pressed, its value should indicate an ASCII character for backward
+    // compatibility rather than inputting character without the modifiers.
+    // Therefore, we need to modify charCode value here.
+    aKeyEvent.SetCharCode(charCode);
 
     gint level = GetKeyLevel(aGdkKeyEvent);
     if (level != 0 && level != 1) {
         MOZ_LOG(gKeymapWrapperLog, LogLevel::Info,
             ("KeymapWrapper(%p): WillDispatchKeyboardEventInternal, "
              "keyCode=0x%02X, charCode=0x%08X, level=%d",
              this, aKeyEvent.keyCode, aKeyEvent.charCode, level));
         return;
@@ -1451,26 +1434,17 @@ KeymapWrapper::WillDispatchKeyboardEvent
     // If the charCode is not Latin, and the level is 0 or 1, we should
     // replace the charCode to Latin char if Alt and Meta keys are not
     // pressed. (Alt should be sent the localized char for accesskey
     // like handling of Web Applications.)
     ch = aKeyEvent.IsShift() ? altLatinCharCodes.mShiftedCharCode :
                                altLatinCharCodes.mUnshiftedCharCode;
     if (ch && !(aKeyEvent.IsAlt() || aKeyEvent.IsMeta()) &&
         charCode == unmodifiedCh) {
-        if (aKeyEvent.mMessage == eKeyPress) {
-            aKeyEvent.charCode = ch;
-        } else {
-            MOZ_RELEASE_ASSERT(firstAltCharCodes);
-            if (!aKeyEvent.IsShift()) {
-                firstAltCharCodes->mUnshiftedCharCode = ch;
-            } else {
-                firstAltCharCodes->mShiftedCharCode = ch;
-            }
-        }
+        aKeyEvent.SetCharCode(ch);
     }
 
     MOZ_LOG(gKeymapWrapperLog, LogLevel::Info,
         ("KeymapWrapper(%p): WillDispatchKeyboardEventInternal, "
          "keyCode=0x%02X, charCode=0x%08X, level=%d, minGroup=%d, "
          "altCharCodes={ mUnshiftedCharCode=0x%08X, "
          "mShiftedCharCode=0x%08X } "
          "altLatinCharCodes={ mUnshiftedCharCode=0x%08X, "
--- a/widget/nsGUIEventIPC.h
+++ b/widget/nsGUIEventIPC.h
@@ -373,16 +373,17 @@ struct ParamTraits<mozilla::WidgetKeyboa
   {
     WriteParam(aMsg, static_cast<mozilla::WidgetInputEvent>(aParam));
     WriteParam(aMsg, static_cast<uint32_t>(aParam.mKeyNameIndex));
     WriteParam(aMsg, static_cast<uint32_t>(aParam.mCodeNameIndex));
     WriteParam(aMsg, aParam.mKeyValue);
     WriteParam(aMsg, aParam.mCodeValue);
     WriteParam(aMsg, aParam.keyCode);
     WriteParam(aMsg, aParam.charCode);
+    WriteParam(aMsg, aParam.mPseudoCharCode);
     WriteParam(aMsg, aParam.alternativeCharCodes);
     WriteParam(aMsg, aParam.isChar);
     WriteParam(aMsg, aParam.mIsRepeat);
     WriteParam(aMsg, aParam.location);
     WriteParam(aMsg, aParam.mUniqueId);
 #ifdef XP_MACOSX
     WriteParam(aMsg, aParam.mNativeKeyCode);
     WriteParam(aMsg, aParam.mNativeModifierFlags);
@@ -400,16 +401,17 @@ struct ParamTraits<mozilla::WidgetKeyboa
     if (ReadParam(aMsg, aIter,
                   static_cast<mozilla::WidgetInputEvent*>(aResult)) &&
         ReadParam(aMsg, aIter, &keyNameIndex) &&
         ReadParam(aMsg, aIter, &codeNameIndex) &&
         ReadParam(aMsg, aIter, &aResult->mKeyValue) &&
         ReadParam(aMsg, aIter, &aResult->mCodeValue) &&
         ReadParam(aMsg, aIter, &aResult->keyCode) &&
         ReadParam(aMsg, aIter, &aResult->charCode) &&
+        ReadParam(aMsg, aIter, &aResult->mPseudoCharCode) &&
         ReadParam(aMsg, aIter, &aResult->alternativeCharCodes) &&
         ReadParam(aMsg, aIter, &aResult->isChar) &&
         ReadParam(aMsg, aIter, &aResult->mIsRepeat) &&
         ReadParam(aMsg, aIter, &aResult->location) &&
         ReadParam(aMsg, aIter, &aResult->mUniqueId)
 #ifdef XP_MACOSX
         && ReadParam(aMsg, aIter, &aResult->mNativeKeyCode)
         && ReadParam(aMsg, aIter, &aResult->mNativeModifierFlags)
--- a/widget/windows/KeyboardLayout.cpp
+++ b/widget/windows/KeyboardLayout.cpp
@@ -2222,34 +2222,22 @@ NativeKey::WillDispatchKeyboardEvent(Wid
       modKeyState.Unset(MODIFIER_SHIFT | MODIFIER_CONTROL | MODIFIER_ALT |
                         MODIFIER_ALTGRAPH | MODIFIER_CAPSLOCK);
       modKeyState.Set(
         mInputtingStringAndModifiers.mModifiers[aIndex - skipUniChars]);
       modKeyState.InitInputEvent(aKeyboardEvent);
     }
     uint16_t uniChar =
       mInputtingStringAndModifiers.mChars[aIndex - skipUniChars];
-    if (aKeyboardEvent.mMessage == eKeyPress) {
-      // charCode is set from mKeyValue but e.g., when Ctrl key is pressed,
-      // the value should indicate an ASCII character for backward
-      // compatibility instead of inputting character without the modifiers.
-      aKeyboardEvent.charCode = uniChar;
-      MOZ_ASSERT(!aKeyboardEvent.keyCode);
-    } else if (uniChar) {
-      // If the event is not keypress event, we should set charCode as
-      // first alternative char code since the char code value is necessary
-      // for shortcut key handlers at looking for a proper handler.
-      AlternativeCharCode chars(0, 0);
-      if (!aKeyboardEvent.IsShift()) {
-        chars.mUnshiftedCharCode = uniChar;
-      } else {
-        chars.mShiftedCharCode = uniChar;
-      }
-      altArray.AppendElement(chars);
-    }
+
+    // The charCode was set from mKeyValue. However, for example, when Ctrl key
+    // is pressed, its value should indicate an ASCII character for backward
+    // compatibility rather than inputting character without the modifiers.
+    // Therefore, we need to modify charCode value here.
+    aKeyboardEvent.SetCharCode(uniChar);
   }
 
   if (skipShiftedChars <= aIndex) {
     shiftedChar = mShiftedString.mChars[aIndex - skipShiftedChars];
   }
   if (skipUnshiftedChars <= aIndex) {
     unshiftedChar = mUnshiftedString.mChars[aIndex - skipUnshiftedChars];
   }