Log Message
[Win] Update KeyboardEvent as per the latest specification https://bugs.webkit.org/show_bug.cgi?id=202183
Reviewed by Ross Kirsling. Source/WebCore: Add 'key' and 'code' properties of KeyboardEvent for Windows. The implementation is copied from Chromium for Windows. For implementing 'key' properties, ToUnicodeEx API is used to convert a virtual key code to a character information. Unfortunately, ToUnicodeEx alters the stored previous typed dead key in the driver, it can't be used for each key event. So, ToUnicodeEx is used to convert all virtual keys with all modifier combinations beforehand. This change turns on ENABLE_KEYBOARD_KEY_ATTRIBUTE and ENABLE_KEYBOARD_CODE_ATTRIBUTE macros for all ports. A follow-up patch will remove the macros. Existing tests covers. * PlatformWin.cmake: * platform/win/KeyEventWin.cpp: (WebCore::windowsKeyNames): (WebCore::PlatformKeyboardEvent::PlatformKeyboardEvent): * platform/win/WindowsKeyNames.cpp: Added. (hasControlAndAlt): (getModifierFlags): (nonPrintableVirtualKeyToDomKey): (WindowsKeyNames::WindowsKeyNames): (WindowsKeyNames::domKeyFromLParam): (singleCharacterString): (WindowsKeyNames::domKeyFromChar): (WindowsKeyNames::domCodeFromLParam): (WindowsKeyNames::updateLayout): * platform/win/WindowsKeyNames.h: Added. Source/WebKit: * Shared/WebEvent.h: * Shared/WebKeyboardEvent.cpp: (WebKit::WebKeyboardEvent::WebKeyboardEvent): * Shared/win/WebEventFactory.cpp: (WebKit::windowsKeyNames): (WebKit::WebEventFactory::createWebKeyboardEvent): Source/WTF: * wtf/FeatureDefines.h: LayoutTests: * platform/win/TestExpectations: * platform/wincairo/TestExpectations: Unskipped fast/events/arrow-keys-on-body.html, fast/events/keyboardevent-key.html, and fast/events/key-events-in-input-text.html.
Modified Paths
- trunk/LayoutTests/ChangeLog
- trunk/LayoutTests/platform/win/TestExpectations
- trunk/LayoutTests/platform/wincairo/TestExpectations
- trunk/Source/WTF/ChangeLog
- trunk/Source/WTF/wtf/FeatureDefines.h
- trunk/Source/WebCore/ChangeLog
- trunk/Source/WebCore/PlatformWin.cmake
- trunk/Source/WebCore/platform/win/KeyEventWin.cpp
- trunk/Source/WebKit/ChangeLog
- trunk/Source/WebKit/Shared/WebEvent.h
- trunk/Source/WebKit/Shared/WebKeyboardEvent.cpp
- trunk/Source/WebKit/Shared/win/WebEventFactory.cpp
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (252872 => 252873)
--- trunk/LayoutTests/ChangeLog 2019-11-26 02:56:33 UTC (rev 252872)
+++ trunk/LayoutTests/ChangeLog 2019-11-26 05:18:54 UTC (rev 252873)
@@ -1,3 +1,14 @@
+2019-11-25 Fujii Hironori <[email protected]>
+
+ [Win] Update KeyboardEvent as per the latest specification
+ https://bugs.webkit.org/show_bug.cgi?id=202183
+
+ Reviewed by Ross Kirsling.
+
+ * platform/win/TestExpectations:
+ * platform/wincairo/TestExpectations:
+ Unskipped fast/events/arrow-keys-on-body.html, fast/events/keyboardevent-key.html, and fast/events/key-events-in-input-text.html.
+
2019-11-25 Zan Dobersek <[email protected]> and Chris Lord <[email protected]>
Basic OffscreenCanvas functionality
Modified: trunk/LayoutTests/platform/win/TestExpectations (252872 => 252873)
--- trunk/LayoutTests/platform/win/TestExpectations 2019-11-26 02:56:33 UTC (rev 252872)
+++ trunk/LayoutTests/platform/win/TestExpectations 2019-11-26 05:18:54 UTC (rev 252873)
@@ -3234,7 +3234,6 @@
fast/dom/HTMLProgressElement/progress-bar-value-pseudo-element.html [ Failure ]
fast/dom/Window/get-set-properties.html [ Failure ]
fast/dom/Window/window-lookup-precedence.html [ Failure ]
-fast/events/arrow-keys-on-body.html [ Failure ]
fast/events/before-input-events-prevent-drag-and-drop.html [ Failure ]
fast/events/constructors/keyboard-event-constructor.html [ Failure ]
fast/events/constructors/overconstrained-error-event-constructor.html [ Failure ]
@@ -3245,9 +3244,7 @@
fast/events/ime-compositionend-on-selection-change.html [ Failure ]
fast/events/input-events-paste-rich-datatransfer.html [ Failure ]
fast/events/key-events-in-input-button.html [ Failure ]
-fast/events/key-events-in-input-text.html [ Failure ]
fast/events/keyboardevent-code.html [ Failure ]
-fast/events/keyboardevent-key.html [ Failure ]
fast/events/updateLayoutForHitTest.html [ Failure ]
fast/events/wheelevent-basic.html [ Failure ]
fast/forms/listbox-respects-padding-bottom.html [ Failure ]
Modified: trunk/LayoutTests/platform/wincairo/TestExpectations (252872 => 252873)
--- trunk/LayoutTests/platform/wincairo/TestExpectations 2019-11-26 02:56:33 UTC (rev 252872)
+++ trunk/LayoutTests/platform/wincairo/TestExpectations 2019-11-26 05:18:54 UTC (rev 252873)
@@ -1636,7 +1636,6 @@
fast/css/will-change/will-change-creates-stacking-context.html [ ImageOnlyFailure ]
fast/dom/adopt-attribute-crash.svg [ Failure ]
fast/dom/navigator-property-gc-after-frame-detach.html [ Failure ]
-fast/events/arrow-keys-on-body.html [ Failure ]
fast/events/attempt-scroll-with-no-scrollbars.html [ Failure ]
fast/events/autoscroll-when-input-is-offscreen.html [ Skip ] # UIScript
fast/events/autoscroll-with-software-keyboard.html [ Skip ] # UIScript
@@ -1672,9 +1671,7 @@
fast/events/input-events-paste-data.html [ Pass Failure ]
fast/events/input-events-paste-rich-datatransfer.html [ Failure ]
fast/events/key-events-in-input-button.html [ Failure ]
-fast/events/key-events-in-input-text.html [ Failure ]
fast/events/keyboardevent-code.html [ Failure ]
-fast/events/keyboardevent-key.html [ Failure ]
fast/events/keydown-numpad-keys.html [ Failure ]
fast/events/mouse-cursor-image-set.html [ Failure ]
fast/events/mouseover-button.html [ Failure ]
Modified: trunk/Source/WTF/ChangeLog (252872 => 252873)
--- trunk/Source/WTF/ChangeLog 2019-11-26 02:56:33 UTC (rev 252872)
+++ trunk/Source/WTF/ChangeLog 2019-11-26 05:18:54 UTC (rev 252873)
@@ -1,5 +1,14 @@
2019-11-25 Fujii Hironori <[email protected]>
+ [Win] Update KeyboardEvent as per the latest specification
+ https://bugs.webkit.org/show_bug.cgi?id=202183
+
+ Reviewed by Ross Kirsling.
+
+ * wtf/FeatureDefines.h:
+
+2019-11-25 Fujii Hironori <[email protected]>
+
Add DefaultHash<OptionSet<T>> and HashTrait<OptionSet<T>> specializations
https://bugs.webkit.org/show_bug.cgi?id=204562
Modified: trunk/Source/WTF/wtf/FeatureDefines.h (252872 => 252873)
--- trunk/Source/WTF/wtf/FeatureDefines.h 2019-11-26 02:56:33 UTC (rev 252872)
+++ trunk/Source/WTF/wtf/FeatureDefines.h 2019-11-26 05:18:54 UTC (rev 252873)
@@ -751,11 +751,11 @@
#endif
#if !defined(ENABLE_KEYBOARD_KEY_ATTRIBUTE)
-#define ENABLE_KEYBOARD_KEY_ATTRIBUTE 0
+#define ENABLE_KEYBOARD_KEY_ATTRIBUTE 1
#endif
#if !defined(ENABLE_KEYBOARD_CODE_ATTRIBUTE)
-#define ENABLE_KEYBOARD_CODE_ATTRIBUTE 0
+#define ENABLE_KEYBOARD_CODE_ATTRIBUTE 1
#endif
#if !defined(ENABLE_DATA_INTERACTION)
Modified: trunk/Source/WebCore/ChangeLog (252872 => 252873)
--- trunk/Source/WebCore/ChangeLog 2019-11-26 02:56:33 UTC (rev 252872)
+++ trunk/Source/WebCore/ChangeLog 2019-11-26 05:18:54 UTC (rev 252873)
@@ -1,3 +1,42 @@
+2019-11-25 Fujii Hironori <[email protected]>
+
+ [Win] Update KeyboardEvent as per the latest specification
+ https://bugs.webkit.org/show_bug.cgi?id=202183
+
+ Reviewed by Ross Kirsling.
+
+ Add 'key' and 'code' properties of KeyboardEvent for Windows. The
+ implementation is copied from Chromium for Windows.
+
+ For implementing 'key' properties, ToUnicodeEx API is used to
+ convert a virtual key code to a character information.
+ Unfortunately, ToUnicodeEx alters the stored previous typed dead
+ key in the driver, it can't be used for each key event. So,
+ ToUnicodeEx is used to convert all virtual keys with all modifier
+ combinations beforehand.
+
+ This change turns on ENABLE_KEYBOARD_KEY_ATTRIBUTE and
+ ENABLE_KEYBOARD_CODE_ATTRIBUTE macros for all ports. A follow-up
+ patch will remove the macros.
+
+ Existing tests covers.
+
+ * PlatformWin.cmake:
+ * platform/win/KeyEventWin.cpp:
+ (WebCore::windowsKeyNames):
+ (WebCore::PlatformKeyboardEvent::PlatformKeyboardEvent):
+ * platform/win/WindowsKeyNames.cpp: Added.
+ (hasControlAndAlt):
+ (getModifierFlags):
+ (nonPrintableVirtualKeyToDomKey):
+ (WindowsKeyNames::WindowsKeyNames):
+ (WindowsKeyNames::domKeyFromLParam):
+ (singleCharacterString):
+ (WindowsKeyNames::domKeyFromChar):
+ (WindowsKeyNames::domCodeFromLParam):
+ (WindowsKeyNames::updateLayout):
+ * platform/win/WindowsKeyNames.h: Added.
+
2019-11-25 Zalan Bujtas <[email protected]>
[LFC][IFC] Use FontCascade::spaceWidth to measure single or collapsed whitespace content
Modified: trunk/Source/WebCore/PlatformWin.cmake (252872 => 252873)
--- trunk/Source/WebCore/PlatformWin.cmake 2019-11-26 02:56:33 UTC (rev 252872)
+++ trunk/Source/WebCore/PlatformWin.cmake 2019-11-26 05:18:54 UTC (rev 252873)
@@ -107,6 +107,7 @@
platform/win/WheelEventWin.cpp
platform/win/WidgetWin.cpp
platform/win/WindowMessageBroadcaster.cpp
+ platform/win/WindowsKeyNames.cpp
rendering/RenderThemeWin.cpp
)
@@ -142,6 +143,7 @@
platform/win/WebCoreTextRenderer.h
platform/win/WindowMessageBroadcaster.h
platform/win/WindowMessageListener.h
+ platform/win/WindowsKeyNames.h
platform/win/WindowsTouch.h
)
Modified: trunk/Source/WebCore/platform/win/KeyEventWin.cpp (252872 => 252873)
--- trunk/Source/WebCore/platform/win/KeyEventWin.cpp 2019-11-26 02:56:33 UTC (rev 252872)
+++ trunk/Source/WebCore/platform/win/KeyEventWin.cpp 2019-11-26 05:18:54 UTC (rev 252873)
@@ -26,6 +26,7 @@
#include "config.h"
#include "PlatformKeyboardEvent.h"
+#include "WindowsKeyNames.h"
#include <windows.h>
#include <wtf/ASCIICType.h>
#include <wtf/HexNumber.h>
@@ -218,10 +219,18 @@
return String(&c, 1);
}
+static WindowsKeyNames& windowsKeyNames()
+{
+ static NeverDestroyed<WindowsKeyNames> keyNames;
+ return keyNames;
+}
+
PlatformKeyboardEvent::PlatformKeyboardEvent(HWND, WPARAM code, LPARAM keyData, Type type, bool systemKey)
: PlatformEvent(type, GetKeyState(VK_SHIFT) & HIGH_BIT_MASK_SHORT, GetKeyState(VK_CONTROL) & HIGH_BIT_MASK_SHORT, GetKeyState(VK_MENU) & HIGH_BIT_MASK_SHORT, false, WallTime::fromRawSeconds(::GetTickCount() * 0.001))
, m_text((type == PlatformEvent::Char) ? singleCharacterString(code) : String())
, m_unmodifiedText((type == PlatformEvent::Char) ? singleCharacterString(code) : String())
+ , m_key(type == PlatformEvent::Char ? windowsKeyNames().domKeyFromChar(code) : windowsKeyNames().domKeyFromLParam(keyData))
+ , m_code(windowsKeyNames().domCodeFromLParam(keyData))
, m_keyIdentifier((type == PlatformEvent::Char) ? String() : keyIdentifierForWindowsKeyCode(code))
, m_windowsVirtualKeyCode((type == RawKeyDown || type == KeyUp) ? windowsKeycodeWithLocation(code, keyData) : 0)
, m_autoRepeat(HIWORD(keyData) & KF_REPEAT)
Added: trunk/Source/WebCore/platform/win/WindowsKeyNames.cpp (0 => 252873)
--- trunk/Source/WebCore/platform/win/WindowsKeyNames.cpp (rev 0)
+++ trunk/Source/WebCore/platform/win/WindowsKeyNames.cpp 2019-11-26 05:18:54 UTC (rev 252873)
@@ -0,0 +1,534 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Copyright (C) 2019 Sony Interactive Entertainment Inc.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+#include "WindowsKeyNames.h"
+
+namespace WebCore {
+
+enum class WindowsKeyNames::KeyModifier : uint8_t {
+ Shift = 1 << 0,
+ Control = 1 << 1,
+ Alt = 1 << 2,
+ CapsLock = 1 << 3,
+};
+
+static void setModifierState(BYTE* keyboardState, WindowsKeyNames::KeyModifierSet modifiers)
+{
+ // According to MSDN GetKeyState():
+ // 1. If the high-order bit is 1, the key is down; otherwise, it is up.
+ // 2. If the low-order bit is 1, the key is toggled. A key, such as the
+ // CAPS LOCK key, is toggled if it is turned on. The key is off and
+ // untoggled if the low-order bit is 0.
+ // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms646301.aspx
+ if (modifiers.contains(WindowsKeyNames::KeyModifier::Shift))
+ keyboardState[VK_SHIFT] |= 0x80;
+
+ if (modifiers.contains(WindowsKeyNames::KeyModifier::Control))
+ keyboardState[VK_CONTROL] |= 0x80;
+
+ if (modifiers.contains(WindowsKeyNames::KeyModifier::Alt))
+ keyboardState[VK_MENU] |= 0x80;
+
+ if (modifiers.contains(WindowsKeyNames::KeyModifier::CapsLock))
+ keyboardState[VK_CAPITAL] |= 0x01;
+}
+
+static bool hasControlAndAlt(WindowsKeyNames::KeyModifierSet modifiers)
+{
+ return modifiers.containsAll({ WindowsKeyNames::KeyModifier::Control, WindowsKeyNames::KeyModifier::Alt });
+}
+
+// This table must be sorted by 'virtualKey' for binary search.
+constexpr struct NonPrintableKeyEntry {
+ int virtualKey;
+ ASCIILiteral domKey;
+} cNonPrintableKeyMap[] = {
+ { VK_CANCEL, "Cancel"_s },
+ { VK_BACK, "Backspace"_s },
+ { VK_TAB, "Tab"_s },
+ { VK_CLEAR, "Clear"_s },
+ { VK_RETURN, "Enter"_s },
+ { VK_SHIFT, "Shift"_s },
+ { VK_CONTROL, "Control"_s },
+ { VK_MENU, "Alt"_s },
+ { VK_PAUSE, "Pause"_s },
+ { VK_CAPITAL, "CapsLock"_s },
+ // VK_KANA == VK_HANGUL
+ { VK_JUNJA, "JunjaMode"_s },
+ { VK_FINAL, "FINAL_MODE"_s },
+ // VK_HANJA == VK_KANJI
+ { VK_ESCAPE, "Escape"_s },
+ { VK_CONVERT, "Convert"_s },
+ { VK_NONCONVERT, "NonConvert"_s },
+ { VK_ACCEPT, "Accept"_s },
+ { VK_MODECHANGE, "ModeChange"_s },
+ // VK_SPACE
+ { VK_PRIOR, "PageUp"_s },
+ { VK_NEXT, "PageDown"_s },
+ { VK_END, "End"_s },
+ { VK_HOME, "Home"_s },
+ { VK_LEFT, "ArrowLeft"_s },
+ { VK_UP, "ArrowUp"_s },
+ { VK_RIGHT, "ArrowRight"_s },
+ { VK_DOWN, "ArrowDown"_s },
+ { VK_SELECT, "Select"_s },
+ { VK_PRINT, "Print"_s },
+ { VK_EXECUTE, "Execute"_s },
+ { VK_SNAPSHOT, "PrintScreen"_s },
+ { VK_INSERT, "Insert"_s },
+ { VK_DELETE, "Delete"_s },
+ { VK_HELP, "Help"_s },
+ // VK_0..9
+ // VK_A..Z
+ { VK_LWIN, "Meta"_s },
+ // VK_COMMAND == VK_LWIN
+ { VK_RWIN, "Meta"_s },
+ { VK_APPS, "ContextMenu"_s },
+ { VK_SLEEP, "Standby"_s },
+ // VK_NUMPAD0..9
+ // VK_MULTIPLY, VK_ADD, VK_SEPARATOR, VK_SUBTRACT, VK_DECIMAL,
+ // VK_DIVIDE
+ { VK_F1, "F1"_s },
+ { VK_F2, "F2"_s },
+ { VK_F3, "F3"_s },
+ { VK_F4, "F4"_s },
+ { VK_F5, "F5"_s },
+ { VK_F6, "F6"_s },
+ { VK_F7, "F7"_s },
+ { VK_F8, "F8"_s },
+ { VK_F9, "F9"_s },
+ { VK_F10, "F10"_s },
+ { VK_F11, "F11"_s },
+ { VK_F12, "F12"_s },
+ { VK_F13, "F13"_s },
+ { VK_F14, "F14"_s },
+ { VK_F15, "F15"_s },
+ { VK_F16, "F16"_s },
+ { VK_F17, "F17"_s },
+ { VK_F18, "F18"_s },
+ { VK_F19, "F19"_s },
+ { VK_F20, "F20"_s },
+ { VK_F21, "F21"_s },
+ { VK_F22, "F22"_s },
+ { VK_F23, "F23"_s },
+ { VK_F24, "F24"_s },
+ { VK_NUMLOCK, "NumLock"_s },
+ { VK_SCROLL, "ScrollLock"_s },
+ { VK_LSHIFT, "Shift"_s },
+ { VK_RSHIFT, "Shift"_s },
+ { VK_LCONTROL, "Control"_s },
+ { VK_RCONTROL, "Control"_s },
+ { VK_LMENU, "Alt"_s },
+ { VK_RMENU, "Alt"_s },
+ { VK_BROWSER_BACK, "BrowserBack"_s },
+ { VK_BROWSER_FORWARD, "BrowserForward"_s },
+ { VK_BROWSER_REFRESH, "BrowserRefresh"_s },
+ { VK_BROWSER_STOP, "BrowserStop"_s },
+ { VK_BROWSER_SEARCH, "BrowserSearch"_s },
+ { VK_BROWSER_FAVORITES, "BrowserFavorites"_s },
+ { VK_BROWSER_HOME, "BrowserHome"_s },
+ { VK_VOLUME_MUTE, "AudioVolume"_s },
+ { VK_VOLUME_DOWN, "AudioVolumeDown"_s },
+ { VK_VOLUME_UP, "AudioVolumeUp"_s },
+ { VK_MEDIA_NEXT_TRACK, "MediaTrackNext"_s },
+ { VK_MEDIA_PREV_TRACK, "MediaTrackPrevious"_s },
+ { VK_MEDIA_STOP, "MediaStop"_s },
+ { VK_MEDIA_PLAY_PAUSE, "MediaPlayPause"_s },
+ // VK_OEM_1..8, 102, PLUS, COMMA, MINUS, PERIOD
+ { VK_PROCESSKEY, "Process"_s },
+ // VK_PACKET - Used to pass Unicode char, considered as printable key.
+ { VK_ATTN, "Attn"_s },
+ { VK_CRSEL, "CrSel"_s },
+ { VK_EXSEL, "ExSel"_s },
+ { VK_EREOF, "EraseEof"_s },
+ { VK_PLAY, "Play"_s },
+ { VK_ZOOM, "ZoomToggle"_s },
+ { VK_OEM_CLEAR, "Clear"_s },
+};
+
+// Disambiguates the meaning of certain non-printable keys which have different
+// meanings under different languages, but use the same VKEY code.
+static String languageSpecificOemVirtualKeyToDomKey(int virtualKey, HKL layout)
+{
+ WORD language = LOWORD(layout);
+ WORD primaryLanguage = PRIMARYLANGID(language);
+ if (primaryLanguage == LANG_KOREAN) {
+ switch (virtualKey) {
+ case VK_HANGUL:
+ return "HangulMode"_s;
+ case VK_HANJA:
+ return "HanjaMode"_s;
+ default:
+ return String();
+ }
+ } else if (primaryLanguage == LANG_JAPANESE) {
+ switch (virtualKey) {
+ // VK_KANA isn't generated by any modern layouts but is a listed value
+ // that third-party apps might synthesize, so we handle it anyway.
+ case VK_KANA:
+ case VK_ATTN:
+ return "KanaMode"_s;
+ case VK_KANJI:
+ return "KanjiMode"_s;
+ case VK_OEM_ATTN:
+ return "Alphanumeric"_s;
+ case VK_OEM_FINISH:
+ return "Katakana"_s;
+ case VK_OEM_COPY:
+ return "Hiragana"_s;
+ case VK_OEM_BACKTAB:
+ return "Romaji"_s;
+ case VK_OEM_AUTO:
+ return "Hankaku"_s;
+ case VK_OEM_ENLW:
+ return "Zenkaku"_s;
+ default:
+ return String();
+ }
+ }
+ return String();
+}
+
+static String nonPrintableVirtualKeyToDomKey(int virtualKey, HKL layout)
+{
+ // 1. Check if |virtualKey| has a |layout|-specific meaning.
+ const String key = languageSpecificOemVirtualKeyToDomKey(virtualKey, layout);
+ if (!key.isNull())
+ return key;
+
+ // 2. Most |virtualKeys| have the same meaning regardless of |layout|.
+ const NonPrintableKeyEntry* result = std::lower_bound(
+ std::begin(cNonPrintableKeyMap), std::end(cNonPrintableKeyMap), virtualKey,
+ [](const NonPrintableKeyEntry& entry, int needle) {
+ return entry.virtualKey < needle;
+ });
+ if (result != std::end(cNonPrintableKeyMap) && result->virtualKey == virtualKey)
+ return result->domKey;
+
+ return String();
+}
+
+WindowsKeyNames::WindowsKeyNames()
+{
+ updateLayout();
+}
+
+String WindowsKeyNames::domKeyFromLParam(LPARAM lParam)
+{
+ unsigned scanCode = (lParam >> 16) & 0xff;
+ bool extended = lParam & 0x01000000;
+ unsigned virtualKey = MapVirtualKey(scanCode, MAPVK_VSC_TO_VK);
+ KeyModifierSet modifiers;
+ if (GetKeyState(VK_SHIFT) < 0)
+ modifiers.add(KeyModifier::Shift);
+ if (GetKeyState(VK_CONTROL) < 0)
+ modifiers.add(KeyModifier::Control);
+ if (GetKeyState(VK_MENU ) < 0)
+ modifiers.add(KeyModifier::Alt);
+ if (GetKeyState(VK_CAPITAL) & 1)
+ modifiers.add(KeyModifier::CapsLock);
+
+ updateLayout();
+ // Windows expresses right-Alt as VK_MENU with the extended flag set.
+ // This key should generate AltGraph under layouts which use that modifier.
+ if (virtualKey == VK_MENU && extended && m_hasAltGraph)
+ return "AltGraph"_s;
+
+ String key = nonPrintableVirtualKeyToDomKey(virtualKey, m_keyboardLayout);
+ if (!key.isNull())
+ return key;
+
+ const KeyModifierSet modifiersToTry[] = {
+ // Trying to match Firefox's behavior and UIEvents DomKey guidelines.
+ // If the combination doesn't produce a printable character, the key value
+ // should be the key with no modifiers except for Shift and AltGr.
+ // See https://w3c.github.io/uievents/#keys-guidelines
+ modifiers,
+ KeyModifierSet({ KeyModifier::Shift, KeyModifier::CapsLock }) & modifiers,
+ };
+
+ for (auto tryModifiers : modifiersToTry) {
+ const auto& it = m_printableKeyCodeToKey.find(std::make_pair(virtualKey, tryModifiers));
+ if (it != m_printableKeyCodeToKey.end()) {
+ key = it->value;
+ if (!key.isNull())
+ return key;
+ }
+ }
+
+ return "Unidentified"_s;
+}
+
+String WindowsKeyNames::domKeyFromChar(UChar c)
+{
+ switch (c) {
+ case '\x1b':
+ return "Escape"_s;
+ case '\t':
+ return "Tab"_s;
+ case '\r':
+ return "Enter"_s;
+ default:
+ break;
+ }
+ return makeString(c);
+}
+
+// This table must be sorted by 'scanCode' for binary search.
+constexpr struct {
+ unsigned scanCode;
+ ASCIILiteral domCode;
+} cDomCodeMap[] = {
+ { 0x0001, "Escape"_s },
+ { 0x0002, "Digit1"_s },
+ { 0x0003, "Digit2"_s },
+ { 0x0004, "Digit3"_s },
+ { 0x0005, "Digit4"_s },
+ { 0x0006, "Digit5"_s },
+ { 0x0007, "Digit6"_s },
+ { 0x0008, "Digit7"_s },
+ { 0x0009, "Digit8"_s },
+ { 0x000a, "Digit9"_s },
+ { 0x000b, "Digit0"_s },
+ { 0x000c, "Minus"_s },
+ { 0x000d, "Equal"_s },
+ { 0x000e, "Backspace"_s },
+ { 0x000f, "Tab"_s },
+ { 0x0010, "KeyQ"_s },
+ { 0x0011, "KeyW"_s },
+ { 0x0012, "KeyE"_s },
+ { 0x0013, "KeyR"_s },
+ { 0x0014, "KeyT"_s },
+ { 0x0015, "KeyY"_s },
+ { 0x0016, "KeyU"_s },
+ { 0x0017, "KeyI"_s },
+ { 0x0018, "KeyO"_s },
+ { 0x0019, "KeyP"_s },
+ { 0x001a, "BracketLeft"_s },
+ { 0x001b, "BracketRight"_s },
+ { 0x001c, "Enter"_s },
+ { 0x001d, "ControlLeft"_s },
+ { 0x001e, "KeyA"_s },
+ { 0x001f, "KeyS"_s },
+ { 0x0020, "KeyD"_s },
+ { 0x0021, "KeyF"_s },
+ { 0x0022, "KeyG"_s },
+ { 0x0023, "KeyH"_s },
+ { 0x0024, "KeyJ"_s },
+ { 0x0025, "KeyK"_s },
+ { 0x0026, "KeyL"_s },
+ { 0x0027, "Semicolon"_s },
+ { 0x0028, "Quote"_s },
+ { 0x0029, "Backquote"_s },
+ { 0x002a, "ShiftLeft"_s },
+ { 0x002b, "Backslash"_s },
+ { 0x002c, "KeyZ"_s },
+ { 0x002d, "KeyX"_s },
+ { 0x002e, "KeyC"_s },
+ { 0x002f, "KeyV"_s },
+ { 0x0030, "KeyB"_s },
+ { 0x0031, "KeyN"_s },
+ { 0x0032, "KeyM"_s },
+ { 0x0033, "Comma"_s },
+ { 0x0034, "Period"_s },
+ { 0x0035, "Slash"_s },
+ { 0x0036, "ShiftRight"_s },
+ { 0x0037, "NumpadMultiply"_s },
+ { 0x0038, "AltLeft"_s },
+ { 0x0039, "Space"_s },
+ { 0x003a, "CapsLock"_s },
+ { 0x003b, "F1"_s },
+ { 0x003c, "F2"_s },
+ { 0x003d, "F3"_s },
+ { 0x003e, "F4"_s },
+ { 0x003f, "F5"_s },
+ { 0x0040, "F6"_s },
+ { 0x0041, "F7"_s },
+ { 0x0042, "F8"_s },
+ { 0x0043, "F9"_s },
+ { 0x0044, "F10"_s },
+ { 0x0045, "Pause"_s },
+ { 0x0046, "ScrollLock"_s },
+ { 0x0047, "Numpad7"_s },
+ { 0x0048, "Numpad8"_s },
+ { 0x0049, "Numpad9"_s },
+ { 0x004a, "NumpadSubtract"_s },
+ { 0x004b, "Numpad4"_s },
+ { 0x004c, "Numpad5"_s },
+ { 0x004d, "Numpad6"_s },
+ { 0x004e, "NumpadAdd"_s },
+ { 0x004f, "Numpad1"_s },
+ { 0x0050, "Numpad2"_s },
+ { 0x0051, "Numpad3"_s },
+ { 0x0052, "Numpad0"_s },
+ { 0x0053, "NumpadDecimal"_s },
+ { 0x0056, "IntlBackslash"_s },
+ { 0x0057, "F11"_s },
+ { 0x0058, "F12"_s },
+ { 0x0059, "NumpadEqual"_s },
+ { 0x0064, "F13"_s },
+ { 0x0065, "F14"_s },
+ { 0x0066, "F15"_s },
+ { 0x0067, "F16"_s },
+ { 0x0068, "F17"_s },
+ { 0x0069, "F18"_s },
+ { 0x006a, "F19"_s },
+ { 0x006b, "F20"_s },
+ { 0x006c, "F21"_s },
+ { 0x006d, "F22"_s },
+ { 0x006e, "F23"_s },
+ { 0x0070, "KanaMode"_s },
+ { 0x0071, "Lang2"_s },
+ { 0x0072, "Lang1"_s },
+ { 0x0073, "IntlRo"_s },
+ { 0x0076, "F24"_s },
+ { 0x0077, "Lang4"_s },
+ { 0x0078, "Lang3"_s },
+ { 0x0079, "Convert"_s },
+ { 0x007b, "NonConvert"_s },
+ { 0x007d, "IntlYen"_s },
+ { 0x007e, "NumpadComma"_s },
+ { 0x0108, "Undo"_s },
+ { 0x010a, "Paste"_s },
+ { 0x0110, "MediaTrackPrevious"_s },
+ { 0x0117, "Cut"_s },
+ { 0x0118, "Copy"_s },
+ { 0x0119, "MediaTrackNext"_s },
+ { 0x011c, "NumpadEnter"_s },
+ { 0x011d, "ControlRight"_s },
+ { 0x0120, "AudioVolumeMute"_s },
+ { 0x0121, "LaunchApp2"_s },
+ { 0x0122, "MediaPlayPause"_s },
+ { 0x0124, "MediaStop"_s },
+ { 0x012c, "Eject"_s },
+ { 0x012e, "AudioVolumeDown"_s },
+ { 0x0130, "AudioVolumeUp"_s },
+ { 0x0132, "BrowserHome"_s },
+ { 0x0135, "NumpadDivide"_s },
+ { 0x0137, "PrintScreen"_s },
+ { 0x0138, "AltRight"_s },
+ { 0x013b, "Help"_s },
+ { 0x0145, "NumLock"_s },
+ { 0x0147, "Home"_s },
+ { 0x0148, "ArrowUp"_s },
+ { 0x0149, "PageUp"_s },
+ { 0x014b, "ArrowLeft"_s },
+ { 0x014d, "ArrowRight"_s },
+ { 0x014f, "End"_s },
+ { 0x0150, "ArrowDown"_s },
+ { 0x0151, "PageDown"_s },
+ { 0x0152, "Insert"_s },
+ { 0x0153, "Delete"_s },
+ { 0x015b, "MetaLeft"_s },
+ { 0x015c, "MetaRight"_s },
+ { 0x015d, "ContextMenu"_s },
+ { 0x015e, "Power"_s },
+ { 0x015f, "Sleep"_s },
+ { 0x0163, "WakeUp"_s },
+ { 0x0165, "BrowserSearch"_s },
+ { 0x0166, "BrowserFavorites"_s },
+ { 0x0167, "BrowserRefresh"_s },
+ { 0x0168, "BrowserStop"_s },
+ { 0x0169, "BrowserForward"_s },
+ { 0x016a, "BrowserBack"_s },
+ { 0x016b, "LaunchApp1"_s },
+ { 0x016c, "LaunchMail"_s },
+ { 0x016d, "MediaSelect"_s },
+};
+
+String WindowsKeyNames::domCodeFromLParam(LPARAM lParam)
+{
+ unsigned extendedScanCode = (lParam >> 16) & 0x1ff;
+ const auto* result = std::lower_bound(
+ std::begin(cDomCodeMap), std::end(cDomCodeMap), extendedScanCode,
+ [](const auto& entry, int needle) {
+ return entry.scanCode < needle;
+ });
+ if (result != std::end(cDomCodeMap) && result->scanCode == extendedScanCode)
+ return result->domCode;
+
+ return "Unidentified"_s;
+}
+
+void WindowsKeyNames::updateLayout()
+{
+ HKL currentLayout = GetKeyboardLayout(0);
+ if (currentLayout == m_keyboardLayout)
+ return;
+
+ BYTE keyboardStateToRestore[256];
+ if (!GetKeyboardState(keyboardStateToRestore))
+ return;
+
+ m_keyboardLayout = currentLayout;
+ m_printableKeyCodeToKey.clear();
+ m_hasAltGraph = false;
+
+ // Map size for some sample keyboard layouts:
+ // US: 476, French: 602, Persian: 482, Vietnamese: 1436
+ m_printableKeyCodeToKey.reserveInitialCapacity(1500);
+
+ KeyModifierSet allCombination { KeyModifier::Shift, KeyModifier::Control, KeyModifier::Alt, KeyModifier::CapsLock };
+
+ for (int combination = 0; combination <= allCombination.toRaw(); ++combination) {
+ BYTE keyboardState[256] = { };
+
+ // Setting up keyboard state for modifiers.
+ auto modifiers = KeyModifierSet::fromRaw(combination);
+ setModifierState(keyboardState, modifiers);
+
+ for (unsigned virtualKey = 0; virtualKey <= 0xFF; ++virtualKey) {
+ wchar_t translatedChars[5];
+ int rv = ToUnicodeEx(virtualKey, 0, keyboardState, translatedChars,
+ WTF_ARRAY_LENGTH(translatedChars), 0, m_keyboardLayout);
+
+ if (rv == -1) {
+ // Dead key, injecting VK_SPACE to get character representation.
+ BYTE emptyState[256] = { };
+ rv = ToUnicodeEx(VK_SPACE, 0, emptyState, translatedChars,
+ WTF_ARRAY_LENGTH(translatedChars), 0, m_keyboardLayout);
+ // Expecting a dead key character (not followed by a space).
+ if (rv == 1)
+ m_printableKeyCodeToKey.set(std::make_pair(virtualKey, modifiers), "Dead"_s);
+ } else if (rv == 1) {
+ if (translatedChars[0] >= 0x20) {
+ m_printableKeyCodeToKey.set(std::make_pair(virtualKey, modifiers), String(translatedChars, 1));
+
+ // Detect whether the layout makes use of AltGraph.
+ if (hasControlAndAlt(modifiers))
+ m_hasAltGraph = true;
+ }
+ }
+ }
+ }
+ SetKeyboardState(keyboardStateToRestore);
+}
+
+} // namespace WebCore
Added: trunk/Source/WebCore/platform/win/WindowsKeyNames.h (0 => 252873)
--- trunk/Source/WebCore/platform/win/WindowsKeyNames.h (rev 0)
+++ trunk/Source/WebCore/platform/win/WindowsKeyNames.h 2019-11-26 05:18:54 UTC (rev 252873)
@@ -0,0 +1,61 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Copyright (C) 2019 Sony Interactive Entertainment Inc.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#pragma once
+
+#include <windows.h>
+#include <wtf/HashMap.h>
+#include <wtf/OptionSetHash.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class WindowsKeyNames {
+public:
+ WindowsKeyNames();
+
+ String domKeyFromLParam(LPARAM);
+ String domKeyFromChar(UChar);
+ String domCodeFromLParam(LPARAM);
+
+ enum class KeyModifier : uint8_t;
+ using KeyModifierSet = OptionSet<KeyModifier>;
+
+private:
+ void updateLayout();
+
+ HKL m_keyboardLayout = 0;
+ bool m_hasAltGraph = false;
+
+ using VirtualKeyModifierSetPair = std::pair<unsigned, KeyModifierSet>;
+ using VirtualKeyToKeyMap = HashMap<VirtualKeyModifierSetPair, String, DefaultHash<VirtualKeyModifierSetPair>::Hash, PairHashTraits<WTF::UnsignedWithZeroKeyHashTraits<unsigned>, HashTraits<KeyModifierSet>>>;
+ VirtualKeyToKeyMap m_printableKeyCodeToKey;
+};
+
+} // namespace WebCore
Modified: trunk/Source/WebKit/ChangeLog (252872 => 252873)
--- trunk/Source/WebKit/ChangeLog 2019-11-26 02:56:33 UTC (rev 252872)
+++ trunk/Source/WebKit/ChangeLog 2019-11-26 05:18:54 UTC (rev 252873)
@@ -1,3 +1,17 @@
+2019-11-25 Fujii Hironori <[email protected]>
+
+ [Win] Update KeyboardEvent as per the latest specification
+ https://bugs.webkit.org/show_bug.cgi?id=202183
+
+ Reviewed by Ross Kirsling.
+
+ * Shared/WebEvent.h:
+ * Shared/WebKeyboardEvent.cpp:
+ (WebKit::WebKeyboardEvent::WebKeyboardEvent):
+ * Shared/win/WebEventFactory.cpp:
+ (WebKit::windowsKeyNames):
+ (WebKit::WebEventFactory::createWebKeyboardEvent):
+
2019-11-25 ChangSeok Oh <[email protected]>
[GTK] Check EGL image extension by using native gl API in AcceleratedBackingStoreWayland
Modified: trunk/Source/WebKit/Shared/WebEvent.h (252872 => 252873)
--- trunk/Source/WebKit/Shared/WebEvent.h 2019-11-26 02:56:33 UTC (rev 252872)
+++ trunk/Source/WebKit/Shared/WebEvent.h 2019-11-26 05:18:54 UTC (rev 252873)
@@ -263,7 +263,7 @@
#elif USE(LIBWPE)
WebKeyboardEvent(Type, const String& text, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, bool isKeypad, OptionSet<Modifier>, WallTime timestamp);
#else
- WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier>, WallTime timestamp);
+ WebKeyboardEvent(Type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier>, WallTime timestamp);
#endif
const String& text() const { return m_text; }
Modified: trunk/Source/WebKit/Shared/WebKeyboardEvent.cpp (252872 => 252873)
--- trunk/Source/WebKit/Shared/WebKeyboardEvent.cpp 2019-11-26 02:56:33 UTC (rev 252872)
+++ trunk/Source/WebKit/Shared/WebKeyboardEvent.cpp 2019-11-26 05:18:54 UTC (rev 252873)
@@ -132,10 +132,12 @@
#else
-WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String& unmodifiedText, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier> modifiers, WallTime timestamp)
+WebKeyboardEvent::WebKeyboardEvent(Type type, const String& text, const String& unmodifiedText, const String& key, const String& code, const String& keyIdentifier, int windowsVirtualKeyCode, int nativeVirtualKeyCode, int macCharCode, bool isAutoRepeat, bool isKeypad, bool isSystemKey, OptionSet<Modifier> modifiers, WallTime timestamp)
: WebEvent(type, modifiers, timestamp)
, m_text(text)
, m_unmodifiedText(unmodifiedText)
+ , m_key(key)
+ , m_code(code)
, m_keyIdentifier(keyIdentifier)
, m_windowsVirtualKeyCode(windowsVirtualKeyCode)
, m_nativeVirtualKeyCode(nativeVirtualKeyCode)
Modified: trunk/Source/WebKit/Shared/win/WebEventFactory.cpp (252872 => 252873)
--- trunk/Source/WebKit/Shared/win/WebEventFactory.cpp 2019-11-26 02:56:33 UTC (rev 252872)
+++ trunk/Source/WebKit/Shared/win/WebEventFactory.cpp 2019-11-26 05:18:54 UTC (rev 252873)
@@ -31,6 +31,7 @@
#include <WebCore/PlatformKeyboardEvent.h>
#include <WebCore/PlatformWheelEvent.h>
#include <WebCore/Scrollbar.h>
+#include <WebCore/WindowsKeyNames.h>
#include <WebCore/WindowsKeyboardCodes.h>
#include <windowsx.h>
#include <wtf/ASCIICType.h>
@@ -446,11 +447,19 @@
return WebWheelEvent(WebEvent::Wheel, position, globalPosition, FloatSize(deltaX, deltaY), FloatSize(wheelTicksX, wheelTicksY), granularity, modifiers, WallTime::now());
}
+static WindowsKeyNames& windowsKeyNames()
+{
+ static NeverDestroyed<WindowsKeyNames> keyNames;
+ return keyNames;
+}
+
WebKeyboardEvent WebEventFactory::createWebKeyboardEvent(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
WebEvent::Type type = keyboardEventTypeForEvent(message);
String text = textFromEvent(wparam, type);
String unmodifiedText = unmodifiedTextFromEvent(wparam, type);
+ String key = message == WM_CHAR ? windowsKeyNames().domKeyFromChar(wparam) : windowsKeyNames().domKeyFromLParam(lparam);
+ String code = windowsKeyNames().domCodeFromLParam(lparam);
String keyIdentifier = keyIdentifierFromEvent(wparam, type);
int windowsVirtualKeyCode = static_cast<int>(wparam);
int nativeVirtualKeyCode = static_cast<int>(wparam);
@@ -460,7 +469,7 @@
bool isSystemKey = isSystemKeyEvent(message);
auto modifiers = modifiersForCurrentKeyState();
- return WebKeyboardEvent(type, text, unmodifiedText, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, macCharCode, autoRepeat, isKeypad, isSystemKey, modifiers, WallTime::now());
+ return WebKeyboardEvent(type, text, unmodifiedText, key, code, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, macCharCode, autoRepeat, isKeypad, isSystemKey, modifiers, WallTime::now());
}
#if ENABLE(TOUCH_EVENTS)
_______________________________________________ webkit-changes mailing list [email protected] https://lists.webkit.org/mailman/listinfo/webkit-changes
