Use scancodes instead of keycodes for hotkeys.

This allows hotkeys to work on non-English keyboard layouts.
Prevents Ctrl+I from being treated as Tab.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/1811
Fixes https://gitlab.com/kicad/code/kicad/-/issues/9519
Fixes https://gitlab.com/kicad/code/kicad/-/issues/12992
Fixes https://gitlab.com/kicad/code/kicad/-/issues/16303
This commit is contained in:
Alex Shvartzkop 2024-04-07 19:41:01 +03:00
parent 7b935f7673
commit 002503d9bd
10 changed files with 1476 additions and 94 deletions

View File

@ -661,6 +661,7 @@ target_link_libraries( common
dxflib_qcad
tinyspline_lib
scripting
gecko-keys
nlohmann_json
pybind11::embed
compoundfilereader

View File

@ -31,6 +31,7 @@
#include <eda_draw_frame.h>
#include <wildcards_and_files_ext.h>
#include <paths.h>
#include <gecko_keys.h>
#include <tool/tool_manager.h>
#include "dialogs/dialog_hotkey_list.h"
@ -93,6 +94,7 @@ static struct hotkey_name_descr hotkeyNameList[] =
{ wxT( "Tab" ), WXK_TAB },
{ wxT( "Back" ), WXK_BACK },
{ wxT( "Ins" ), WXK_INSERT },
{ wxT( "Pause" ), WXK_PAUSE },
{ wxT( "Home" ), WXK_HOME },
{ wxT( "End" ), WXK_END },

View File

@ -35,6 +35,7 @@
#include <view/wx_view_controls.h>
#include <eda_draw_frame.h>
#include <core/kicad_algo.h>
#include <gecko_keys.h>
#include <optional>
#include <wx/log.h>
#include <wx/stc/stc.h>
@ -340,7 +341,7 @@ std::optional<TOOL_EVENT> TOOL_DISPATCHER::GetToolEvent( wxKeyEvent* aKeyEvent,
{
std::optional<TOOL_EVENT> evt;
int key = aKeyEvent->GetKeyCode();
int unicode_key = aKeyEvent->GetUnicodeKey();
// int unicode_key = aKeyEvent->GetUnicodeKey();
// This wxEVT_CHAR_HOOK event can be ignored: not useful in Kicad
if( isKeyModifierOnly( key ) )
@ -355,57 +356,59 @@ std::optional<TOOL_EVENT> TOOL_DISPATCHER::GetToolEvent( wxKeyEvent* aKeyEvent,
// and do nothing.
*keyIsSpecial = isKeySpecialCode( key );
key = GeckoKeys::WXKFromKeyEvent( aKeyEvent->GetRawKeyCode(), aKeyEvent->GetRawKeyFlags() );
if( aKeyEvent->GetEventType() == wxEVT_CHAR_HOOK )
key = translateSpecialCode( key );
int mods = decodeModifiers( aKeyEvent );
if( mods & MD_CTRL )
{
// wxWidgets maps key codes related to Ctrl+letter handled by CHAR_EVT
// (http://docs.wxwidgets.org/trunk/classwx_key_event.html):
// char events for ASCII letters in this case carry codes corresponding to the ASCII
// value of Ctrl-Latter, i.e. 1 for Ctrl-A, 2 for Ctrl-B and so on until 26 for Ctrl-Z.
// They are remapped here to be more easy to handle in code
// Note also on OSX wxWidgets has a different behavior and the mapping is made
// only for ctrl+'A' to ctlr+'Z' (unicode code return 'A' to 'Z').
// Others OS return WXK_CONTROL_A to WXK_CONTROL_Z, and Ctrl+'M' returns the same code as
// the return key, so the remapping does not use the unicode key value.
#ifdef __APPLE__
if( unicode_key >= 'A' && unicode_key <= 'Z' && key >= WXK_CONTROL_A && key <= WXK_CONTROL_Z )
#else
ignore_unused( unicode_key );
// if( mods & MD_CTRL )
// {
// // wxWidgets maps key codes related to Ctrl+letter handled by CHAR_EVT
// // (http://docs.wxwidgets.org/trunk/classwx_key_event.html):
// // char events for ASCII letters in this case carry codes corresponding to the ASCII
// // value of Ctrl-Latter, i.e. 1 for Ctrl-A, 2 for Ctrl-B and so on until 26 for Ctrl-Z.
// // They are remapped here to be more easy to handle in code
// // Note also on OSX wxWidgets has a different behavior and the mapping is made
// // only for ctrl+'A' to ctlr+'Z' (unicode code return 'A' to 'Z').
// // Others OS return WXK_CONTROL_A to WXK_CONTROL_Z, and Ctrl+'M' returns the same code as
// // the return key, so the remapping does not use the unicode key value.
// #ifdef __APPLE__
// if( unicode_key >= 'A' && unicode_key <= 'Z' && key >= WXK_CONTROL_A && key <= WXK_CONTROL_Z )
// #else
// ignore_unused( unicode_key );
if( key >= WXK_CONTROL_A && key <= WXK_CONTROL_Z )
#endif
key += 'A' - 1;
}
// if( key >= WXK_CONTROL_A && key <= WXK_CONTROL_Z )
// #endif
// key += 'A' - 1;
// }
#ifdef __APPLE__
if( mods & MD_ALT )
{
// OSX maps a bunch of commonly used extended-ASCII characters onto the keyboard
// using the ALT key. Since we use ALT for some of our hotkeys, we need to map back
// to the underlying keys. The kVK_ANSI_* values come from Apple and are said to be
// hardware independent.
switch( aKeyEvent->GetRawKeyCode() )
{
case /* kVK_ANSI_1 */ 0x12: key = '1'; break;
case /* kVK_ANSI_2 */ 0x13: key = '2'; break;
case /* kVK_ANSI_3 */ 0x14: key = '3'; break;
case /* kVK_ANSI_4 */ 0x15: key = '4'; break;
case /* kVK_ANSI_6 */ 0x16: key = '6'; break;
case /* kVK_ANSI_5 */ 0x17: key = '5'; break;
case /* kVK_ANSI_Equal */ 0x18: key = '='; break;
case /* kVK_ANSI_9 */ 0x19: key = '9'; break;
case /* kVK_ANSI_7 */ 0x1A: key = '7'; break;
case /* kVK_ANSI_Minus */ 0x1B: key = '-'; break;
case /* kVK_ANSI_8 */ 0x1C: key = '8'; break;
case /* kVK_ANSI_0 */ 0x1D: key = '0'; break;
default: ;
}
}
#endif
// #ifdef __APPLE__
// if( mods & MD_ALT )
// {
// // OSX maps a bunch of commonly used extended-ASCII characters onto the keyboard
// // using the ALT key. Since we use ALT for some of our hotkeys, we need to map back
// // to the underlying keys. The kVK_ANSI_* values come from Apple and are said to be
// // hardware independent.
// switch( aKeyEvent->GetRawKeyCode() )
// {
// case /* kVK_ANSI_1 */ 0x12: key = '1'; break;
// case /* kVK_ANSI_2 */ 0x13: key = '2'; break;
// case /* kVK_ANSI_3 */ 0x14: key = '3'; break;
// case /* kVK_ANSI_4 */ 0x15: key = '4'; break;
// case /* kVK_ANSI_6 */ 0x16: key = '6'; break;
// case /* kVK_ANSI_5 */ 0x17: key = '5'; break;
// case /* kVK_ANSI_Equal */ 0x18: key = '='; break;
// case /* kVK_ANSI_9 */ 0x19: key = '9'; break;
// case /* kVK_ANSI_7 */ 0x1A: key = '7'; break;
// case /* kVK_ANSI_Minus */ 0x1B: key = '-'; break;
// case /* kVK_ANSI_8 */ 0x1C: key = '8'; break;
// case /* kVK_ANSI_0 */ 0x1D: key = '0'; break;
// default: ;
// }
// }
// #endif
if( key == WXK_ESCAPE ) // ESC is the special key for canceling tools
evt = TOOL_EVENT( TC_COMMAND, TA_CANCEL_TOOL, WXK_ESCAPE );

View File

@ -28,6 +28,7 @@
#include <widgets/widget_hotkey_list.h>
#include <tool/tool_event.h>
#include <dialog_shim.h>
#include <gecko_keys.h>
#include <wx/button.h>
#include <wx/log.h>
@ -120,10 +121,10 @@ public:
wxStaticText* key_label_0 = new wxStaticText( panelDisplayCurrent, wxID_ANY, _( "Current key:" ) );
fgsizer->Add( key_label_0, 0, wxALL | wxALIGN_CENTRE_VERTICAL, 5 );
wxStaticText* key_label_1 = new wxStaticText( panelDisplayCurrent, wxID_ANY, wxEmptyString );
key_label_1->SetFont( key_label_1->GetFont().Bold() );
key_label_1->SetLabel( aCurrentKey );
fgsizer->Add( key_label_1, 0, wxALL | wxALIGN_CENTRE_VERTICAL, 5 );
m_key_label_1 = new wxStaticText( panelDisplayCurrent, wxID_ANY, wxEmptyString );
m_key_label_1->SetFont( m_key_label_1->GetFont().Bold() );
m_key_label_1->SetLabel( aCurrentKey );
fgsizer->Add( m_key_label_1, 0, wxALL | wxALIGN_CENTRE_VERTICAL, 5 );
fgsizer->AddStretchSpacer();
@ -139,7 +140,6 @@ public:
// Binding both EVT_CHAR and EVT_CHAR_HOOK ensures that all key events, including
// specials like Tab and Return, are received, particularly on MSW.
panelDisplayCurrent->Bind( wxEVT_CHAR, &HK_PROMPT_DIALOG::OnChar, this );
panelDisplayCurrent->Bind( wxEVT_CHAR_HOOK, &HK_PROMPT_DIALOG::OnCharHook, this );
panelDisplayCurrent->Bind( wxEVT_KEY_UP, &HK_PROMPT_DIALOG::OnKeyUp, this );
@ -189,7 +189,7 @@ protected:
WXK_RAW_CONTROL
};
int key = aEvent.GetKeyCode();
int key = GeckoKeys::WXKFromKeyEvent( aEvent.GetRawKeyCode(), aEvent.GetRawKeyFlags() );
for( wxKeyCode skipped_key : skipped_keys )
{
@ -197,28 +197,12 @@ protected:
return;
}
if( key <= 255 && isprint( key ) && !isspace( key ) )
{
// Let EVT_CHAR handle this one
aEvent.DoAllowNextEvent();
long keycode = WIDGET_HOTKEY_LIST::MapKeypressToKeycode( aEvent );
#ifdef __WXMSW__
// On Windows, looks like a OnChar event is not generated when
// using the Alt key modifier. So ensure m_event is up to date
// to handle the right key code when releasing the key and therefore
// closing the dialog
m_event = aEvent;
#endif
aEvent.Skip();
}
else
{
OnChar( aEvent );
}
}
if( keycode == WXK_NONE )
return;
void OnChar( wxKeyEvent& aEvent )
{
m_key_label_1->SetLabel( KeyNameFromKeyCode( keycode ) );
m_event = aEvent;
}
@ -239,8 +223,9 @@ protected:
}
private:
bool m_resetkey = false;
wxKeyEvent m_event;
wxStaticText* m_key_label_1 = nullptr;
bool m_resetkey = false;
wxKeyEvent m_event;
};
@ -669,40 +654,44 @@ bool WIDGET_HOTKEY_LIST::TransferDataFromControl()
long WIDGET_HOTKEY_LIST::MapKeypressToKeycode( const wxKeyEvent& aEvent )
{
long key = aEvent.GetKeyCode();
bool is_tab = aEvent.IsKeyInCategory( WXK_CATEGORY_TAB );
long code = GeckoKeys::WXKFromKeyEvent( aEvent.GetRawKeyCode(), aEvent.GetRawKeyFlags() );
if( key == WXK_ESCAPE )
// bool is_tab = aEvent.IsKeyInCategory( WXK_CATEGORY_TAB );
if( code == WXK_ESCAPE )
{
return 0;
}
else
{
if( key >= 'a' && key <= 'z' ) // convert to uppercase
key = key + ('A' - 'a');
// if( code >= 'a' && code <= 'z' ) // convert to uppercase
// code = code + ('A' - 'a');
// Remap Ctrl A (=1+GR_KB_CTRL) to Ctrl Z(=26+GR_KB_CTRL)
// to GR_KB_CTRL+'A' .. GR_KB_CTRL+'Z'
if( !is_tab && aEvent.ControlDown() && key >= WXK_CONTROL_A && key <= WXK_CONTROL_Z )
key += 'A' - 1;
// // Remap Ctrl A (=1+GR_KB_CTRL) to Ctrl Z(=26+GR_KB_CTRL)
// // to GR_KB_CTRL+'A' .. GR_KB_CTRL+'Z'
// if( !is_tab && aEvent.ControlDown() && key >= WXK_CONTROL_A && key <= WXK_CONTROL_Z )
// key += 'A' - 1;
/* Disallow shift for keys that have two keycodes on them (e.g. number and
* punctuation keys) leaving only the "letter keys" of A-Z, tab and space
* Then, you can have, e.g. Ctrl-5 and Ctrl-% (GB layout)
* and Ctrl-( and Ctrl-5 (FR layout).
* Otherwise, you'd have to have to say Ctrl-Shift-5 on a FR layout
*/
bool keyIsLetter = key >= 'A' && key <= 'Z';
// /* Disallow shift for keys that have two keycodes on them (e.g. number and
// * punctuation keys) leaving only the "letter keys" of A-Z, tab and space
// * Then, you can have, e.g. Ctrl-5 and Ctrl-% (GB layout)
// * and Ctrl-( and Ctrl-5 (FR layout).
// * Otherwise, you'd have to have to say Ctrl-Shift-5 on a FR layout
// */
// bool keyIsLetter = key >= 'A' && key <= 'Z';
if( aEvent.ShiftDown() && ( keyIsLetter || key > 256 || key == 9 || key == 32 ) )
key |= MD_SHIFT;
// if( aEvent.ShiftDown() && ( keyIsLetter || key > 256 || key == 9 || key == 32 ) )
// key |= MD_SHIFT;
if( aEvent.ShiftDown() )
code |= MD_SHIFT;
if( aEvent.ControlDown() )
key |= MD_CTRL;
code |= MD_CTRL;
if( aEvent.AltDown() )
key |= MD_ALT;
code |= MD_ALT;
return key;
return code;
}
}

View File

@ -42,6 +42,7 @@ add_subdirectory( dxflib_qcad )
add_subdirectory( expected )
set( FMT_INSTALL OFF )
add_subdirectory( fmt )
add_subdirectory( gecko-keys )
add_subdirectory( gzip-hpp )
add_subdirectory( lemon )
add_subdirectory( libcontext )

8
thirdparty/gecko-keys/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,8 @@
add_library( gecko-keys OBJECT
gecko_keys.cpp
)
target_include_directories( gecko-keys
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,235 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* This header file defines all DOM code name which are used for DOM
* KeyboardEvent.code.
* You must define NS_DEFINE_PHYSICAL_KEY_CODE_NAME macro before including this.
*
* It must have two arguments, (aCPPName, aDOMCodeName)
* aCPPName is usable name for a part of C++ constants.
* aDOMCodeName is the actual value.
*/
#define NS_DEFINE_PHYSICAL_KEY_CODE_NAME_INTERNAL(aCPPName, aDOMCodeName) \
NS_DEFINE_PHYSICAL_KEY_CODE_NAME(aCPPName, aDOMCodeName)
#define DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(aName) \
NS_DEFINE_PHYSICAL_KEY_CODE_NAME_INTERNAL(aName, #aName)
// Unknown key
NS_DEFINE_PHYSICAL_KEY_CODE_NAME_INTERNAL(UNKNOWN, "")
// Writing system keys
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Backquote)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Backslash)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Backspace)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(BracketLeft)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(BracketRight)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Comma)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Digit0)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Digit1)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Digit2)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Digit3)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Digit4)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Digit5)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Digit6)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Digit7)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Digit8)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Digit9)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Equal)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(IntlBackslash)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(IntlHash)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(IntlRo)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(IntlYen)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyA)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyB)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyC)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyD)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyE)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyF)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyG)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyH)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyI)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyJ)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyK)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyL)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyM)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyN)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyO)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyP)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyQ)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyR)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyS)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyT)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyU)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyV)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyW)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyX)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyY)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KeyZ)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Minus)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Period)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Quote)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Semicolon)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Slash)
// Functional keys
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(AltLeft)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(AltRight)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(CapsLock)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(ContextMenu)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(ControlLeft)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(ControlRight)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Enter)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(MetaLeft)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(MetaRight)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(ShiftLeft)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(ShiftRight)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Space)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Tab)
// IME keys
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Convert)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(KanaMode)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Lang1)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Lang2)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Lang3)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Lang4)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Lang5)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(NonConvert)
// Control pad section
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Delete)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(End)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Help)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Home)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Insert)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(PageDown)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(PageUp)
// Arrow pad section
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(ArrowDown)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(ArrowLeft)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(ArrowRight)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(ArrowUp)
// Numpad section
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(NumLock)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Numpad0)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Numpad1)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Numpad2)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Numpad3)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Numpad4)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Numpad5)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Numpad6)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Numpad7)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Numpad8)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Numpad9)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(NumpadAdd)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(NumpadBackspace)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(NumpadClear)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(NumpadClearEntry)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(NumpadComma)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(NumpadDecimal)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(NumpadDivide)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(NumpadEnter)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(NumpadEqual)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(NumpadMemoryAdd)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(NumpadMemoryClear)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(NumpadMemoryRecall)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(NumpadMemoryStore)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(NumpadMemorySubtract)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(NumpadMultiply)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(NumpadParenLeft)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(NumpadParenRight)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(NumpadSubtract)
// Function section
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Escape)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F1)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F2)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F3)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F4)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F5)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F6)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F7)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F8)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F9)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F10)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F11)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F12)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F13)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F14)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F15)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F16)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F17)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F18)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F19)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F20)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F21)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F22)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F23)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(F24)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Fn)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(FnLock)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(PrintScreen)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(ScrollLock)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Pause)
// Media keys
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(BrowserBack)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(BrowserFavorites)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(BrowserForward)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(BrowserHome)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(BrowserRefresh)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(BrowserSearch)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(BrowserStop)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Eject)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(LaunchApp1)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(LaunchApp2)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(LaunchMail)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(MediaPlayPause)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(MediaSelect)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(MediaStop)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(MediaTrackNext)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(MediaTrackPrevious)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Power)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Sleep)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(VolumeDown)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(VolumeMute)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(VolumeUp)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(WakeUp)
// Legacy Keys and Non-Standard Keys
// Legacy modifier keys
// DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Hyper)
// DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Super)
// DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Turbo)
// Legacy process control keys
// DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Abort)
// DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Resume)
// DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Suspend)
// Legacy editing keys
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Again)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Copy)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Cut)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Find)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Open)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Paste)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Props)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Select)
DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Undo)
// International keyboards
// DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Hiragana)
// DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME(Katakana)
#undef DEFINE_PHYSICAL_KEY_CODE_NAME_WITH_SAME_NAME
#undef NS_DEFINE_PHYSICAL_KEY_CODE_NAME_INTERNAL

103
thirdparty/gecko-keys/gecko_keys.cpp vendored Normal file
View File

@ -0,0 +1,103 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <gecko_keys.h>
#include <wx/defs.h>
namespace GeckoKeys
{
unsigned int ScanCodeFromKeyEvent( uint32_t aRawKeyCode, uint32_t aRawKeyFlags )
{
#if defined( _WIN32 )
uint16_t scanCode = ( aRawKeyFlags >> 16 ) & 0xFF;
if( ( aRawKeyFlags & 0x1000000 ) != 0 ) // Extended
{
return ( 0xE000 | scanCode );
}
return scanCode;
#elif defined( __APPLE__ )
return aRawKeyCode;
#else
return aRawKeyFlags;
#endif
}
CodeNameIndex CodeNameIndexFromScanCode( unsigned int aScanCode )
{
// clang-format off
switch (aScanCode) {
#define NS_NATIVE_KEY_TO_DOM_CODE_NAME_INDEX(aNativeKey, aCodeNameIndex) \
case aNativeKey: \
return aCodeNameIndex;
#include "NativeKeyToDOMCodeName.h"
#undef NS_NATIVE_KEY_TO_DOM_CODE_NAME_INDEX
default:
break;
}
// clang-format on
return CODE_NAME_INDEX_UNKNOWN;
}
int WXKFromCodeNameIndex( CodeNameIndex aCodeNameIndex )
{
// clang-format off
switch (aCodeNameIndex) {
#define NS_WX_KEY_TO_DOM_CODE_NAME_INDEX(aWXKey, aCPPCodeName) \
case aCPPCodeName: \
return aWXKey;
#include "NativeKeyToDOMCodeName.h"
#undef NS_WX_KEY_TO_DOM_CODE_NAME_INDEX
default:
break;
}
// clang-format on
return WXK_NONE;
}
CodeNameIndex CodeNameIndexFromWXK( int aWXKey )
{
// clang-format off
switch (aWXKey) {
#define NS_WX_KEY_TO_DOM_CODE_NAME_INDEX(aWXKey, aCPPCodeName) \
case aWXKey: \
return aCPPCodeName;
#include "NativeKeyToDOMCodeName.h"
#undef NS_WX_KEY_TO_DOM_CODE_NAME_INDEX
default:
break;
}
// clang-format on
return CODE_NAME_INDEX_UNKNOWN;
}
int WXKFromKeyEvent( uint32_t aRawKeyCode, uint32_t aRawKeyFlags )
{
return WXKFromCodeNameIndex(
CodeNameIndexFromScanCode( ScanCodeFromKeyEvent( aRawKeyCode, aRawKeyFlags ) ) );
}
}

37
thirdparty/gecko-keys/gecko_keys.h vendored Normal file
View File

@ -0,0 +1,37 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef _GECKO_KEYS_H_
#define _GECKO_KEYS_H_
#include <stdint.h>
#include <string>
namespace GeckoKeys
{
#define NS_DEFINE_PHYSICAL_KEY_CODE_NAME( aCPPName, aDOMCodeName ) CODE_NAME_INDEX_##aCPPName,
typedef uint8_t CodeNameIndexType;
enum CodeNameIndex : CodeNameIndexType
{
#include "PhysicalKeyCodeNameList.h"
// If a DOM keyboard event is synthesized by script, this is used. Then,
// specified code name should be stored and use it as .code value.
CODE_NAME_INDEX_USE_STRING
};
#undef NS_DEFINE_PHYSICAL_KEY_CODE_NAME
unsigned int ScanCodeFromKeyEvent( uint32_t aRawKeyCode, uint32_t aRawKeyFlags );
CodeNameIndex CodeNameIndexFromScanCode( unsigned int aScanCode );
int WXKFromCodeNameIndex( CodeNameIndex aCodeNameIndex );
CodeNameIndex CodeNameIndexFromWXK( int aWXKey );
int WXKFromKeyEvent( uint32_t aRawKeyCode, uint32_t aRawKeyFlags );
} // namespace GeckoKeys
#endif // _GECKO_KEYS_H_