You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
122 lines
4.1 KiB
122 lines
4.1 KiB
From 98065821bbf0178981b50515094f565b703fcaa8 Mon Sep 17 00:00:00 2001
|
|
From: Scott Talbert <swt@techie.net>
|
|
Date: Tue, 13 Sep 2016 13:24:12 +0200
|
|
Subject: [PATCH] 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 of 1033fb048dec849906f76ece25f154e6a61fde4e,
|
|
9f9c09e24a7f9d86ea51997bd4c55c1ddb7c3159 and
|
|
a18fe083cc91bee442863c8ab7f97d6549f2b75c from master)
|
|
---
|
|
interface/wx/utils.h | 3 +++
|
|
src/unix/utilsx11.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++++++++--
|
|
2 files changed, 63 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/interface/wx/utils.h b/interface/wx/utils.h
|
|
index 0bac1c0..f127a74 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 6b35551..efc0837 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
|
|
// ----------------------------------------------------------------------------
|