LibWeb+UI: Detect and handle left vs. right modifier keys

Our handling of left vs. right modifiers keys (shift, ctrl, etc.) was
largely not to spec. This patch adds explicit UIEvents::KeyCode values
for these keys, and updates the UI to match native key events to these
keys (as best as we are able).

(cherry picked from commit 4fcaeabe1a6acd9f4d5fd811a36f2e86748b2a72;
amended to make the rest of the system build and to keep `Mod_AltGr`
around in addition to adding it as a key)

Co-authored-by: Nico Weber <thakis@chromium.org>
This commit is contained in:
Timothy Flynn 2024-10-09 08:56:55 -04:00 committed by Nico Weber
parent 96ba151190
commit 965e1baa8c
19 changed files with 163 additions and 115 deletions

View file

@ -31,10 +31,11 @@
__ENUMERATE_KEY_CODE(PageDown, "PageDown") \
__ENUMERATE_KEY_CODE(LeftShift, "LeftShift") \
__ENUMERATE_KEY_CODE(RightShift, "RightShift") \
__ENUMERATE_KEY_CODE(Control, "Ctrl") \
__ENUMERATE_KEY_CODE(RightControl, "RightCtrl") \
__ENUMERATE_KEY_CODE(Alt, "Alt") \
__ENUMERATE_KEY_CODE(RightAlt, "Alt") \
__ENUMERATE_KEY_CODE(LeftControl, "LeftControl") \
__ENUMERATE_KEY_CODE(RightControl, "RightControl") \
__ENUMERATE_KEY_CODE(LeftAlt, "LeftAlt") \
__ENUMERATE_KEY_CODE(RightAlt, "RightAlt") \
__ENUMERATE_KEY_CODE(AltGr, "AltGr") \
__ENUMERATE_KEY_CODE(CapsLock, "CapsLock") \
__ENUMERATE_KEY_CODE(NumLock, "NumLock") \
__ENUMERATE_KEY_CODE(ScrollLock, "ScrollLock") \
@ -119,7 +120,8 @@
__ENUMERATE_KEY_CODE(Pipe, "|") \
__ENUMERATE_KEY_CODE(Tilde, "~") \
__ENUMERATE_KEY_CODE(Backtick, "`") \
__ENUMERATE_KEY_CODE(Super, "Super") \
__ENUMERATE_KEY_CODE(LeftSuper, "LeftSuper") \
__ENUMERATE_KEY_CODE(RightSuper, "RightSuper") \
__ENUMERATE_KEY_CODE(BrowserSearch, "BrowserSearch") \
__ENUMERATE_KEY_CODE(BrowserFavorites, "BrowserFavorites") \
__ENUMERATE_KEY_CODE(BrowserHome, "BrowserHome") \

View file

@ -20,29 +20,29 @@ namespace Kernel {
// clang-format off
static constexpr KeyCodeEntry unshifted_scan_code_set1_key_map[0x80] = {
{ Key_Invalid, 0xFF }, { Key_Escape, 1 }, { Key_1, 2 }, { Key_2, 3 },
{ Key_3, 4 }, { Key_4, 5 }, { Key_5, 6 }, { Key_6, 7 },
{ Key_7, 8 }, { Key_8, 9 }, { Key_9, 0x0A }, { Key_0, 0x0B },
{ Key_Minus, 0x0C }, { Key_Equal, 0x0D }, { Key_Backspace, 0x0E }, { Key_Tab, 0x0F },
{ Key_Q, 0x10 }, { Key_W, 0x11 }, { Key_E, 0x12 }, { Key_R, 0x13 },
{ Key_T, 0x14 }, { Key_Y, 0x15 }, { Key_U, 0x16 }, { Key_I, 0x17 },
{ Key_O, 0x18 }, { Key_P, 0x19 }, { Key_LeftBracket, 0x1A }, { Key_RightBracket, 0x1B },
{ Key_Return, 0x1C }, { Key_Control, 0x1D }, { Key_A, 0x1E }, { Key_S, 0x1F },
{ Key_D, 0x20 }, { Key_F, 0x21 }, { Key_G, 0x22 }, { Key_H, 0x23 },
{ Key_J, 0x24 }, { Key_K, 0x25 }, { Key_L, 0x26 }, { Key_Semicolon, 0x27 },
{ Key_Apostrophe, 0x28 }, { Key_Backtick, 0x29 }, { Key_LeftShift, 0xFF }, { Key_Backslash, 0x2B },
{ Key_Z, 0x2C }, { Key_X, 0x2D }, { Key_C, 0x2E }, { Key_V, 0x2F },
{ Key_B, 0x30 }, { Key_N, 0x31 }, { Key_M, 0x32 }, { Key_Comma, 0x33 },
{ Key_Period, 0x34 }, { Key_Slash, 0x35 }, { Key_RightShift, 0xFF }, { Key_Asterisk, 0x37 },
{ Key_Alt, 0xFF }, { Key_Space, 0x39 }, { Key_CapsLock, 0xFF }, { Key_F1, 0xFF },
{ Key_F2, 0xFF }, { Key_F3, 0xFF }, { Key_F4, 0xFF }, { Key_F5, 0xFF },
{ Key_F6, 0xFF }, { Key_F7, 0xFF }, { Key_F8, 0xFF }, { Key_F9, 0xFF },
{ Key_F10, 0xFF }, { Key_NumLock, 0x45 }, { Key_ScrollLock, 0xFF }, { Key_Home, 0xFF },
{ Key_Up, 0xFF }, { Key_PageUp, 0xFF }, { Key_Minus, 0x4A }, { Key_Left, 0xFF },
{ Key_Invalid, 0xFF }, { Key_Right, 0xFF }, { Key_Plus, 0x4E }, { Key_End, 0xFF },
{ Key_Down, 0xFF }, { Key_PageDown, 0xFF }, { Key_Insert, 0xFF }, { Key_Delete, 0xFF },
{ Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Backslash, 0x56 }, { Key_F11, 0xFF },
{ Key_F12, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Super, 0xFF },
{ Key_Invalid, 0xFF }, { Key_Escape, 1 }, { Key_1, 2 }, { Key_2, 3 },
{ Key_3, 4 }, { Key_4, 5 }, { Key_5, 6 }, { Key_6, 7 },
{ Key_7, 8 }, { Key_8, 9 }, { Key_9, 0x0A }, { Key_0, 0x0B },
{ Key_Minus, 0x0C }, { Key_Equal, 0x0D }, { Key_Backspace, 0x0E }, { Key_Tab, 0x0F },
{ Key_Q, 0x10 }, { Key_W, 0x11 }, { Key_E, 0x12 }, { Key_R, 0x13 },
{ Key_T, 0x14 }, { Key_Y, 0x15 }, { Key_U, 0x16 }, { Key_I, 0x17 },
{ Key_O, 0x18 }, { Key_P, 0x19 }, { Key_LeftBracket, 0x1A }, { Key_RightBracket, 0x1B },
{ Key_Return, 0x1C }, { Key_LeftControl, 0x1D }, { Key_A, 0x1E }, { Key_S, 0x1F },
{ Key_D, 0x20 }, { Key_F, 0x21 }, { Key_G, 0x22 }, { Key_H, 0x23 },
{ Key_J, 0x24 }, { Key_K, 0x25 }, { Key_L, 0x26 }, { Key_Semicolon, 0x27 },
{ Key_Apostrophe, 0x28 }, { Key_Backtick, 0x29 }, { Key_LeftShift, 0xFF }, { Key_Backslash, 0x2B },
{ Key_Z, 0x2C }, { Key_X, 0x2D }, { Key_C, 0x2E }, { Key_V, 0x2F },
{ Key_B, 0x30 }, { Key_N, 0x31 }, { Key_M, 0x32 }, { Key_Comma, 0x33 },
{ Key_Period, 0x34 }, { Key_Slash, 0x35 }, { Key_RightShift, 0xFF }, { Key_Asterisk, 0x37 },
{ Key_LeftAlt, 0xFF }, { Key_Space, 0x39 }, { Key_CapsLock, 0xFF }, { Key_F1, 0xFF },
{ Key_F2, 0xFF }, { Key_F3, 0xFF }, { Key_F4, 0xFF }, { Key_F5, 0xFF },
{ Key_F6, 0xFF }, { Key_F7, 0xFF }, { Key_F8, 0xFF }, { Key_F9, 0xFF },
{ Key_F10, 0xFF }, { Key_NumLock, 0x45 }, { Key_ScrollLock, 0xFF }, { Key_Home, 0xFF },
{ Key_Up, 0xFF }, { Key_PageUp, 0xFF }, { Key_Minus, 0x4A }, { Key_Left, 0xFF },
{ Key_Invalid, 0xFF }, { Key_Right, 0xFF }, { Key_Plus, 0x4E }, { Key_End, 0xFF },
{ Key_Down, 0xFF }, { Key_PageDown, 0xFF }, { Key_Insert, 0xFF }, { Key_Delete, 0xFF },
{ Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Backslash, 0x56 }, { Key_F11, 0xFF },
{ Key_F12, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_LeftSuper, 0xFF },
{ Key_Invalid, 0xFF }, { Key_Menu, 0xFF },
};
// clang-format on
@ -56,14 +56,14 @@ static constexpr KeyCodeEntry shifted_scan_code_set1_key_map[0x100] = {
{ Key_Q, 0x10 }, { Key_W, 0x11 }, { Key_E, 0x12 }, { Key_R, 0x13 },
{ Key_T, 0x14 }, { Key_Y, 0x15 }, { Key_U, 0x16 }, { Key_I, 0x17 },
{ Key_O, 0x18 }, { Key_P, 0x19 }, { Key_LeftBrace, 0x1A }, { Key_RightBrace, 0x1B },
{ Key_Return, 0x1C }, { Key_Control, 0x1D }, { Key_A, 0x1E }, { Key_S, 0x1F },
{ Key_Return, 0x1C }, { Key_LeftControl, 0x1D }, { Key_A, 0x1E }, { Key_S, 0x1F },
{ Key_D, 0x20 }, { Key_F, 0x21 }, { Key_G, 0x22 }, { Key_H, 0x23 },
{ Key_J, 0x24 }, { Key_K, 0x25 }, { Key_L, 0x26 }, { Key_Colon, 0x27 },
{ Key_DoubleQuote, 0x28 }, { Key_Tilde, 0x29 }, { Key_LeftShift, 0xFF }, { Key_Pipe, 0x2B },
{ Key_Z, 0x2C }, { Key_X, 0x2D }, { Key_C, 0x2E }, { Key_V, 0x2F },
{ Key_B, 0x30 }, { Key_N, 0x31 }, { Key_M, 0x32 }, { Key_LessThan, 0x33 },
{ Key_GreaterThan, 0x34 }, { Key_QuestionMark, 0x35 }, { Key_RightShift, 0xFF }, { Key_Asterisk, 0x37 },
{ Key_Alt, 0xFF }, { Key_Space, 0x39 }, { Key_CapsLock, 0xFF }, { Key_F1, 0xFF },
{ Key_LeftAlt, 0xFF }, { Key_Space, 0x39 }, { Key_CapsLock, 0xFF }, { Key_F1, 0xFF },
{ Key_F2, 0xFF }, { Key_F3, 0xFF }, { Key_F4, 0xFF }, { Key_F5, 0xFF },
{ Key_F6, 0xFF }, { Key_F7, 0xFF }, { Key_F8, 0xFF }, { Key_F9, 0xFF },
{ Key_F10, 0xFF }, { Key_NumLock, 0xFF }, { Key_ScrollLock, 0xFF }, { Key_Home, 0xFF },
@ -71,7 +71,7 @@ static constexpr KeyCodeEntry shifted_scan_code_set1_key_map[0x100] = {
{ Key_Invalid, 0xFF }, { Key_Right, 0xFF }, { Key_Plus, 0x4E }, { Key_End, 0xFF },
{ Key_Down, 0xFF }, { Key_PageDown, 0xFF }, { Key_Insert, 0xFF }, { Key_Delete, 0xFF },
{ Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Pipe, 0x56 }, { Key_F11, 0xFF },
{ Key_F12, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Super, 0xFF },
{ Key_F12, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_LeftSuper, 0xFF },
{ Key_Invalid, 0xFF }, { Key_Menu, 0xFF },
};
// clang-format on
@ -82,8 +82,8 @@ static constexpr KeyCodeEntry unshifted_simple_scan_code_set2_key_map_with_key_n
{ Key_F3, 0x3D }, { Key_F1, 0x3B }, { Key_F2, 0x3C }, { Key_F12, 0xFF },
{ Key_Invalid, 0xFF }, { Key_F10, 0x44 }, { Key_F8, 0x42 }, { Key_F6, 0x40 },
{ Key_F4, 0x3E }, { Key_Tab, 0x0F }, { Key_Backtick, 0x29 }, { Key_Invalid, 0xFF },
{ Key_Invalid, 0xFF }, { Key_Alt, 0x38 }, { Key_LeftShift, 0x2A }, { Key_Invalid, 0xFF },
{ Key_Control, 0x1D }, { Key_Q, 0x10 }, { Key_1, 2 }, { Key_Invalid, 0xFF },
{ Key_Invalid, 0xFF }, { Key_LeftAlt, 0x38 }, { Key_LeftShift, 0x2A }, { Key_Invalid, 0xFF },
{ Key_LeftControl, 0x1D }, { Key_Q, 0x10 }, { Key_1, 2 }, { Key_Invalid, 0xFF },
{ Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Z, 0x2C }, { Key_S, 0x1F },
{ Key_A, 0x1E }, { Key_W, 0x11 }, { Key_2, 3 }, { Key_Invalid, 0xFF },
{ Key_Invalid, 0xFF }, { Key_C, 0x2E }, { Key_X, 0x2D }, { Key_D, 0x20 },
@ -121,8 +121,8 @@ static constexpr KeyCodeEntry unshifted_simple_scan_code_set2_key_map_with_disab
{ Key_F3, 0x3D }, { Key_F1, 0x3B }, { Key_F2, 0x3C }, { Key_F12, 0xFF },
{ Key_Invalid, 0xFF }, { Key_F10, 0x44 }, { Key_F8, 0x42 }, { Key_F6, 0x40 },
{ Key_F4, 0x3E }, { Key_Tab, 0x0F }, { Key_Backtick, 0x29 }, { Key_Invalid, 0xFF },
{ Key_Invalid, 0xFF }, { Key_Alt, 0x38 }, { Key_LeftShift, 0x2A }, { Key_Invalid, 0xFF },
{ Key_Control, 0x1D }, { Key_Q, 0x10 }, { Key_1, 2 }, { Key_Invalid, 0xFF },
{ Key_Invalid, 0xFF }, { Key_LeftAlt, 0x38 }, { Key_LeftShift, 0x2A }, { Key_Invalid, 0xFF },
{ Key_LeftControl, 0x1D }, { Key_Q, 0x10 }, { Key_1, 2 }, { Key_Invalid, 0xFF },
{ Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Z, 0x2C }, { Key_S, 0x1F },
{ Key_A, 0x1E }, { Key_W, 0x11 }, { Key_2, 3 }, { Key_Invalid, 0xFF },
{ Key_Invalid, 0xFF }, { Key_C, 0x2E }, { Key_X, 0x2D }, { Key_D, 0x20 },
@ -160,8 +160,8 @@ static constexpr KeyCodeEntry shifted_simple_scan_code_set2_key_map_with_key_num
{ Key_F3, 0x3D }, { Key_F1, 0x3B }, { Key_F2, 0x3C }, { Key_F12, 0xFF },
{ Key_Invalid, 0xFF }, { Key_F10, 0x44 }, { Key_F8, 0x42 }, { Key_F6, 0x40 },
{ Key_F4, 0x3E }, { Key_Tab, 0x0F }, { Key_Backtick, 0x29 }, { Key_Invalid, 0xFF },
{ Key_Invalid, 0xFF }, { Key_Alt, 0x38 }, { Key_LeftShift, 0x2A }, { Key_Invalid, 0xFF },
{ Key_Control, 0x1D }, { Key_Q, 0x10 }, { Key_Escape, 2 }, { Key_Invalid, 0xFF },
{ Key_Invalid, 0xFF }, { Key_LeftAlt, 0x38 }, { Key_LeftShift, 0x2A }, { Key_Invalid, 0xFF },
{ Key_LeftControl, 0x1D }, { Key_Q, 0x10 }, { Key_Escape, 2 }, { Key_Invalid, 0xFF },
{ Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Z, 0x2C }, { Key_S, 0x1F },
{ Key_A, 0x1E }, { Key_W, 0x11 }, { Key_AtSign, 3 }, { Key_Invalid, 0xFF },
{ Key_Invalid, 0xFF }, { Key_C, 0x2E }, { Key_X, 0x2D }, { Key_D, 0x20 },
@ -199,8 +199,8 @@ static constexpr KeyCodeEntry shifted_simple_scan_code_set2_key_map_with_disable
{ Key_F3, 0x3D }, { Key_F1, 0x3B }, { Key_F2, 0x3C }, { Key_F12, 0xFF },
{ Key_Invalid, 0xFF }, { Key_F10, 0x44 }, { Key_F8, 0x42 }, { Key_F6, 0x40 },
{ Key_F4, 0x3E }, { Key_Tab, 0x0F }, { Key_Backtick, 0x29 }, { Key_Invalid, 0xFF },
{ Key_Invalid, 0xFF }, { Key_Alt, 0x38 }, { Key_LeftShift, 0x2A }, { Key_Invalid, 0xFF },
{ Key_Control, 0x1D }, { Key_Q, 0x10 }, { Key_Escape, 2 }, { Key_Invalid, 0xFF },
{ Key_Invalid, 0xFF }, { Key_LeftAlt, 0x38 }, { Key_LeftShift, 0x2A }, { Key_Invalid, 0xFF },
{ Key_LeftControl, 0x1D }, { Key_Q, 0x10 }, { Key_Escape, 2 }, { Key_Invalid, 0xFF },
{ Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Z, 0x2C }, { Key_S, 0x1F },
{ Key_A, 0x1E }, { Key_W, 0x11 }, { Key_AtSign, 3 }, { Key_Invalid, 0xFF },
{ Key_Invalid, 0xFF }, { Key_C, 0x2E }, { Key_X, 0x2D }, { Key_D, 0x20 },
@ -451,13 +451,13 @@ Optional<RawKeyEvent> PS2KeyboardDevice::generate_raw_key_event_input_from_set2(
case Key_RightAlt:
m_keyboard_device->update_modifier(Mod_AltGr, key_event.is_press());
break;
case Key_Alt:
case Key_LeftAlt:
m_keyboard_device->update_modifier(Mod_Alt, key_event.is_press());
break;
case Key_Control:
case Key_LeftControl:
m_keyboard_device->update_modifier(Mod_Ctrl, key_event.is_press());
break;
case Key_Super:
case Key_LeftSuper:
m_left_super_pressed = key_event.is_press();
m_keyboard_device->update_modifier(Mod_Super, m_left_super_pressed || m_right_super_pressed);
break;

View file

@ -74,7 +74,7 @@ static constexpr auto unshifted_evdev_key_map = to_array<KeyCodeEntry const>({
{ Key_Q, 0x10 }, { Key_W, 0x11 }, { Key_E, 0x12 }, { Key_R, 0x13 },
{ Key_T, 0x14 }, { Key_Y, 0x15 }, { Key_U, 0x16 }, { Key_I, 0x17 },
{ Key_O, 0x18 }, { Key_P, 0x19 }, { Key_LeftBracket, 0x1a }, { Key_RightBracket, 0x1b },
{ Key_Return, 0x1c }, { Key_Control, 0x1d }, { Key_A, 0x1e }, { Key_S, 0x1f },
{ Key_Return, 0x1c }, { Key_LeftControl, 0x1d }, { Key_A, 0x1e }, { Key_S, 0x1f },
// 0x20-0x2f
{ Key_D, 0x20 }, { Key_F, 0x21 }, { Key_G, 0x22 }, { Key_H, 0x23 },
@ -85,7 +85,7 @@ static constexpr auto unshifted_evdev_key_map = to_array<KeyCodeEntry const>({
// 0x30-0x3f
{ Key_B, 0x30 }, { Key_N, 0x31 }, { Key_M, 0x32 }, { Key_Comma, 0x33 },
{ Key_Period, 0x34 }, { Key_Slash, 0x35 }, { Key_RightShift, 0xff }, { Key_Asterisk, 0x37 },
{ Key_Alt, 0xff }, { Key_Space, 0x39 }, { Key_CapsLock, 0xff }, { Key_F1, 0xff },
{ Key_LeftAlt, 0xff }, { Key_Space, 0x39 }, { Key_CapsLock, 0xff }, { Key_F1, 0xff },
{ Key_F2, 0xff }, { Key_F3, 0xff }, { Key_F4, 0xff }, { Key_F5, 0xff },
// 0x40-0x4f
@ -111,7 +111,7 @@ static constexpr auto unshifted_evdev_key_map = to_array<KeyCodeEntry const>({
{ Key_Invalid, 0xff }, { Key_Mute, 0xff }, { Key_VolumeDown, 0xff }, { Key_VolumeUp, 0xff },
{ Key_Power, 0xff }, { Key_Equal, 0xff }, { Key_Invalid, 0xff }, { Key_PauseBreak, 0xff },
{ Key_Invalid, 0xff }, { Key_Invalid, 0xff }, { Key_Invalid, 0xff }, { Key_Invalid, 0xff },
{ Key_Invalid, 0xff }, { Key_Super, 0xff }, { Key_Super, 0xff }, { Key_Menu, 0xff },
{ Key_Invalid, 0xff }, { Key_LeftSuper, 0xff }, { Key_LeftSuper, 0xff }, { Key_Menu, 0xff },
// 0x80-0x8f
{ Key_Stop, 0xff }, { Key_Invalid, 0xff }, { Key_Invalid, 0xff }, { Key_Invalid, 0xff },
@ -133,7 +133,7 @@ static constexpr auto shifted_evdev_key_map = to_array<KeyCodeEntry const>({
{ Key_Q, 0x10 }, { Key_W, 0x11 }, { Key_E, 0x12 }, { Key_R, 0x13 },
{ Key_T, 0x14 }, { Key_Y, 0x15 }, { Key_U, 0x16 }, { Key_I, 0x17 },
{ Key_O, 0x18 }, { Key_P, 0x19 }, { Key_LeftBrace, 0x1a }, { Key_RightBrace, 0x1b },
{ Key_Return, 0x1c }, { Key_Control, 0x1d }, { Key_A, 0x1e }, { Key_S, 0x1f },
{ Key_Return, 0x1c }, { Key_LeftControl, 0x1d }, { Key_A, 0x1e }, { Key_S, 0x1f },
// 0x20-0x2f
{ Key_D, 0x20 }, { Key_F, 0x21 }, { Key_G, 0x22 }, { Key_H, 0x23 },
@ -144,7 +144,7 @@ static constexpr auto shifted_evdev_key_map = to_array<KeyCodeEntry const>({
// 0x30-0x3f
{ Key_B, 0x30 }, { Key_N, 0x31 }, { Key_M, 0x32 }, { Key_LessThan, 0x33 },
{ Key_GreaterThan, 0x34 }, { Key_QuestionMark, 0x35 }, { Key_RightShift, 0xff }, { Key_Asterisk, 0x37 },
{ Key_Alt, 0xff }, { Key_Space, 0x39 }, { Key_CapsLock, 0xff }, { Key_F1, 0xff },
{ Key_LeftAlt, 0xff }, { Key_Space, 0x39 }, { Key_CapsLock, 0xff }, { Key_F1, 0xff },
{ Key_F2, 0xff }, { Key_F3, 0xff }, { Key_F4, 0xff }, { Key_F5, 0xff },
// 0x40-0x4f

View file

@ -226,8 +226,8 @@ static Web::UIEvents::KeyCode ns_key_code_to_key_code(unsigned short key_code, W
case kVK_ANSI_Semicolon: return Web::UIEvents::KeyCode::Key_Semicolon;
case kVK_ANSI_Slash: return Web::UIEvents::KeyCode::Key_Slash;
case kVK_CapsLock: return Web::UIEvents::KeyCode::Key_CapsLock;
case kVK_Command: return Web::UIEvents::KeyCode::Key_Super;
case kVK_Control: return Web::UIEvents::KeyCode::Key_Control;
case kVK_Command: return Web::UIEvents::KeyCode::Key_LeftSuper;
case kVK_Control: return Web::UIEvents::KeyCode::Key_LeftControl;
case kVK_Delete: return Web::UIEvents::KeyCode::Key_Backspace;
case kVK_DownArrow: return Web::UIEvents::KeyCode::Key_Down;
case kVK_End: return Web::UIEvents::KeyCode::Key_End;
@ -247,16 +247,16 @@ static Web::UIEvents::KeyCode ns_key_code_to_key_code(unsigned short key_code, W
case kVK_ForwardDelete: return Web::UIEvents::KeyCode::Key_Delete;
case kVK_Home: return Web::UIEvents::KeyCode::Key_Home;
case kVK_LeftArrow: return Web::UIEvents::KeyCode::Key_Left;
case kVK_Option: return Web::UIEvents::KeyCode::Key_Alt;
case kVK_Option: return Web::UIEvents::KeyCode::Key_LeftAlt;
case kVK_PageDown: return Web::UIEvents::KeyCode::Key_PageDown;
case kVK_PageUp: return Web::UIEvents::KeyCode::Key_PageUp;
case kVK_Return: return Web::UIEvents::KeyCode::Key_Return;
case kVK_RightArrow: return Web::UIEvents::KeyCode::Key_Right;
case kVK_RightCommand: return Web::UIEvents::KeyCode::Key_Super; // FIXME: We do not distinguish left-vs-right.
case kVK_RightControl: return Web::UIEvents::KeyCode::Key_Control; // FIXME: We do not distinguish left-vs-right.
case kVK_RightOption: return Web::UIEvents::KeyCode::Key_Alt; // FIXME: We do not distinguish left-vs-right.
case kVK_RightCommand: return Web::UIEvents::KeyCode::Key_RightSuper;
case kVK_RightControl: return Web::UIEvents::KeyCode::Key_RightControl;
case kVK_RightOption: return Web::UIEvents::KeyCode::Key_RightAlt;
case kVK_RightShift: return Web::UIEvents::KeyCode::Key_RightShift;
case kVK_Shift: return Web::UIEvents::KeyCode::Key_Shift;
case kVK_Shift: return Web::UIEvents::KeyCode::Key_LeftShift;
case kVK_Space: return Web::UIEvents::KeyCode::Key_Space;
case kVK_Tab: return Web::UIEvents::KeyCode::Key_Tab;
case kVK_UpArrow: return Web::UIEvents::KeyCode::Key_Up;

View file

@ -248,8 +248,6 @@ static Web::UIEvents::KeyModifier get_modifiers_from_qt_key_event(QKeyEvent cons
modifiers |= Web::UIEvents::KeyModifier::Mod_Super;
if (event.modifiers().testFlag(Qt::ShiftModifier))
modifiers |= Web::UIEvents::KeyModifier::Mod_Shift;
if (event.modifiers().testFlag(Qt::AltModifier))
modifiers |= Web::UIEvents::KeyModifier::Mod_AltGr;
if (event.modifiers().testFlag(Qt::KeypadModifier))
modifiers |= Web::UIEvents::KeyModifier::Mod_Keypad;
return modifiers;
@ -268,8 +266,12 @@ static Web::UIEvents::KeyCode get_keycode_from_qt_key_event(QKeyEvent const& eve
Web::UIEvents::KeyCode serenity_key;
};
// FIXME: Qt does not differentiate between left-and-right modifier keys. Unfortunately, it seems like we would have
// to inspect event.nativeScanCode() / event.nativeVirtualKey() to do so, which has platform-dependent values.
// For now, we default to left keys.
// https://doc.qt.io/qt-6/qt.html#Key-enum
constexpr Mapping mappings[] = {
static constexpr Mapping mappings[] = {
{ Qt::Key_0, Web::UIEvents::Key_0 },
{ Qt::Key_1, Web::UIEvents::Key_1 },
{ Qt::Key_2, Web::UIEvents::Key_2 },
@ -281,7 +283,7 @@ static Web::UIEvents::KeyCode get_keycode_from_qt_key_event(QKeyEvent const& eve
{ Qt::Key_8, Web::UIEvents::Key_8 },
{ Qt::Key_9, Web::UIEvents::Key_9 },
{ Qt::Key_A, Web::UIEvents::Key_A },
{ Qt::Key_Alt, Web::UIEvents::Key_Alt },
{ Qt::Key_Alt, Web::UIEvents::Key_LeftAlt },
{ Qt::Key_Ampersand, Web::UIEvents::Key_Ampersand },
{ Qt::Key_Apostrophe, Web::UIEvents::Key_Apostrophe },
{ Qt::Key_AsciiCircum, Web::UIEvents::Key_Circumflex },
@ -300,7 +302,7 @@ static Web::UIEvents::KeyCode get_keycode_from_qt_key_event(QKeyEvent const& eve
{ Qt::Key_CapsLock, Web::UIEvents::Key_CapsLock },
{ Qt::Key_Colon, Web::UIEvents::Key_Colon },
{ Qt::Key_Comma, Web::UIEvents::Key_Comma },
{ Qt::Key_Control, Web::UIEvents::Key_Control },
{ Qt::Key_Control, Web::UIEvents::Key_LeftControl },
{ Qt::Key_D, Web::UIEvents::Key_D },
{ Qt::Key_Delete, Web::UIEvents::Key_Delete },
{ Qt::Key_Dollar, Web::UIEvents::Key_Dollar },
@ -338,7 +340,7 @@ static Web::UIEvents::KeyCode get_keycode_from_qt_key_event(QKeyEvent const& eve
{ Qt::Key_Less, Web::UIEvents::Key_LessThan },
{ Qt::Key_M, Web::UIEvents::Key_M },
{ Qt::Key_Menu, Web::UIEvents::Key_Menu },
{ Qt::Key_Meta, Web::UIEvents::Key_Super },
{ Qt::Key_Meta, Web::UIEvents::Key_LeftSuper },
{ Qt::Key_Minus, Web::UIEvents::Key_Minus },
{ Qt::Key_N, Web::UIEvents::Key_N },
{ Qt::Key_NumberSign, Web::UIEvents::Key_Hashtag },
@ -366,8 +368,8 @@ static Web::UIEvents::KeyCode get_keycode_from_qt_key_event(QKeyEvent const& eve
{ Qt::Key_Shift, Web::UIEvents::Key_LeftShift },
{ Qt::Key_Slash, Web::UIEvents::Key_Slash },
{ Qt::Key_Space, Web::UIEvents::Key_Space },
{ Qt::Key_Super_L, Web::UIEvents::Key_Super },
{ Qt::Key_Super_R, Web::UIEvents::Key_Super },
{ Qt::Key_Super_L, Web::UIEvents::Key_LeftSuper },
{ Qt::Key_Super_R, Web::UIEvents::Key_RightSuper },
{ Qt::Key_SysReq, Web::UIEvents::Key_SysRq },
{ Qt::Key_T, Web::UIEvents::Key_T },
{ Qt::Key_Tab, Web::UIEvents::Key_Tab },

View file

@ -0,0 +1,13 @@
key=CapsLock code=CapsLock
key=Escape code=Escape
key=Enter code=Enter
key= code=Space
key=Tab code=Tab
key=Alt code=AltLeft
key=Alt code=AltRight
key=Control code=ControlLeft
key=Control code=ControlRight
key=Shift code=ShiftLeft
key=Shift code=ShiftRight
key=Meta code=MetaLeft
key=Meta code=MetaRight

View file

@ -1 +0,0 @@
Escape

View file

@ -0,0 +1,32 @@
<input id="input" />
<script src="../include.js"></script>
<script>
const FUNCTIONAL_KEYS = [
"CapsLock",
"Escape",
"Return",
"Space",
"Tab",
"LeftAlt",
"RightAlt",
"LeftControl",
"RightControl",
"LeftShift",
"RightShift",
"LeftSuper",
"RightSuper",
];
test(() => {
let input = document.getElementById("input");
input.addEventListener("keydown", e => {
println(`key=${e.key} code=${e.code}`);
e.preventDefault();
});
FUNCTIONAL_KEYS.forEach(key => {
internals.sendKey(input, key);
});
});
</script>

View file

@ -1,17 +0,0 @@
<input id="input" />
<script src="../include.js"></script>
<script>
const SPECIAL_KEYS = ["Escape"];
test(() => {
let input = document.getElementById("input");
input.addEventListener("keydown", e => {
println(`${e.key}`);
});
SPECIAL_KEYS.forEach(key => {
internals.sendKey(input, "Escape");
});
});
</script>

View file

@ -485,7 +485,7 @@ void ImageEditor::keydown_event(GUI::KeyEvent& event)
if (!m_active_tool)
return;
if (!m_active_tool->is_overriding_alt() && event.key() == Key_Alt)
if (!m_active_tool->is_overriding_alt() && event.key() == Key_LeftAlt)
set_override_cursor(Gfx::StandardCursor::Eyedropper);
if (m_active_tool->on_keydown(event))
@ -505,7 +505,7 @@ void ImageEditor::keyup_event(GUI::KeyEvent& event)
if (!m_active_tool)
return;
if (!m_active_tool->is_overriding_alt() && event.key() == Key_Alt)
if (!m_active_tool->is_overriding_alt() && event.key() == Key_LeftAlt)
update_tool_cursor();
m_active_tool->on_keyup(event);

View file

@ -108,7 +108,7 @@ void CloneTool::on_second_paint(Layer const*, GUI::PaintEvent& event)
bool CloneTool::on_keydown(GUI::KeyEvent& event)
{
if (event.key() == KeyCode::Key_Alt && !m_is_selecting_location) {
if (event.key() == KeyCode::Key_LeftAlt && !m_is_selecting_location) {
m_is_selecting_location = true;
m_editor->update_tool_cursor();
return true;
@ -118,7 +118,7 @@ bool CloneTool::on_keydown(GUI::KeyEvent& event)
void CloneTool::on_keyup(GUI::KeyEvent& event)
{
if (m_is_selecting_location && event.key() == KeyCode::Key_Alt) {
if (m_is_selecting_location && event.key() == KeyCode::Key_LeftAlt) {
m_is_selecting_location = false;
m_editor->update_tool_cursor();
return;

View file

@ -140,10 +140,10 @@ void MoveTool::on_mouseup(Layer* layer, MouseEvent& event)
bool MoveTool::on_keydown(GUI::KeyEvent& event)
{
if (event.key() == Key_Shift)
if (event.key() == Key_LeftShift)
m_keep_aspect_ratio = true;
if (event.key() == Key_Alt)
if (event.key() == Key_LeftAlt)
toggle_selection_mode();
if (m_scaling)
@ -182,10 +182,10 @@ bool MoveTool::on_keydown(GUI::KeyEvent& event)
void MoveTool::on_keyup(GUI::KeyEvent& event)
{
if (event.key() == Key_Shift)
if (event.key() == Key_LeftShift)
m_keep_aspect_ratio = false;
if (event.key() == Key_Alt)
if (event.key() == Key_LeftAlt)
toggle_selection_mode();
}

View file

@ -110,7 +110,7 @@ bool RectangleSelectTool::on_keydown(GUI::KeyEvent& key_event)
m_moving_mode = MovingMode::MovingOrigin;
return true;
}
if (key_event.key() == KeyCode::Key_Control) {
if (key_event.key() == KeyCode::Key_LeftControl) {
m_moving_mode = MovingMode::AroundCenter;
return true;
}
@ -130,7 +130,7 @@ void RectangleSelectTool::on_keyup(GUI::KeyEvent& key_event)
{
if (key_event.key() == KeyCode::Key_Space && m_moving_mode == MovingMode::MovingOrigin)
m_moving_mode = MovingMode::None;
else if (key_event.key() == KeyCode::Key_Control && m_moving_mode == MovingMode::AroundCenter)
else if (key_event.key() == KeyCode::Key_LeftControl && m_moving_mode == MovingMode::AroundCenter)
m_moving_mode = MovingMode::None;
}

View file

@ -825,8 +825,8 @@ bool VimEditingEngine::on_key_in_normal_mode(KeyEvent const& event)
// Ignore auxiliary keypress events.
if (event.key() == KeyCode::Key_LeftShift
|| event.key() == KeyCode::Key_RightShift
|| event.key() == KeyCode::Key_Control
|| event.key() == KeyCode::Key_Alt) {
|| event.key() == KeyCode::Key_LeftControl
|| event.key() == KeyCode::Key_LeftAlt) {
return false;
}

View file

@ -248,7 +248,7 @@ void TerminalWidget::keydown_event(GUI::KeyEvent& event)
m_scrollbar->increase_slider_by(m_terminal.rows());
return;
}
if (event.key() == KeyCode::Key_Alt) {
if (event.key() == KeyCode::Key_LeftAlt) {
m_alt_key_held = true;
return;
}
@ -266,14 +266,14 @@ void TerminalWidget::keydown_event(GUI::KeyEvent& event)
m_terminal.handle_key_press(event.key(), event.code_point(), event.modifiers());
if (event.key() != Key_Control && event.key() != Key_Alt && event.key() != Key_LeftShift && event.key() != Key_RightShift && event.key() != Key_Super)
if (event.key() != Key_LeftControl && event.key() != Key_LeftAlt && event.key() != Key_LeftShift && event.key() != Key_RightShift && event.key() != Key_LeftSuper)
scroll_to_bottom();
}
void TerminalWidget::keyup_event(GUI::KeyEvent& event)
{
switch (event.key()) {
case KeyCode::Key_Alt:
case KeyCode::Key_LeftAlt:
m_alt_key_held = false;
return;
default:

View file

@ -1078,7 +1078,7 @@ EventResult EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u
return EventResult::Handled;
case UIEvents::KeyCode::Key_Left:
case UIEvents::KeyCode::Key_Right:
if (modifiers > UIEvents::KeyModifier::Mod_Alt && modifiers != (UIEvents::KeyModifier::Mod_Alt | UIEvents::KeyModifier::Mod_AltGr))
if (modifiers && modifiers != UIEvents::KeyModifier::Mod_Alt)
break;
if (modifiers)
document->page().traverse_the_history_by_delta(key == UIEvents::KeyCode::Key_Left ? -1 : 1);
@ -1087,7 +1087,7 @@ EventResult EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u
return EventResult::Handled;
case UIEvents::KeyCode::Key_PageUp:
case UIEvents::KeyCode::Key_PageDown:
if (modifiers > UIEvents::KeyModifier::Mod_None)
if (modifiers != UIEvents::KeyModifier::Mod_None)
break;
document->window()->scroll_by(0, key == UIEvents::KeyCode::Key_PageUp ? -page_scroll_distance : page_scroll_distance);
return EventResult::Handled;

View file

@ -59,11 +59,14 @@ static unsigned long determine_key_code(KeyCode platform_key, u32 code_point)
return 9;
case KeyCode::Key_Return:
return 13;
case KeyCode::Key_Shift:
case KeyCode::Key_LeftShift:
case KeyCode::Key_RightShift:
return 16;
case KeyCode::Key_Control:
case KeyCode::Key_LeftControl:
case KeyCode::Key_RightControl:
return 17;
case KeyCode::Key_Alt:
case KeyCode::Key_LeftAlt:
case KeyCode::Key_RightAlt:
return 18;
case KeyCode::Key_CapsLock:
return 20;
@ -143,15 +146,20 @@ static ErrorOr<Optional<String>> get_event_named_key(KeyCode platform_key)
return "Unidentified"_string;
// 3.2. Modifier Keys, https://www.w3.org/TR/uievents-key/#keys-modifier
case KeyCode::Key_Alt:
return "AltLeft"_string;
case KeyCode::Key_LeftAlt:
case KeyCode::Key_RightAlt:
return "AltRight"_string;
return "Alt"_string;
case KeyCode::Key_AltGr:
return "AltGraph"_string;
case KeyCode::Key_CapsLock:
return "CapsLock"_string;
case KeyCode::Key_Control:
case KeyCode::Key_LeftControl:
case KeyCode::Key_RightControl:
return "Control"_string;
case KeyCode::Key_Super:
// FIXME: Fn
// FIXME: FnLock
case KeyCode::Key_LeftSuper:
case KeyCode::Key_RightSuper:
return "Meta"_string;
case KeyCode::Key_NumLock:
return "NumLock"_string;
@ -454,24 +462,28 @@ static ErrorOr<String> get_event_code(KeyCode platform_key, unsigned modifiers)
return "Slash"_string;
// 3.1.2. Functional Keys, https://www.w3.org/TR/uievents-code/#key-alphanumeric-functional
case KeyCode::Key_Alt:
case KeyCode::Key_LeftAlt:
return "AltLeft"_string;
case KeyCode::Key_RightAlt:
return "AltRight"_string;
case KeyCode::Key_AltGr:
return "AltGraph"_string;
case KeyCode::Key_Backspace:
return "Backspace"_string;
case KeyCode::Key_CapsLock:
return "CapsLock"_string;
case KeyCode::Key_Menu:
return "ContextMenu"_string;
case KeyCode::Key_Control:
case KeyCode::Key_LeftControl:
return "ControlLeft"_string;
case KeyCode::Key_RightControl:
return "ControlRight"_string;
case KeyCode::Key_Return:
return "Enter"_string;
case KeyCode::Key_Super:
return "Meta"_string; // FIXME: Detect left vs. right key.
case KeyCode::Key_LeftSuper:
return "MetaLeft"_string;
case KeyCode::Key_RightSuper:
return "MetaRight"_string;
case KeyCode::Key_LeftShift:
return "ShiftLeft"_string;
case KeyCode::Key_RightShift:
@ -611,11 +623,16 @@ static DOMKeyLocation get_event_location(KeyCode platform_key, unsigned modifier
if ((modifiers & Mod_Keypad) != 0)
return DOMKeyLocation::Numpad;
// FIXME: Detect left vs. right for Control and Alt keys.
switch (platform_key) {
case KeyCode::Key_LeftAlt:
case KeyCode::Key_LeftControl:
case KeyCode::Key_LeftShift:
case KeyCode::Key_LeftSuper:
return DOMKeyLocation::Left;
case KeyCode::Key_RightAlt:
case KeyCode::Key_RightControl:
case KeyCode::Key_RightShift:
case KeyCode::Key_RightSuper:
return DOMKeyLocation::Right;
default:
break;

View file

@ -1690,11 +1690,11 @@ void WindowManager::process_key_event(KeyEvent& event)
return;
}
if (event.type() == Event::KeyDown && event.key() == Key_Super) {
if (event.type() == Event::KeyDown && event.key() == Key_LeftSuper) {
m_previous_event_was_super_keydown = true;
} else if (m_previous_event_was_super_keydown) {
m_previous_event_was_super_keydown = false;
if (!m_dnd_client && !automatic_cursor_tracking_window() && event.type() == Event::KeyUp && event.key() == Key_Super) {
if (!m_dnd_client && !automatic_cursor_tracking_window() && event.type() == Event::KeyUp && event.key() == Key_LeftSuper) {
tell_wms_super_key_pressed();
return;
}
@ -1716,7 +1716,7 @@ void WindowManager::process_key_event(KeyEvent& event)
}
}
if (MenuManager::the().current_menu() && event.key() != Key_Super) {
if (MenuManager::the().current_menu() && event.key() != Key_LeftSuper) {
MenuManager::the().dispatch_event(event);
return;
}
@ -1733,7 +1733,7 @@ void WindowManager::process_key_event(KeyEvent& event)
return;
}
if (event.type() == Event::KeyDown && (event.modifiers() == (Mod_Alt | Mod_Shift) && (event.key() == Key_Shift || event.key() == Key_Alt))) {
if (event.type() == Event::KeyDown && (event.modifiers() == (Mod_Alt | Mod_Shift) && (event.key() == Key_LeftShift || event.key() == Key_LeftAlt))) {
m_keymap_switcher->next_keymap();
return;
}

View file

@ -88,7 +88,7 @@ void WindowSwitcher::event(Core::Event& event)
void WindowSwitcher::on_key_event(KeyEvent const& event)
{
if (event.type() == Event::KeyUp) {
if (event.key() == (m_mode == Mode::ShowAllWindows ? Key_Super : Key_Alt)) {
if (event.key() == (m_mode == Mode::ShowAllWindows ? Key_LeftSuper : Key_LeftAlt)) {
if (auto* window = selected_window()) {
WindowManager::the().move_to_front_and_make_active(*window);
}