From e961307043f0ff1a877a68c6dbd155f8d7e565bf Mon Sep 17 00:00:00 2001 From: Ian McInerney Date: Sun, 25 Aug 2019 15:24:44 +0200 Subject: [PATCH] Add compatibility warning for invalid GTK accelerator keys --- include/wx/accel.h | 8 +++- src/common/accelcmn.cpp | 90 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/include/wx/accel.h b/include/wx/accel.h index c1f78d58ed..c0f23ca534 100644 --- a/include/wx/accel.h +++ b/include/wx/accel.h @@ -53,7 +53,9 @@ public: , m_keyCode(keyCode) , m_command(cmd) , m_item(item) - { } + { + ValidateKey(flags, keyCode); + } // create accelerator corresponding to the specified string, return NULL if // string couldn't be parsed or a pointer to be deleted by the caller @@ -61,6 +63,8 @@ public: void Set(int flags, int keyCode, int cmd, wxMenuItem *item = NULL) { + ValidateKey(flags, keyCode); + m_flags = flags; m_keyCode = keyCode; m_command = cmd; @@ -118,6 +122,8 @@ public: private: wxString AsPossiblyLocalizedString(bool localized) const; + static bool ValidateKey(int flags, int keycode); + // common part of Create() and FromString() static bool ParseAccel(const wxString& str, int *flags, int *keycode); diff --git a/src/common/accelcmn.cpp b/src/common/accelcmn.cpp index 820985df26..bc8937a2b8 100644 --- a/src/common/accelcmn.cpp +++ b/src/common/accelcmn.cpp @@ -156,6 +156,96 @@ static int IsNumberedAccelKey(const wxString& str, return prefixCode + num - first; } +// static +bool wxAcceleratorEntry::ValidateKey(int flags, int keycode) +{ + wxString keyname; + if ( keycode ) + { + for ( size_t n = 0; n < WXSIZEOF(wxKeyNames); n++ ) + { + const wxKeyName& kn = wxKeyNames[n]; + if ( kn.code == keycode ) + { + keyname = kn.name; + break; + } + } + + if ( keyname.IsEmpty() && keycode >= WXK_SPECIAL1 && keycode <= WXK_SPECIAL20 ) + keyname << wxS("SPECIAL") << keycode - WXK_SPECIAL1 + 1; + } + + bool valid = true; + switch ( keycode ) + { + /* + The following keycodes must have modifier keys to be valid on GTK + */ + case WXK_UP: + case WXK_DOWN: + case WXK_LEFT: + case WXK_RIGHT: + case WXK_NUMPAD_UP: + case WXK_NUMPAD_DOWN: + case WXK_NUMPAD_LEFT: + case WXK_NUMPAD_RIGHT: + if ( !flags ) + { + valid = false; + wxLogDebug( wxString::Format( wxT("Compatibility issue: %s key must have modifiers to be an accelerator key on GTK"), + keyname ) ); + } + break; + + /* + The following keycodes have been shown not to work as accelerator + keys on GTK (see https://trac.wxwidgets.org/ticket/10049) + and are not valid + (see gtkaccelgroup.c inside gtk_accelerator_valid()) + */ + case WXK_COMMAND: // Same as WXK_CONTROL + case WXK_SHIFT: + case WXK_ALT: + case WXK_SCROLL: // Scroll lock + case WXK_CAPITAL: // Caps lock + case WXK_NUMLOCK: + case WXK_NUMPAD_TAB: + case WXK_TAB: + case WXK_WINDOWS_LEFT: + case WXK_WINDOWS_RIGHT: + + /* + The following keycodes do not map clearly into a GTK keycode, + so they are not included in the accelerator mapping: + */ + case WXK_ADD: + case WXK_SEPARATOR: + case WXK_SUBTRACT: + case WXK_DECIMAL: + case WXK_DIVIDE: + case WXK_SNAPSHOT: + + /* + The following special codes do not map into GTK keycodes, + see gdk/keynames.txt + */ + case WXK_SPECIAL1: case WXK_SPECIAL2: case WXK_SPECIAL3: + case WXK_SPECIAL4: case WXK_SPECIAL5: case WXK_SPECIAL6: + case WXK_SPECIAL7: case WXK_SPECIAL8: case WXK_SPECIAL9: + case WXK_SPECIAL10: case WXK_SPECIAL11: case WXK_SPECIAL12: + case WXK_SPECIAL13: case WXK_SPECIAL14: case WXK_SPECIAL15: + case WXK_SPECIAL16: case WXK_SPECIAL17: case WXK_SPECIAL18: + case WXK_SPECIAL19: case WXK_SPECIAL20: + valid = false; + wxLogDebug( wxString::Format( wxT("Compatibility issue: %s is not supported as a keyboard accelerator key on GTK"), + keyname ) ); + break; + } + + return valid; +} + /* static */ bool wxAcceleratorEntry::ParseAccel(const wxString& text, int *flagsOut, int *keyOut)