diff --git a/interface/wx/utils.h b/interface/wx/utils.h index 0bac1c07a0..f127a74084 100644 --- a/interface/wx/utils.h +++ b/interface/wx/utils.h @@ -372,6 +372,9 @@ wxString wxGetDisplayName(); Even though there are virtual key codes defined for mouse buttons, they cannot be used with this function currently. + In wxGTK, this function can be only used with modifier keys (@c WXK_ALT, @c + WXK_CONTROL and @c WXK_SHIFT) when not using X11 backend currently. + @header{wx/utils.h} */ bool wxGetKeyState(wxKeyCode key); diff --git a/src/unix/utilsx11.cpp b/src/unix/utilsx11.cpp index 6b35551647..efc0837431 100644 --- a/src/unix/utilsx11.cpp +++ b/src/unix/utilsx11.cpp @@ -809,7 +809,7 @@ WXKeySym wxCharCodeWXToX(int id) // check current state of a key // ---------------------------------------------------------------------------- -bool wxGetKeyState(wxKeyCode key) +static bool wxGetKeyStateX11(wxKeyCode key) { wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key != WXK_MBUTTON, wxT("can't use wxGetKeyState() for mouse buttons")); @@ -851,11 +851,69 @@ bool wxGetKeyState(wxKeyCode key) // with the least-significant bit in the byte representing key 8N. char key_vector[32]; XQueryKeymap(pDisplay, key_vector); - return key_vector[keyCode >> 3] & (1 << (keyCode & 7)); + return (key_vector[keyCode >> 3] & (1 << (keyCode & 7))) != 0; } #endif // !defined(__WXGTK__) || defined(GDK_WINDOWING_X11) +// We need to use GDK functions when using wxGTK with a non-X11 backend, the +// X11 code above can't work in this case. +#ifdef __WXGTK__ + +// gdk_keymap_get_modifier_state() is only available since 3.4 +#if GTK_CHECK_VERSION(3,4,0) + +#define wxHAS_GETKEYSTATE_GTK + +extern GtkWidget *wxGetRootWindow(); + +static bool wxGetKeyStateGTK(wxKeyCode key) +{ + if (gtk_check_version(3,4,0) != NULL) + return false; + + GdkDisplay* display = gtk_widget_get_display(wxGetRootWindow()); + GdkKeymap* keymap = gdk_keymap_get_for_display(display); + guint state = gdk_keymap_get_modifier_state(keymap); + guint mask = 0; + switch (key) + { + case WXK_ALT: + mask = GDK_MOD1_MASK; + break; + + case WXK_CONTROL: + mask = GDK_CONTROL_MASK; + break; + + case WXK_SHIFT: + mask = GDK_SHIFT_MASK; + break; + + default: + wxFAIL_MSG(wxS("Unsupported key, only modifiers can be used")); + return false; + } + return (state & mask) != 0; +} + +#endif // GTK+ 3.4 +#endif // __WXGTK__ + +bool wxGetKeyState(wxKeyCode key) +{ +#ifdef wxHAS_GETKEYSTATE_GTK + GdkDisplay* display = gtk_widget_get_display(wxGetRootWindow()); + const char* name = g_type_name(G_TYPE_FROM_INSTANCE(display)); + if (strcmp(name, "GdkX11Display") != 0) + { + return wxGetKeyStateGTK(key); + } +#endif // GTK+ 3.4+ + + return wxGetKeyStateX11(key); +} + // ---------------------------------------------------------------------------- // Launch document with default app // ----------------------------------------------------------------------------