diff --git a/interface/wx/event.h b/interface/wx/event.h index 1096d48f12..8744f1be34 100644 --- a/interface/wx/event.h +++ b/interface/wx/event.h @@ -1300,10 +1300,20 @@ enum wxKeyCategoryFlags /// home and end keys, on and off numeric keypads WXK_CATEGORY_JUMP, - /// tab key, on and off numeric keypads + /** + Tab key, on and off numeric keypads. + + Note that while `Ctrl+I` and `TAB` keys generate the same key code, + only the latter is considered to be in this category. + */ WXK_CATEGORY_TAB, - /// backspace and delete keys, on and off numeric keypads + /** + Backspace and delete keys, on and off numeric keypads. + + Note that while `Ctrl+H` and `BACKSPACE` keys generate the same key + code, only the latter is considered to be in this category. + */ WXK_CATEGORY_CUT, /// union of WXK_CATEGORY_ARROW, WXK_CATEGORY_PAGING, and WXK_CATEGORY_JUMP categories diff --git a/samples/keyboard/keyboard.cpp b/samples/keyboard/keyboard.cpp index 98f32da274..fdbc5eb818 100644 --- a/samples/keyboard/keyboard.cpp +++ b/samples/keyboard/keyboard.cpp @@ -236,8 +236,8 @@ MyFrame::MyFrame(const wxString& title) wxDefaultPosition, wxDefaultSize, wxTE_READONLY); headerText->SetValue( - " event key KeyCode mod UnicodeKey " - " RawKeyCode RawKeyFlags Position Repeat"); + " event key KeyCode mod UnicodeKey " + " RawKeyCode RawKeyFlags Position Repeat? Category"); m_logText = new wxTextCtrl(this, wxID_ANY, "", @@ -257,7 +257,7 @@ MyFrame::MyFrame(const wxString& title) SetSizerAndFit(sizer); // set size and position on screen - SetSize(700, 340); + SetSize(FromDIP(wxSize(700, 340))); CentreOnScreen(); // connect menu event handlers @@ -537,6 +537,33 @@ wxString GetKeyName(const wxKeyEvent &event) return "unknown"; } +// another helper showing the key category as determined by IsKeyInCategory(). +wxString GetKeyCategory(const wxKeyEvent& event) +{ + struct Category + { + wxKeyCategoryFlags category; + const char* name; + }; + + const Category categories[] = + { + { WXK_CATEGORY_ARROW, "arrow" }, + { WXK_CATEGORY_PAGING, "page" }, + { WXK_CATEGORY_JUMP, "jump" }, + { WXK_CATEGORY_TAB, "tab" }, + { WXK_CATEGORY_CUT, "cut" }, + }; + + for ( const auto& cat : categories ) + { + if ( event.IsKeyInCategory(cat.category) ) + return cat.name; + } + + return {}; +} + void MyFrame::LogEvent(const wxString& name, wxKeyEvent& event) { @@ -551,6 +578,7 @@ void MyFrame::LogEvent(const wxString& name, wxKeyEvent& event) #endif " (%5d,%5d)" " %s" + " %s" "\n", name, GetKeyName(event), @@ -568,6 +596,7 @@ void MyFrame::LogEvent(const wxString& name, wxKeyEvent& event) , event.GetX() , event.GetY() , event.IsAutoRepeat() ? "Yes" : "No" + , GetKeyCategory(event) ); m_logText->AppendText(msg); diff --git a/src/common/event.cpp b/src/common/event.cpp index b0a1100d3b..0ad7eaaa4d 100644 --- a/src/common/event.cpp +++ b/src/common/event.cpp @@ -849,10 +849,58 @@ bool wxKeyEvent::IsKeyInCategory(int category) const return (category & WXK_CATEGORY_JUMP) != 0; case WXK_TAB: + // We have to make an extra check for this one, as it's a synonym + // for Ctrl-I, but we don't want to recognize Ctrl-I as a TAB key. + // As raw key codes are platform-dependent we have to do it in + // platform-specific way. +#ifdef __WXMSW__ + // Under Windows the native WM_CHAR already does the translation + // and so we need to look at the scan code, which is part of the + // flags, rather than the key code itself. + if ( ((GetRawKeyFlags() >> 16) & 0xff) == 0x17 ) + { + return false; + } +#else // !__WXMSW__ + // For the other platforms we can use the raw key code, but it's + // still different, with Mac doing its own thing. We assume all the + // other platforms do as GTK does and use either "I" or "i" for + // this letter events. + switch ( GetRawKeyCode() ) + { +#ifdef __WXOSX__ + case 0x22: // kVK_ANSI_I +#else + case 'I': + case 'i': +#endif + return false; + } +#endif // __WXMSW__/!__WXMSW__ + wxFALLTHROUGH; case WXK_NUMPAD_TAB: return (category & WXK_CATEGORY_TAB) != 0; case WXK_BACK: + // See the comment above for TAB. +#ifdef __WXMSW__ + if ( ((GetRawKeyFlags() >> 16) & 0xff) == 0x23 ) + { + return false; + } +#else // !__WXMSW__ + switch ( GetRawKeyCode() ) + { +#ifdef __WXOSX__ + case 0x04: // kVK_ANSI_H +#else + case 'H': + case 'h': +#endif + return false; + } +#endif // __WXMSW__/!__WXMSW__ + wxFALLTHROUGH; case WXK_DELETE: case WXK_NUMPAD_DELETE: return (category & WXK_CATEGORY_CUT) != 0;