From 963976b46d93b08112154a5bd733b5967be77037 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Fri, 18 Mar 2016 11:22:37 +0900 Subject: [PATCH] Bug 1154183 part.1 Move shortcut/access key candidate list creators from nsContentUtils to WidgetKeyboardEvent r=smaug MozReview-Commit-ID: Ied6qEUc2Kz --- dom/base/nsContentUtils.cpp | 182 ------------------------------ dom/base/nsContentUtils.h | 30 ----- dom/events/EventStateManager.cpp | 2 +- dom/xbl/nsXBLEventHandler.cpp | 15 ++- dom/xbl/nsXBLWindowKeyHandler.cpp | 14 ++- layout/xul/nsMenuBarFrame.cpp | 5 +- layout/xul/nsMenuBarListener.cpp | 2 +- widget/EventForwards.h | 6 + widget/TextEvents.h | 36 ++++++ widget/WidgetEventImpl.cpp | 169 +++++++++++++++++++++++++++ 10 files changed, 234 insertions(+), 227 deletions(-) diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 5a199208fba5..ff35ae53296c 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -4905,188 +4905,6 @@ nsContentUtils::GetLocalizedEllipsis() return nsDependentString(sBuf); } -static bool -HasASCIIDigit(const nsTArray& aCandidates) -{ - for (uint32_t i = 0; i < aCandidates.Length(); ++i) { - uint32_t ch = aCandidates[i].mCharCode; - if (ch >= '0' && ch <= '9') - return true; - } - return false; -} - -static bool -CharsCaseInsensitiveEqual(uint32_t aChar1, uint32_t aChar2) -{ - return aChar1 == aChar2 || - (IS_IN_BMP(aChar1) && IS_IN_BMP(aChar2) && - ToLowerCase(char16_t(aChar1)) == ToLowerCase(char16_t(aChar2))); -} - -static bool -IsCaseChangeableChar(uint32_t aChar) -{ - return IS_IN_BMP(aChar) && - ToLowerCase(char16_t(aChar)) != ToUpperCase(char16_t(aChar)); -} - -/* static */ -void -nsContentUtils::GetAccelKeyCandidates(nsIDOMKeyEvent* aDOMKeyEvent, - nsTArray& aCandidates) -{ - NS_PRECONDITION(aCandidates.IsEmpty(), "aCandidates must be empty"); - - nsAutoString eventType; - aDOMKeyEvent->AsEvent()->GetType(eventType); - // Don't process if aDOMKeyEvent is not a keypress event. - if (!eventType.EqualsLiteral("keypress")) - return; - - WidgetKeyboardEvent* nativeKeyEvent = - aDOMKeyEvent->AsEvent()->WidgetEventPtr()->AsKeyboardEvent(); - if (nativeKeyEvent) { - NS_ASSERTION(nativeKeyEvent->mClass == eKeyboardEventClass, - "wrong type of native event"); - // nsShortcutCandidate::mCharCode is a candidate charCode. - // nsShoftcutCandidate::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, - // 1: unshiftedCharCodes[0]/false, 2: unshiftedCharCodes[1]/false... - // the priority of the charCodes are (shift key is pressed): - // 0: charCode/false, - // 1: shiftedCharCodes[0]/false, 2: shiftedCharCodes[0]/true, - // 3: shiftedCharCodes[1]/false, 4: shiftedCharCodes[1]/true... - if (nativeKeyEvent->charCode) { - nsShortcutCandidate key(nativeKeyEvent->charCode, false); - aCandidates.AppendElement(key); - } - - uint32_t len = nativeKeyEvent->alternativeCharCodes.Length(); - if (!nativeKeyEvent->IsShift()) { - for (uint32_t i = 0; i < len; ++i) { - uint32_t ch = - nativeKeyEvent->alternativeCharCodes[i].mUnshiftedCharCode; - if (!ch || ch == nativeKeyEvent->charCode) - continue; - - nsShortcutCandidate 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. - // However, the priority should be lowest. - if (!HasASCIIDigit(aCandidates)) { - for (uint32_t i = 0; i < len; ++i) { - uint32_t ch = - nativeKeyEvent->alternativeCharCodes[i].mShiftedCharCode; - if (ch >= '0' && ch <= '9') { - nsShortcutCandidate key(ch, false); - aCandidates.AppendElement(key); - break; - } - } - } - } else { - for (uint32_t i = 0; i < len; ++i) { - uint32_t ch = nativeKeyEvent->alternativeCharCodes[i].mShiftedCharCode; - if (!ch) - continue; - - if (ch != nativeKeyEvent->charCode) { - nsShortcutCandidate 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. - // E.g., for Ctrl+Shift+(Plus of Numpad) should not run Ctrl+Plus. - uint32_t unshiftCh = - nativeKeyEvent->alternativeCharCodes[i].mUnshiftedCharCode; - if (CharsCaseInsensitiveEqual(ch, unshiftCh)) - continue; - - // On the Hebrew keyboard layout on Windows, the unshifted char is a - // localized character but the shifted char is a Latin alphabet, - // then, we should not execute without the shift state. See bug 433192. - if (IsCaseChangeableChar(ch)) - continue; - - // Setting the alternative charCode candidates for retry without shift - // key state only when the shift key is pressed. - nsShortcutCandidate key(ch, true); - aCandidates.AppendElement(key); - } - } - - // 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 (nativeKeyEvent->mCodeNameIndex == CODE_NAME_INDEX_Space && - nativeKeyEvent->charCode != static_cast(' ')) { - nsShortcutCandidate spaceKey(static_cast(' '), false); - aCandidates.AppendElement(spaceKey); - } - } else { - uint32_t charCode; - aDOMKeyEvent->GetCharCode(&charCode); - if (charCode) { - nsShortcutCandidate key(charCode, false); - aCandidates.AppendElement(key); - } - } -} - -/* static */ -void -nsContentUtils::GetAccessKeyCandidates(WidgetKeyboardEvent* aNativeKeyEvent, - nsTArray& aCandidates) -{ - NS_PRECONDITION(aCandidates.IsEmpty(), "aCandidates must be empty"); - - // return the lower cased charCode candidates for access keys. - // the priority of the charCodes are: - // 0: charCode, 1: unshiftedCharCodes[0], 2: shiftedCharCodes[0] - // 3: unshiftedCharCodes[1], 4: shiftedCharCodes[1],... - if (aNativeKeyEvent->charCode) { - uint32_t ch = aNativeKeyEvent->charCode; - if (IS_IN_BMP(ch)) - ch = ToLowerCase(char16_t(ch)); - aCandidates.AppendElement(ch); - } - for (uint32_t i = 0; - i < aNativeKeyEvent->alternativeCharCodes.Length(); ++i) { - uint32_t ch[2] = - { aNativeKeyEvent->alternativeCharCodes[i].mUnshiftedCharCode, - aNativeKeyEvent->alternativeCharCodes[i].mShiftedCharCode }; - for (uint32_t j = 0; j < 2; ++j) { - if (!ch[j]) - continue; - if (IS_IN_BMP(ch[j])) - ch[j] = ToLowerCase(char16_t(ch[j])); - // Don't append the charCode that was already appended. - if (aCandidates.IndexOf(ch[j]) == aCandidates.NoIndex) - aCandidates.AppendElement(ch[j]); - } - } - // 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 (aNativeKeyEvent->mCodeNameIndex == CODE_NAME_INDEX_Space && - aNativeKeyEvent->charCode != static_cast(' ')) { - aCandidates.AppendElement(static_cast(' ')); - } - return; -} - /* static */ void nsContentUtils::AddScriptBlocker() diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 86222aacb848..23251a5a57d0 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -171,15 +171,6 @@ struct EventNameMapping mozilla::EventClassID mEventClassID; }; -struct nsShortcutCandidate { - nsShortcutCandidate(uint32_t aCharCode, bool aIgnoreShift) : - mCharCode(aCharCode), mIgnoreShift(aIgnoreShift) - { - } - uint32_t mCharCode; - bool mIgnoreShift; -}; - typedef void (*CallOnRemoteChildFunction) (mozilla::dom::TabParent* aTabParent, void* aArg); @@ -1511,27 +1502,6 @@ public: */ static const nsDependentString GetLocalizedEllipsis(); - /** - * Get the candidates for accelkeys for aDOMKeyEvent. - * - * @param aDOMKeyEvent [in] the key event for accelkey handling. - * @param aCandidates [out] the candidate shortcut key combination list. - * the first item is most preferred. - */ - static void GetAccelKeyCandidates(nsIDOMKeyEvent* aDOMKeyEvent, - nsTArray& aCandidates); - - /** - * Get the candidates for accesskeys for aNativeKeyEvent. - * - * @param aNativeKeyEvent [in] the key event for accesskey handling. - * @param aCandidates [out] the candidate access key list. - * the first item is most preferred. - */ - static void GetAccessKeyCandidates( - mozilla::WidgetKeyboardEvent* aNativeKeyEvent, - nsTArray& aCandidates); - /** * Hide any XUL popups associated with aDocument, including any documents * displayed in child frames. Does nothing if aDocument is null. diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index a041de871088..2d04902961c9 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -733,7 +733,7 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext, (modifierMask == Prefs::ChromeAccessModifierMask() || modifierMask == Prefs::ContentAccessModifierMask())) { AutoTArray accessCharCodes; - nsContentUtils::GetAccessKeyCandidates(keyEvent, accessCharCodes); + keyEvent->GetAccessKeyCandidates(accessCharCodes); if (HandleAccessKey(aPresContext, accessCharCodes, keyEvent->mFlags.mIsTrusted, modifierMask)) { diff --git a/dom/xbl/nsXBLEventHandler.cpp b/dom/xbl/nsXBLEventHandler.cpp index 064d672e4ba1..09914052e0e7 100644 --- a/dom/xbl/nsXBLEventHandler.cpp +++ b/dom/xbl/nsXBLEventHandler.cpp @@ -140,18 +140,21 @@ nsXBLKeyEventHandler::HandleEvent(nsIDOMEvent* aEvent) if (!key) return NS_OK; - AutoTArray accessKeys; - nsContentUtils::GetAccelKeyCandidates(key, accessKeys); + WidgetKeyboardEvent* nativeKeyboardEvent = + aEvent->WidgetEventPtr()->AsKeyboardEvent(); + MOZ_ASSERT(nativeKeyboardEvent); + AutoShortcutKeyCandidateArray shortcutKeys; + nativeKeyboardEvent->GetShortcutKeyCandidates(shortcutKeys); - if (accessKeys.IsEmpty()) { + if (shortcutKeys.IsEmpty()) { ExecuteMatchedHandlers(key, 0, IgnoreModifierState()); return NS_OK; } - for (uint32_t i = 0; i < accessKeys.Length(); ++i) { + for (uint32_t i = 0; i < shortcutKeys.Length(); ++i) { IgnoreModifierState ignoreModifierState; - ignoreModifierState.mShift = accessKeys[i].mIgnoreShift; - if (ExecuteMatchedHandlers(key, accessKeys[i].mCharCode, + ignoreModifierState.mShift = shortcutKeys[i].mIgnoreShift; + if (ExecuteMatchedHandlers(key, shortcutKeys[i].mCharCode, ignoreModifierState)) { return NS_OK; } diff --git a/dom/xbl/nsXBLWindowKeyHandler.cpp b/dom/xbl/nsXBLWindowKeyHandler.cpp index 676948bfa843..a1d9d0bdcf22 100644 --- a/dom/xbl/nsXBLWindowKeyHandler.cpp +++ b/dom/xbl/nsXBLWindowKeyHandler.cpp @@ -543,17 +543,21 @@ nsXBLWindowKeyHandler::WalkHandlersInternal(nsIDOMKeyEvent* aKeyEvent, bool aExecute, bool* aOutReservedForChrome) { - AutoTArray accessKeys; - nsContentUtils::GetAccelKeyCandidates(aKeyEvent, accessKeys); + WidgetKeyboardEvent* nativeKeyboardEvent = + aKeyEvent->AsEvent()->WidgetEventPtr()->AsKeyboardEvent(); + MOZ_ASSERT(nativeKeyboardEvent); - if (accessKeys.IsEmpty()) { + AutoShortcutKeyCandidateArray shortcutKeys; + nativeKeyboardEvent->GetShortcutKeyCandidates(shortcutKeys); + + if (shortcutKeys.IsEmpty()) { return WalkHandlersAndExecute(aKeyEvent, aEventType, aHandler, 0, IgnoreModifierState(), aExecute, aOutReservedForChrome); } - for (uint32_t i = 0; i < accessKeys.Length(); ++i) { - nsShortcutCandidate &key = accessKeys[i]; + for (uint32_t i = 0; i < shortcutKeys.Length(); ++i) { + ShortcutKeyCandidate& key = shortcutKeys[i]; IgnoreModifierState ignoreModifierState; ignoreModifierState.mShift = key.mIgnoreShift; if (WalkHandlersAndExecute(aKeyEvent, aEventType, aHandler, diff --git a/layout/xul/nsMenuBarFrame.cpp b/layout/xul/nsMenuBarFrame.cpp index 451786280ab0..03ce9fbe355d 100644 --- a/layout/xul/nsMenuBarFrame.cpp +++ b/layout/xul/nsMenuBarFrame.cpp @@ -167,8 +167,9 @@ nsMenuBarFrame::FindMenuWithShortcut(nsIDOMKeyEvent* aKeyEvent) AutoTArray accessKeys; WidgetKeyboardEvent* nativeKeyEvent = aKeyEvent->AsEvent()->WidgetEventPtr()->AsKeyboardEvent(); - if (nativeKeyEvent) - nsContentUtils::GetAccessKeyCandidates(nativeKeyEvent, accessKeys); + if (nativeKeyEvent) { + nativeKeyEvent->GetAccessKeyCandidates(accessKeys); + } if (accessKeys.IsEmpty() && charCode) accessKeys.AppendElement(charCode); diff --git a/layout/xul/nsMenuBarListener.cpp b/layout/xul/nsMenuBarListener.cpp index 512479ca6769..050612e6a76e 100644 --- a/layout/xul/nsMenuBarListener.cpp +++ b/layout/xul/nsMenuBarListener.cpp @@ -222,7 +222,7 @@ nsMenuBarListener::KeyPress(nsIDOMEvent* aKeyEvent) aKeyEvent->WidgetEventPtr()->AsKeyboardEvent(); if (nativeKeyEvent) { AutoTArray keys; - nsContentUtils::GetAccessKeyCandidates(nativeKeyEvent, keys); + nativeKeyEvent->GetAccessKeyCandidates(keys); hasAccessKeyCandidates = !keys.IsEmpty(); } } diff --git a/widget/EventForwards.h b/widget/EventForwards.h index 321f28b78e0c..64fc4a29a8b5 100644 --- a/widget/EventForwards.h +++ b/widget/EventForwards.h @@ -8,6 +8,8 @@ #include +#include "nsTArray.h" + /** * XXX Following enums should be in BasicEvents.h. However, currently, it's * impossible to use foward delearation for enum. @@ -139,6 +141,10 @@ class WidgetEventTime; // TextEvents.h struct AlternativeCharCode; +struct ShortcutKeyCandidate; + +typedef nsTArray ShortcutKeyCandidateArray; +typedef AutoTArray AutoShortcutKeyCandidateArray; // TextRange.h struct TextRangeStyle; diff --git a/widget/TextEvents.h b/widget/TextEvents.h index 8308bcd1bb5f..64465d7be416 100644 --- a/widget/TextEvents.h +++ b/widget/TextEvents.h @@ -70,6 +70,26 @@ struct AlternativeCharCode uint32_t mShiftedCharCode; }; +/****************************************************************************** + * mozilla::ShortcutKeyCandidate + * + * This stores a candidate of shortcut key combination. + ******************************************************************************/ + +struct ShortcutKeyCandidate +{ + ShortcutKeyCandidate(uint32_t aCharCode, bool aIgnoreShift) + : mCharCode(aCharCode) + , mIgnoreShift(aIgnoreShift) + { + } + // The charCode value which must match keyboard shortcut definition. + uint32_t mCharCode; + // true if Shift state can be ignored. Otherwise, Shift key state must + // match keyboard shortcut definition. + bool mIgnoreShift; +}; + /****************************************************************************** * mozilla::WidgetKeyboardEvent ******************************************************************************/ @@ -211,6 +231,22 @@ public: return GetModifierForKeyName(mKeyNameIndex) != MODIFIER_NONE; } + /** + * Get the candidates for shortcut key. + * + * @param aCandidates [out] the candidate shortcut key combination list. + * the first item is most preferred. + */ + void GetShortcutKeyCandidates(ShortcutKeyCandidateArray& aCandidates); + + /** + * Get the candidates for access key. + * + * @param aCandidates [out] the candidate access key list. + * the first item is most preferred. + */ + void GetAccessKeyCandidates(nsTArray& aCandidates); + static void Shutdown(); /** diff --git a/widget/WidgetEventImpl.cpp b/widget/WidgetEventImpl.cpp index 18ce911bf001..e3ced7d8c0a1 100644 --- a/widget/WidgetEventImpl.cpp +++ b/widget/WidgetEventImpl.cpp @@ -449,6 +449,175 @@ WidgetKeyboardEvent::ShouldCauseKeypressEvents() const } } +static bool +HasASCIIDigit(const ShortcutKeyCandidateArray& aCandidates) +{ + for (uint32_t i = 0; i < aCandidates.Length(); ++i) { + uint32_t ch = aCandidates[i].mCharCode; + if (ch >= '0' && ch <= '9') + return true; + } + return false; +} + +static bool +CharsCaseInsensitiveEqual(uint32_t aChar1, uint32_t aChar2) +{ + return aChar1 == aChar2 || + (IS_IN_BMP(aChar1) && IS_IN_BMP(aChar2) && + ToLowerCase(static_cast(aChar1)) == + ToLowerCase(static_cast(aChar2))); +} + +static bool +IsCaseChangeableChar(uint32_t aChar) +{ + return IS_IN_BMP(aChar) && + ToLowerCase(static_cast(aChar)) != + ToUpperCase(static_cast(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, + // 1: unshiftedCharCodes[0]/false, 2: unshiftedCharCodes[1]/false... + // the priority of the charCodes are (shift key is pressed): + // 0: charCode/false, + // 1: shiftedCharCodes[0]/false, 2: shiftedCharCodes[0]/true, + // 3: shiftedCharCodes[1]/false, 4: shiftedCharCodes[1]/true... + if (charCode) { + ShortcutKeyCandidate key(charCode, 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) { + 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. + // However, the priority should be lowest. + if (!HasASCIIDigit(aCandidates)) { + for (uint32_t i = 0; i < len; ++i) { + uint32_t ch = alternativeCharCodes[i].mShiftedCharCode; + if (ch >= '0' && ch <= '9') { + ShortcutKeyCandidate key(ch, false); + aCandidates.AppendElement(key); + break; + } + } + } + } else { + for (uint32_t i = 0; i < len; ++i) { + uint32_t ch = alternativeCharCodes[i].mShiftedCharCode; + if (!ch) { + continue; + } + + if (ch != charCode) { + 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. + // E.g., for Ctrl+Shift+(Plus of Numpad) should not run Ctrl+Plus. + uint32_t unshiftCh = alternativeCharCodes[i].mUnshiftedCharCode; + if (CharsCaseInsensitiveEqual(ch, unshiftCh)) { + continue; + } + + // On the Hebrew keyboard layout on Windows, the unshifted char is a + // localized character but the shifted char is a Latin alphabet, + // then, we should not execute without the shift state. See bug 433192. + if (IsCaseChangeableChar(ch)) { + continue; + } + + // Setting the alternative charCode candidates for retry without shift + // key state only when the shift key is pressed. + ShortcutKeyCandidate key(ch, true); + aCandidates.AppendElement(key); + } + } + + // 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(' ')) { + ShortcutKeyCandidate spaceKey(static_cast(' '), false); + aCandidates.AppendElement(spaceKey); + } +} + +void +WidgetKeyboardEvent::GetAccessKeyCandidates(nsTArray& aCandidates) +{ + MOZ_ASSERT(aCandidates.IsEmpty(), "aCandidates must be empty"); + + // return the lower cased charCode candidates for access keys. + // the priority of the charCodes are: + // 0: charCode, 1: unshiftedCharCodes[0], 2: shiftedCharCodes[0] + // 3: unshiftedCharCodes[1], 4: shiftedCharCodes[1],... + if (charCode) { + uint32_t ch = charCode; + if (IS_IN_BMP(ch)) { + ch = ToLowerCase(static_cast(ch)); + } + aCandidates.AppendElement(ch); + } + for (uint32_t i = 0; i < alternativeCharCodes.Length(); ++i) { + uint32_t ch[2] = + { alternativeCharCodes[i].mUnshiftedCharCode, + alternativeCharCodes[i].mShiftedCharCode }; + for (uint32_t j = 0; j < 2; ++j) { + if (!ch[j]) { + continue; + } + if (IS_IN_BMP(ch[j])) { + ch[j] = ToLowerCase(static_cast(ch[j])); + } + // Don't append the charCode that was already appended. + if (aCandidates.IndexOf(ch[j]) == aCandidates.NoIndex) { + aCandidates.AppendElement(ch[j]); + } + } + } + // 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(' ')) { + aCandidates.AppendElement(static_cast(' ')); + } + return; +} + /* static */ void WidgetKeyboardEvent::Shutdown() {