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/322 (this is a combined backport of1033fb048d
,9f9c09e24a
anda18fe083cc
from master)
This commit is contained in:
committed by
Vadim Zeitlin
parent
fcb8497def
commit
98065821bb
@@ -372,6 +372,9 @@ wxString wxGetDisplayName();
|
|||||||
Even though there are virtual key codes defined for mouse buttons, they
|
Even though there are virtual key codes defined for mouse buttons, they
|
||||||
cannot be used with this function currently.
|
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}
|
@header{wx/utils.h}
|
||||||
*/
|
*/
|
||||||
bool wxGetKeyState(wxKeyCode key);
|
bool wxGetKeyState(wxKeyCode key);
|
||||||
|
@@ -809,7 +809,7 @@ WXKeySym wxCharCodeWXToX(int id)
|
|||||||
// check current state of a key
|
// check current state of a key
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool wxGetKeyState(wxKeyCode key)
|
static bool wxGetKeyStateX11(wxKeyCode key)
|
||||||
{
|
{
|
||||||
wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key !=
|
wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key !=
|
||||||
WXK_MBUTTON, wxT("can't use wxGetKeyState() for mouse buttons"));
|
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.
|
// with the least-significant bit in the byte representing key 8N.
|
||||||
char key_vector[32];
|
char key_vector[32];
|
||||||
XQueryKeymap(pDisplay, key_vector);
|
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)
|
#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
|
// Launch document with default app
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
Reference in New Issue
Block a user