Fix wxGetKeyState() on non-X11 wxGTK backends (e.g., Wayland)

wxGetKeyState() does not currently work on non-X11 GTK backends, and in some
cases it has been reported to crash.  It seems that the most likely use case
for wxGetKeyState() is to query the modifier keys, so on non-X11 backends, use
GTK+ calls to retrieve the modifier key state.

Non-modifier keys are not currently implemented, update the documentation to
mention this.

Closes https://github.com/wxWidgets/wxWidgets/pull/320
This commit is contained in:
Scott Talbert 2016-09-02 20:38:00 -04:00 committed by Vadim Zeitlin
parent 897ffb58b0
commit 1033fb048d
2 changed files with 60 additions and 1 deletions

View File

@ -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);

View File

@ -2535,7 +2535,7 @@ int wxUnicodeCharXToWX(WXKeySym keySym)
// 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"));
@ -2582,6 +2582,62 @@ bool wxGetKeyState(wxKeyCode key)
#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
static bool wxGetKeyStateGTK(wxKeyCode key)
{
if (gtk_check_version(3,4,0) != NULL)
return false;
GdkDisplay* display = gdk_window_get_display(wxGetTopLevelGDK());
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:
wxASSERT_MSG(wxS("Unsupported key, only modifiers can be used"));
return false;
}
return state & mask;
}
#endif // GTK+ 3.4
#endif // __WXGTK__
bool wxGetKeyState(wxKeyCode key)
{
#ifdef wxHAS_GETKEYSTATE_GTK
GdkDisplay* display = gdk_window_get_display(wxGetTopLevelGDK());
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
// ----------------------------------------------------------------------------