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
This commit is contained in:
Seth Hillbrand 2025-09-09 13:29:26 -07:00
parent abf3438ed6
commit a1f816e8be
8 changed files with 174 additions and 30 deletions

View File

@ -40,6 +40,7 @@
#include <wx/txtstrm.h> #include <wx/txtstrm.h>
#include <wx/wfstream.h> #include <wx/wfstream.h>
#include <tool/tool_action.h> #include <tool/tool_action.h>
#include <tool/tool_event.h>
/* /*
@ -159,6 +160,10 @@ static struct hotkey_name_descr hotkeyNameList[] =
#define MODIFIER_CMD_MAC wxT( "Cmd+" ) #define MODIFIER_CMD_MAC wxT( "Cmd+" )
#define MODIFIER_CTRL_BASE wxT( "Ctrl+" ) #define MODIFIER_CTRL_BASE wxT( "Ctrl+" )
#define MODIFIER_SHIFT wxT( "Shift+" ) #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 ) wxString KeyNameFromKeyCode( int aKeycode, bool* aIsFound )
@ -175,6 +180,14 @@ wxString KeyNameFromKeyCode( int aKeycode, bool* aIsFound )
return wxString( MODIFIER_SHIFT ).BeforeFirst( '+' ); return wxString( MODIFIER_SHIFT ).BeforeFirst( '+' );
else if( aKeycode == WXK_ALT ) else if( aKeycode == WXK_ALT )
return wxString( MODIFIER_ALT ).BeforeFirst( '+' ); 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" // Assume keycode of 0 is "unassigned"
if( (aKeycode & MD_CTRL) != 0 ) if( (aKeycode & MD_CTRL) != 0 )
@ -186,7 +199,16 @@ wxString KeyNameFromKeyCode( int aKeycode, bool* aIsFound )
if( (aKeycode & MD_SHIFT) != 0 ) if( (aKeycode & MD_SHIFT) != 0 )
modifier << MODIFIER_SHIFT; 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 ) ) if( (aKeycode > ' ') && (aKeycode < 0x7F ) )
{ {
@ -262,7 +284,7 @@ int KeyCodeFromKeyName( const wxString& keyname )
{ {
int ii, keycode = KEY_NON_FOUND; 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 // Note: on Mac OSX, the Cmd key is equiv here to Ctrl
wxString key = keyname; wxString key = keyname;
wxString prefix; wxString prefix;
@ -292,6 +314,26 @@ int KeyCodeFromKeyName( const wxString& keyname )
modifier |= MD_SHIFT; modifier |= MD_SHIFT;
prefix = MODIFIER_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 else
{ {
break; break;

View File

@ -297,7 +297,19 @@ static bool isKeyModifierOnly( int aKeyCode )
{ {
static std::vector<enum wxKeyCode> special_keys = static std::vector<enum wxKeyCode> 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 ); return alg::contains( special_keys, aKeyCode );
@ -515,7 +527,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
if( !evt && me->GetWheelRotation() != 0 ) if( !evt && me->GetWheelRotation() != 0 )
{ {
const unsigned modBits = const unsigned modBits =
static_cast<unsigned>( mods ) & ( MD_CTRL | MD_ALT | MD_SHIFT ); static_cast<unsigned>( mods ) & MD_MODIFIER_MASK;
const bool shouldHandle = std::popcount( modBits ) > 1; const bool shouldHandle = std::popcount( modBits ) > 1;
if( shouldHandle ) if( shouldHandle )

View File

@ -149,6 +149,9 @@ const std::string TOOL_EVENT::Format() const
{ MD_SHIFT, "shift" }, { MD_SHIFT, "shift" },
{ MD_CTRL, "ctrl" }, { MD_CTRL, "ctrl" },
{ MD_ALT, "alt" }, { MD_ALT, "alt" },
{ MD_SUPER, "super" },
{ MD_META, "meta" },
{ MD_ALTGR, "altgr" },
{ 0, "" } { 0, "" }
}; };

View File

@ -640,15 +640,32 @@ void LIB_TREE::onQueryCharHook( wxKeyEvent& aKeyStroke )
{ {
int hotkey = aKeyStroke.GetKeyCode(); int hotkey = aKeyStroke.GetKeyCode();
if( aKeyStroke.GetModifiers() & wxMOD_CONTROL ) int mods = aKeyStroke.GetModifiers();
if( mods & wxMOD_ALTGR )
hotkey += MD_ALTGR;
else
{
if( mods & wxMOD_CONTROL )
hotkey += MD_CTRL; hotkey += MD_CTRL;
if( aKeyStroke.GetModifiers() & wxMOD_ALT ) if( mods & wxMOD_ALT )
hotkey += MD_ALT; hotkey += MD_ALT;
}
if( aKeyStroke.GetModifiers() & wxMOD_SHIFT ) if( mods & wxMOD_SHIFT )
hotkey += MD_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() if( hotkey == ACTIONS::expandAll.GetHotKey()
|| hotkey == ACTIONS::expandAll.GetHotKeyAlt() ) || hotkey == ACTIONS::expandAll.GetHotKeyAlt() )
{ {
@ -860,14 +877,31 @@ void LIB_TREE::onTreeCharHook( wxKeyEvent& aKeyStroke )
{ {
int hotkey = aKeyStroke.GetKeyCode(); int hotkey = aKeyStroke.GetKeyCode();
if( aKeyStroke.ShiftDown() ) int mods = aKeyStroke.GetModifiers();
hotkey |= MD_SHIFT;
if( aKeyStroke.AltDown() ) if( mods & wxMOD_ALTGR )
hotkey |= MD_ALTGR;
else
{
if( mods & wxMOD_ALT )
hotkey |= MD_ALT; hotkey |= MD_ALT;
if( aKeyStroke.ControlDown() ) if( mods & wxMOD_CONTROL )
hotkey |= MD_CTRL; hotkey |= MD_CTRL;
}
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( tool->GetManager()->GetActionManager()->RunHotKey( hotkey ) ) if( tool->GetManager()->GetActionManager()->RunHotKey( hotkey ) )
aKeyStroke.Skip( false ); aKeyStroke.Skip( false );

View File

@ -693,14 +693,31 @@ long WIDGET_HOTKEY_LIST::MapKeypressToKeycode( const wxKeyEvent& aEvent )
*/ */
bool keyIsLetter = key >= 'A' && key <= 'Z'; 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; key |= MD_SHIFT;
if( aEvent.ControlDown() ) if( mods & wxMOD_ALTGR )
key |= MD_ALTGR;
else
{
if( mods & wxMOD_CONTROL )
key |= MD_CTRL; key |= MD_CTRL;
if( aEvent.AltDown() ) if( mods & wxMOD_ALT )
key |= MD_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; return key;
} }

View File

@ -546,15 +546,32 @@ void HIERARCHY_PANE::onCharHook( wxKeyEvent& aKeyStroke )
{ {
int hotkey = aKeyStroke.GetKeyCode(); int hotkey = aKeyStroke.GetKeyCode();
if( aKeyStroke.GetModifiers() & wxMOD_CONTROL ) int mods = aKeyStroke.GetModifiers();
if( mods & wxMOD_ALTGR )
hotkey += MD_ALTGR;
else
{
if( mods & wxMOD_CONTROL )
hotkey += MD_CTRL; hotkey += MD_CTRL;
if( aKeyStroke.GetModifiers() & wxMOD_ALT ) if( mods & wxMOD_ALT )
hotkey += MD_ALT; hotkey += MD_ALT;
}
if( aKeyStroke.GetModifiers() & wxMOD_SHIFT ) if( mods & wxMOD_SHIFT )
hotkey += MD_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() if( hotkey == ACTIONS::expandAll.GetHotKey()
|| hotkey == ACTIONS::expandAll.GetHotKeyAlt() ) || hotkey == ACTIONS::expandAll.GetHotKeyAlt() )
{ {

View File

@ -88,16 +88,32 @@ private:
static int decodeModifiers( const wxKeyboardState* aState ) static int decodeModifiers( const wxKeyboardState* aState )
{ {
int mods = 0; int mods = 0;
int wxmods = aState->GetModifiers();
if( aState->ControlDown() ) if( wxmods & wxMOD_ALTGR )
mods |= MD_ALTGR;
else
{
if( wxmods & wxMOD_CONTROL )
mods |= MD_CTRL; mods |= MD_CTRL;
if( aState->AltDown() ) if( wxmods & wxMOD_ALT )
mods |= MD_ALT; mods |= MD_ALT;
}
if( aState->ShiftDown() ) if( wxmods & wxMOD_SHIFT )
mods |= MD_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; return mods;
} }

View File

@ -143,7 +143,10 @@ enum TOOL_MODIFIERS
MD_SHIFT = 0x1000, MD_SHIFT = 0x1000,
MD_CTRL = 0x2000, MD_CTRL = 0x2000,
MD_ALT = 0x4000, 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. /// Defines when a context menu is opened.