|
|
e712f1c |
From 98065821bbf0178981b50515094f565b703fcaa8 Mon Sep 17 00:00:00 2001
|
|
|
e712f1c |
From: Scott Talbert <swt@techie.net>
|
|
|
e712f1c |
Date: Tue, 13 Sep 2016 13:24:12 +0200
|
|
|
e712f1c |
Subject: [PATCH] Fix wxGetKeyState() on non-X11 wxGTK backends (e.g., Wayland)
|
|
|
e712f1c |
|
|
|
e712f1c |
wxGetKeyState() does not currently work on non-X11 GTK backends, and in some
|
|
|
e712f1c |
cases it has been reported to crash. It seems that the most likely use case
|
|
|
e712f1c |
for wxGetKeyState() is to query the modifier keys, so on non-X11 backends, use
|
|
|
e712f1c |
GTK+ calls to retrieve the modifier key state.
|
|
|
e712f1c |
|
|
|
e712f1c |
Non-modifier keys are not currently implemented, update the documentation to
|
|
|
e712f1c |
mention this.
|
|
|
e712f1c |
|
|
|
e712f1c |
Closes https://github.com/wxWidgets/wxWidgets/pull/322
|
|
|
e712f1c |
|
|
|
e712f1c |
(this is a combined backport of 1033fb048dec849906f76ece25f154e6a61fde4e,
|
|
|
e712f1c |
9f9c09e24a7f9d86ea51997bd4c55c1ddb7c3159 and
|
|
|
e712f1c |
a18fe083cc91bee442863c8ab7f97d6549f2b75c from master)
|
|
|
e712f1c |
---
|
|
|
e712f1c |
interface/wx/utils.h | 3 +++
|
|
|
e712f1c |
src/unix/utilsx11.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++++++++--
|
|
|
e712f1c |
2 files changed, 63 insertions(+), 2 deletions(-)
|
|
|
e712f1c |
|
|
|
e712f1c |
diff --git a/interface/wx/utils.h b/interface/wx/utils.h
|
|
|
e712f1c |
index 0bac1c0..f127a74 100644
|
|
|
e712f1c |
--- a/interface/wx/utils.h
|
|
|
e712f1c |
+++ b/interface/wx/utils.h
|
|
|
e712f1c |
@@ -372,6 +372,9 @@ wxString wxGetDisplayName();
|
|
|
e712f1c |
Even though there are virtual key codes defined for mouse buttons, they
|
|
|
e712f1c |
cannot be used with this function currently.
|
|
|
e712f1c |
|
|
|
e712f1c |
+ In wxGTK, this function can be only used with modifier keys (@c WXK_ALT, @c
|
|
|
e712f1c |
+ WXK_CONTROL and @c WXK_SHIFT) when not using X11 backend currently.
|
|
|
e712f1c |
+
|
|
|
e712f1c |
@header{wx/utils.h}
|
|
|
e712f1c |
*/
|
|
|
e712f1c |
bool wxGetKeyState(wxKeyCode key);
|
|
|
e712f1c |
diff --git a/src/unix/utilsx11.cpp b/src/unix/utilsx11.cpp
|
|
|
e712f1c |
index 6b35551..efc0837 100644
|
|
|
e712f1c |
--- a/src/unix/utilsx11.cpp
|
|
|
e712f1c |
+++ b/src/unix/utilsx11.cpp
|
|
|
e712f1c |
@@ -809,7 +809,7 @@ WXKeySym wxCharCodeWXToX(int id)
|
|
|
e712f1c |
// check current state of a key
|
|
|
e712f1c |
// ----------------------------------------------------------------------------
|
|
|
e712f1c |
|
|
|
e712f1c |
-bool wxGetKeyState(wxKeyCode key)
|
|
|
e712f1c |
+static bool wxGetKeyStateX11(wxKeyCode key)
|
|
|
e712f1c |
{
|
|
|
e712f1c |
wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key !=
|
|
|
e712f1c |
WXK_MBUTTON, wxT("can't use wxGetKeyState() for mouse buttons"));
|
|
|
e712f1c |
@@ -851,11 +851,69 @@ bool wxGetKeyState(wxKeyCode key)
|
|
|
e712f1c |
// with the least-significant bit in the byte representing key 8N.
|
|
|
e712f1c |
char key_vector[32];
|
|
|
e712f1c |
XQueryKeymap(pDisplay, key_vector);
|
|
|
e712f1c |
- return key_vector[keyCode >> 3] & (1 << (keyCode & 7));
|
|
|
e712f1c |
+ return (key_vector[keyCode >> 3] & (1 << (keyCode & 7))) != 0;
|
|
|
e712f1c |
}
|
|
|
e712f1c |
|
|
|
e712f1c |
#endif // !defined(__WXGTK__) || defined(GDK_WINDOWING_X11)
|
|
|
e712f1c |
|
|
|
e712f1c |
+// We need to use GDK functions when using wxGTK with a non-X11 backend, the
|
|
|
e712f1c |
+// X11 code above can't work in this case.
|
|
|
e712f1c |
+#ifdef __WXGTK__
|
|
|
e712f1c |
+
|
|
|
e712f1c |
+// gdk_keymap_get_modifier_state() is only available since 3.4
|
|
|
e712f1c |
+#if GTK_CHECK_VERSION(3,4,0)
|
|
|
e712f1c |
+
|
|
|
e712f1c |
+#define wxHAS_GETKEYSTATE_GTK
|
|
|
e712f1c |
+
|
|
|
e712f1c |
+extern GtkWidget *wxGetRootWindow();
|
|
|
e712f1c |
+
|
|
|
e712f1c |
+static bool wxGetKeyStateGTK(wxKeyCode key)
|
|
|
e712f1c |
+{
|
|
|
e712f1c |
+ if (gtk_check_version(3,4,0) != NULL)
|
|
|
e712f1c |
+ return false;
|
|
|
e712f1c |
+
|
|
|
e712f1c |
+ GdkDisplay* display = gtk_widget_get_display(wxGetRootWindow());
|
|
|
e712f1c |
+ GdkKeymap* keymap = gdk_keymap_get_for_display(display);
|
|
|
e712f1c |
+ guint state = gdk_keymap_get_modifier_state(keymap);
|
|
|
e712f1c |
+ guint mask = 0;
|
|
|
e712f1c |
+ switch (key)
|
|
|
e712f1c |
+ {
|
|
|
e712f1c |
+ case WXK_ALT:
|
|
|
e712f1c |
+ mask = GDK_MOD1_MASK;
|
|
|
e712f1c |
+ break;
|
|
|
e712f1c |
+
|
|
|
e712f1c |
+ case WXK_CONTROL:
|
|
|
e712f1c |
+ mask = GDK_CONTROL_MASK;
|
|
|
e712f1c |
+ break;
|
|
|
e712f1c |
+
|
|
|
e712f1c |
+ case WXK_SHIFT:
|
|
|
e712f1c |
+ mask = GDK_SHIFT_MASK;
|
|
|
e712f1c |
+ break;
|
|
|
e712f1c |
+
|
|
|
e712f1c |
+ default:
|
|
|
e712f1c |
+ wxFAIL_MSG(wxS("Unsupported key, only modifiers can be used"));
|
|
|
e712f1c |
+ return false;
|
|
|
e712f1c |
+ }
|
|
|
e712f1c |
+ return (state & mask) != 0;
|
|
|
e712f1c |
+}
|
|
|
e712f1c |
+
|
|
|
e712f1c |
+#endif // GTK+ 3.4
|
|
|
e712f1c |
+#endif // __WXGTK__
|
|
|
e712f1c |
+
|
|
|
e712f1c |
+bool wxGetKeyState(wxKeyCode key)
|
|
|
e712f1c |
+{
|
|
|
e712f1c |
+#ifdef wxHAS_GETKEYSTATE_GTK
|
|
|
e712f1c |
+ GdkDisplay* display = gtk_widget_get_display(wxGetRootWindow());
|
|
|
e712f1c |
+ const char* name = g_type_name(G_TYPE_FROM_INSTANCE(display));
|
|
|
e712f1c |
+ if (strcmp(name, "GdkX11Display") != 0)
|
|
|
e712f1c |
+ {
|
|
|
e712f1c |
+ return wxGetKeyStateGTK(key);
|
|
|
e712f1c |
+ }
|
|
|
e712f1c |
+#endif // GTK+ 3.4+
|
|
|
e712f1c |
+
|
|
|
e712f1c |
+ return wxGetKeyStateX11(key);
|
|
|
e712f1c |
+}
|
|
|
e712f1c |
+
|
|
|
e712f1c |
// ----------------------------------------------------------------------------
|
|
|
e712f1c |
// Launch document with default app
|
|
|
e712f1c |
// ----------------------------------------------------------------------------
|