From a1f816e8be8cf04d65bdbb746c4de60d798298d3 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Tue, 9 Sep 2025 13:29:26 -0700 Subject: [PATCH] Add additional modifies to hotkeys Allows (depending on system) AltGr, Meta, Win, Super in combination with other keys Fixes https://gitlab.com/kicad/code/kicad/issues/1908 --- common/hotkeys_basic.cpp | 46 ++++++++++++++++++++++- common/tool/tool_dispatcher.cpp | 16 +++++++- common/tool/tool_event.cpp | 3 ++ common/widgets/lib_tree.cpp | 54 ++++++++++++++++++++++----- common/widgets/widget_hotkey_list.cpp | 27 +++++++++++--- eeschema/widgets/hierarchy_pane.cpp | 27 +++++++++++--- include/tool/tool_dispatcher.h | 26 ++++++++++--- include/tool/tool_event.h | 5 ++- 8 files changed, 174 insertions(+), 30 deletions(-) diff --git a/common/hotkeys_basic.cpp b/common/hotkeys_basic.cpp index 875d7bea04..cd8c435b8e 100644 --- a/common/hotkeys_basic.cpp +++ b/common/hotkeys_basic.cpp @@ -40,6 +40,7 @@ #include #include #include +#include /* @@ -159,6 +160,10 @@ static struct hotkey_name_descr hotkeyNameList[] = #define MODIFIER_CMD_MAC wxT( "Cmd+" ) #define MODIFIER_CTRL_BASE wxT( "Ctrl+" ) #define MODIFIER_SHIFT wxT( "Shift+" ) +#define MODIFIER_META wxT( "Meta+" ) +#define MODIFIER_WIN wxT( "Win+" ) +#define MODIFIER_SUPER wxT( "Super+" ) +#define MODIFIER_ALTGR wxT( "AltGr+" ) wxString KeyNameFromKeyCode( int aKeycode, bool* aIsFound ) @@ -175,6 +180,14 @@ wxString KeyNameFromKeyCode( int aKeycode, bool* aIsFound ) return wxString( MODIFIER_SHIFT ).BeforeFirst( '+' ); else if( aKeycode == WXK_ALT ) return wxString( MODIFIER_ALT ).BeforeFirst( '+' ); +#ifdef WXK_WINDOWS_LEFT + else if( aKeycode == WXK_WINDOWS_LEFT || aKeycode == WXK_WINDOWS_RIGHT ) + return wxString( MODIFIER_WIN ).BeforeFirst( '+' ); +#endif +#ifdef WXK_META + else if( aKeycode == WXK_META ) + return wxString( MODIFIER_META ).BeforeFirst( '+' ); +#endif // Assume keycode of 0 is "unassigned" if( (aKeycode & MD_CTRL) != 0 ) @@ -186,7 +199,16 @@ wxString KeyNameFromKeyCode( int aKeycode, bool* aIsFound ) if( (aKeycode & MD_SHIFT) != 0 ) modifier << MODIFIER_SHIFT; - aKeycode &= ~( MD_CTRL | MD_ALT | MD_SHIFT ); + if( (aKeycode & MD_META) != 0 ) + modifier << MODIFIER_META; + + if( (aKeycode & MD_SUPER) != 0 ) + modifier << MODIFIER_WIN; + + if( (aKeycode & MD_ALTGR) != 0 ) + modifier << MODIFIER_ALTGR; + + aKeycode &= ~MD_MODIFIER_MASK; if( (aKeycode > ' ') && (aKeycode < 0x7F ) ) { @@ -262,7 +284,7 @@ int KeyCodeFromKeyName( const wxString& keyname ) { int ii, keycode = KEY_NON_FOUND; - // Search for modifiers: Ctrl+ Alt+ and Shift+ + // Search for modifiers: Ctrl+ Alt+ Shift+ and others // Note: on Mac OSX, the Cmd key is equiv here to Ctrl wxString key = keyname; wxString prefix; @@ -292,6 +314,26 @@ int KeyCodeFromKeyName( const wxString& keyname ) modifier |= MD_SHIFT; prefix = MODIFIER_SHIFT; } + else if( key.StartsWith( MODIFIER_META ) ) + { + modifier |= MD_META; + prefix = MODIFIER_META; + } + else if( key.StartsWith( MODIFIER_WIN ) ) + { + modifier |= MD_SUPER; + prefix = MODIFIER_WIN; + } + else if( key.StartsWith( MODIFIER_SUPER ) ) + { + modifier |= MD_SUPER; + prefix = MODIFIER_SUPER; + } + else if( key.StartsWith( MODIFIER_ALTGR ) ) + { + modifier |= MD_ALTGR; + prefix = MODIFIER_ALTGR; + } else { break; diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp index 59ca3ba873..5c1030ccd3 100644 --- a/common/tool/tool_dispatcher.cpp +++ b/common/tool/tool_dispatcher.cpp @@ -297,7 +297,19 @@ static bool isKeyModifierOnly( int aKeyCode ) { static std::vector special_keys = { - WXK_CONTROL, WXK_RAW_CONTROL, WXK_SHIFT, WXK_ALT + WXK_CONTROL, WXK_RAW_CONTROL, WXK_SHIFT, WXK_ALT, +#ifdef WXK_WINDOWS_LEFT + WXK_WINDOWS_LEFT, WXK_WINDOWS_RIGHT, +#endif +#ifdef WXK_MENU + WXK_MENU, +#endif +#ifdef WXK_COMMAND + WXK_COMMAND, +#endif +#ifdef WXK_META + WXK_META, +#endif }; return alg::contains( special_keys, aKeyCode ); @@ -515,7 +527,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) if( !evt && me->GetWheelRotation() != 0 ) { const unsigned modBits = - static_cast( mods ) & ( MD_CTRL | MD_ALT | MD_SHIFT ); + static_cast( mods ) & MD_MODIFIER_MASK; const bool shouldHandle = std::popcount( modBits ) > 1; if( shouldHandle ) diff --git a/common/tool/tool_event.cpp b/common/tool/tool_event.cpp index 7e4954a22c..50be89b77d 100644 --- a/common/tool/tool_event.cpp +++ b/common/tool/tool_event.cpp @@ -149,6 +149,9 @@ const std::string TOOL_EVENT::Format() const { MD_SHIFT, "shift" }, { MD_CTRL, "ctrl" }, { MD_ALT, "alt" }, + { MD_SUPER, "super" }, + { MD_META, "meta" }, + { MD_ALTGR, "altgr" }, { 0, "" } }; diff --git a/common/widgets/lib_tree.cpp b/common/widgets/lib_tree.cpp index 8a2a4e9ee1..e2c94c9be3 100644 --- a/common/widgets/lib_tree.cpp +++ b/common/widgets/lib_tree.cpp @@ -640,15 +640,32 @@ void LIB_TREE::onQueryCharHook( wxKeyEvent& aKeyStroke ) { int hotkey = aKeyStroke.GetKeyCode(); - if( aKeyStroke.GetModifiers() & wxMOD_CONTROL ) - hotkey += MD_CTRL; + int mods = aKeyStroke.GetModifiers(); - if( aKeyStroke.GetModifiers() & wxMOD_ALT ) - hotkey += MD_ALT; + if( mods & wxMOD_ALTGR ) + hotkey += MD_ALTGR; + else + { + if( mods & wxMOD_CONTROL ) + hotkey += MD_CTRL; - if( aKeyStroke.GetModifiers() & wxMOD_SHIFT ) + if( mods & wxMOD_ALT ) + hotkey += MD_ALT; + } + + if( mods & wxMOD_SHIFT ) hotkey += MD_SHIFT; +#ifdef wxMOD_META + if( mods & wxMOD_META ) + hotkey += MD_META; +#endif + +#ifdef wxMOD_WIN + if( mods & wxMOD_WIN ) + hotkey += MD_SUPER; +#endif + if( hotkey == ACTIONS::expandAll.GetHotKey() || hotkey == ACTIONS::expandAll.GetHotKeyAlt() ) { @@ -860,14 +877,31 @@ void LIB_TREE::onTreeCharHook( wxKeyEvent& aKeyStroke ) { int hotkey = aKeyStroke.GetKeyCode(); - if( aKeyStroke.ShiftDown() ) + int mods = aKeyStroke.GetModifiers(); + + if( mods & wxMOD_ALTGR ) + hotkey |= MD_ALTGR; + else + { + if( mods & wxMOD_ALT ) + hotkey |= MD_ALT; + + if( mods & wxMOD_CONTROL ) + hotkey |= MD_CTRL; + } + + if( mods & wxMOD_SHIFT ) hotkey |= MD_SHIFT; - if( aKeyStroke.AltDown() ) - hotkey |= MD_ALT; +#ifdef wxMOD_META + if( mods & wxMOD_META ) + hotkey |= MD_META; +#endif - if( aKeyStroke.ControlDown() ) - hotkey |= MD_CTRL; +#ifdef wxMOD_WIN + if( mods & wxMOD_WIN ) + hotkey |= MD_SUPER; +#endif if( tool->GetManager()->GetActionManager()->RunHotKey( hotkey ) ) aKeyStroke.Skip( false ); diff --git a/common/widgets/widget_hotkey_list.cpp b/common/widgets/widget_hotkey_list.cpp index 7870780d76..58da3318c3 100644 --- a/common/widgets/widget_hotkey_list.cpp +++ b/common/widgets/widget_hotkey_list.cpp @@ -693,14 +693,31 @@ long WIDGET_HOTKEY_LIST::MapKeypressToKeycode( const wxKeyEvent& aEvent ) */ bool keyIsLetter = key >= 'A' && key <= 'Z'; - if( aEvent.ShiftDown() && ( keyIsLetter || key > 256 || key == 9 || key == 32 ) ) + int mods = aEvent.GetModifiers(); + + if( ( mods & wxMOD_SHIFT ) && ( keyIsLetter || key > 256 || key == 9 || key == 32 ) ) key |= MD_SHIFT; - if( aEvent.ControlDown() ) - key |= MD_CTRL; + if( mods & wxMOD_ALTGR ) + key |= MD_ALTGR; + else + { + if( mods & wxMOD_CONTROL ) + key |= MD_CTRL; - if( aEvent.AltDown() ) - key |= MD_ALT; + if( mods & wxMOD_ALT ) + key |= MD_ALT; + } + +#ifdef wxMOD_META + if( mods & wxMOD_META ) + key |= MD_META; +#endif + +#ifdef wxMOD_WIN + if( mods & wxMOD_WIN ) + key |= MD_SUPER; +#endif return key; } diff --git a/eeschema/widgets/hierarchy_pane.cpp b/eeschema/widgets/hierarchy_pane.cpp index 436b2a9135..8d2f483092 100644 --- a/eeschema/widgets/hierarchy_pane.cpp +++ b/eeschema/widgets/hierarchy_pane.cpp @@ -546,15 +546,32 @@ void HIERARCHY_PANE::onCharHook( wxKeyEvent& aKeyStroke ) { int hotkey = aKeyStroke.GetKeyCode(); - if( aKeyStroke.GetModifiers() & wxMOD_CONTROL ) - hotkey += MD_CTRL; + int mods = aKeyStroke.GetModifiers(); - if( aKeyStroke.GetModifiers() & wxMOD_ALT ) - hotkey += MD_ALT; + if( mods & wxMOD_ALTGR ) + hotkey += MD_ALTGR; + else + { + if( mods & wxMOD_CONTROL ) + hotkey += MD_CTRL; - if( aKeyStroke.GetModifiers() & wxMOD_SHIFT ) + if( mods & wxMOD_ALT ) + hotkey += MD_ALT; + } + + if( mods & wxMOD_SHIFT ) hotkey += MD_SHIFT; +#ifdef wxMOD_META + if( mods & wxMOD_META ) + hotkey += MD_META; +#endif + +#ifdef wxMOD_WIN + if( mods & wxMOD_WIN ) + hotkey += MD_SUPER; +#endif + if( hotkey == ACTIONS::expandAll.GetHotKey() || hotkey == ACTIONS::expandAll.GetHotKeyAlt() ) { diff --git a/include/tool/tool_dispatcher.h b/include/tool/tool_dispatcher.h index c0ece5585b..d2fc758ee6 100644 --- a/include/tool/tool_dispatcher.h +++ b/include/tool/tool_dispatcher.h @@ -88,16 +88,32 @@ private: static int decodeModifiers( const wxKeyboardState* aState ) { int mods = 0; + int wxmods = aState->GetModifiers(); - if( aState->ControlDown() ) - mods |= MD_CTRL; + if( wxmods & wxMOD_ALTGR ) + mods |= MD_ALTGR; + else + { + if( wxmods & wxMOD_CONTROL ) + mods |= MD_CTRL; - if( aState->AltDown() ) - mods |= MD_ALT; + if( wxmods & wxMOD_ALT ) + mods |= MD_ALT; + } - if( aState->ShiftDown() ) + if( wxmods & wxMOD_SHIFT ) mods |= MD_SHIFT; +#ifdef wxMOD_META + if( wxmods & wxMOD_META ) + mods |= MD_META; +#endif + +#ifdef wxMOD_WIN + if( wxmods & wxMOD_WIN ) + mods |= MD_SUPER; +#endif + return mods; } diff --git a/include/tool/tool_event.h b/include/tool/tool_event.h index ae49111cca..79fadb2d2e 100644 --- a/include/tool/tool_event.h +++ b/include/tool/tool_event.h @@ -143,7 +143,10 @@ enum TOOL_MODIFIERS MD_SHIFT = 0x1000, MD_CTRL = 0x2000, MD_ALT = 0x4000, - MD_MODIFIER_MASK = MD_SHIFT | MD_CTRL | MD_ALT, + MD_SUPER = 0x8000, + MD_META = 0x10000, + MD_ALTGR = 0x20000, + MD_MODIFIER_MASK = MD_SHIFT | MD_CTRL | MD_ALT | MD_SUPER | MD_META | MD_ALTGR, }; /// Defines when a context menu is opened.