From 3be5046f0fffe277e2c3c18bfd6c7371464c4f4e Mon Sep 17 00:00:00 2001 From: Damjan Prerad Date: Tue, 10 Feb 2026 18:07:22 +0100 Subject: [PATCH] Fix uppercase 'X' in text controls when menu accelerator steals key event On macOS, menu accelerators intercept key events before they reach focused text controls. The existing workaround in ACTION_MENU::OnMenuEvent re-creates the key event but uses the raw key code (always uppercase for letters) when converting. Fix by checking the actual Shift/CapsLock keyboard state and converting the key code to the correct case before forwarding the synthetic wxEVT_CHAR event. Row 53 --- common/tool/action_menu.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/common/tool/action_menu.cpp b/common/tool/action_menu.cpp index 380c78e712..18d5d19f7a 100644 --- a/common/tool/action_menu.cpp +++ b/common/tool/action_menu.cpp @@ -471,6 +471,26 @@ void ACTION_MENU::OnMenuEvent( wxMenuEvent& aEvent ) if( keyEvent.GetSkipped() ) { keyEvent.SetEventType( wxEVT_CHAR ); + + // CHAR_HOOK always uses uppercase key codes for letters, but + // wxEVT_CHAR should use the translated (case-correct) character. + // Since the original key event was lost to the menu system, check + // the actual keyboard state to determine proper case. + int keyCode = keyEvent.GetKeyCode(); + + if( keyCode >= 'A' && keyCode <= 'Z' ) + { + bool shiftActive = wxGetKeyState( WXK_SHIFT ); + bool capsActive = wxGetKeyState( WXK_CAPITAL ); + + if( !( shiftActive ^ capsActive ) ) + keyEvent.m_keyCode = keyCode + 32; // Convert to lowercase + } + + #if wxUSE_UNICODE + keyEvent.m_uniChar = keyEvent.m_keyCode; + #endif + focus->HandleWindowEvent( keyEvent ); }