Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/ghost/intern/GHOST_SystemX11.cpp')
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp63
1 files changed, 54 insertions, 9 deletions
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index 325cba0c631..3e1dbd18119 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -48,7 +48,7 @@
#include "GHOST_DisplayManagerX11.h"
#include "GHOST_EventDragnDrop.h"
#ifdef WITH_INPUT_NDOF
-# include "GHOST_NDOFManagerX11.h"
+# include "GHOST_NDOFManagerUnix.h"
#endif
#ifdef WITH_XDND
@@ -76,6 +76,10 @@
/* see [#34039] Fix Alt key glitch on Unity desktop */
#define USE_UNITY_WORKAROUND
+/* Fix 'shortcut' part of keyboard reading code only ever using first defined keymap instead of active one.
+ * See T47228 and D1746 */
+#define USE_NON_LATIN_KB_WORKAROUND
+
static GHOST_TKey convertXKey(KeySym key);
/* these are for copy and select copy */
@@ -202,7 +206,7 @@ init()
if (success) {
#ifdef WITH_INPUT_NDOF
- m_ndofManager = new GHOST_NDOFManagerX11(*this);
+ m_ndofManager = new GHOST_NDOFManagerUnix(*this);
#endif
m_displayManager = new GHOST_DisplayManagerX11(this);
@@ -589,7 +593,7 @@ processEvents(
}
#ifdef WITH_INPUT_NDOF
- if (static_cast<GHOST_NDOFManagerX11 *>(m_ndofManager)->processEvents()) {
+ if (static_cast<GHOST_NDOFManagerUnix *>(m_ndofManager)->processEvents()) {
anyProcessed = true;
}
#endif
@@ -762,6 +766,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
{
XKeyEvent *xke = &(xe->xkey);
KeySym key_sym;
+ KeySym key_sym_str;
char ascii;
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
/* utf8_array[] is initial buffer used for Xutf8LookupString().
@@ -777,8 +782,50 @@ GHOST_SystemX11::processEvent(XEvent *xe)
char *utf8_buf = NULL;
#endif
+ GHOST_TEventType type = (xke->type == KeyPress) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp;
+
GHOST_TKey gkey;
+#ifdef USE_NON_LATIN_KB_WORKAROUND
+ /* XXX Code below is kinda awfully convoluted... Issues are:
+ *
+ * - In keyboards like latin ones, numbers need a 'Shift' to be accessed but key_sym
+ * is unmodified (or anyone swapping the keys with xmodmap).
+ *
+ * - XLookupKeysym seems to always use first defined keymap (see T47228), which generates
+ * keycodes unusable by convertXKey for non-latin-compatible keymaps.
+ *
+ * To address this, we:
+ *
+ * - Try to get a 'number' key_sym using XLookupKeysym (with or without shift modifier).
+ * - Fallback to XLookupString to get a key_sym from active user-defined keymap.
+ *
+ * Note that this enforces users to use an ascii-compatible keymap with Blender - but at least it gives
+ * predictable and consistent results.
+ *
+ * Also, note that nothing in XLib sources [1] makes it obvious why those two functions give different
+ * key_sym results...
+ *
+ * [1] http://cgit.freedesktop.org/xorg/lib/libX11/tree/src/KeyBind.c
+ */
+ if ((xke->keycode >= 10 && xke->keycode < 20)) {
+ key_sym = XLookupKeysym(xke, ShiftMask);
+ if (!((key_sym >= XK_0) && (key_sym <= XK_9))) {
+ key_sym = XLookupKeysym(xke, 0);
+ }
+ }
+ else {
+ key_sym = XLookupKeysym(xke, 0);
+ }
+
+ if (!XLookupString(xke, &ascii, 1, &key_sym_str, NULL)) {
+ ascii = '\0';
+ }
+
+ if ((gkey = convertXKey(key_sym)) == GHOST_kKeyUnknown) {
+ gkey = convertXKey(key_sym_str);
+ }
+#else
/* In keyboards like latin ones,
* numbers needs a 'Shift' to be accessed but key_sym
* is unmodified (or anyone swapping the keys with xmodmap).
@@ -799,14 +846,12 @@ GHOST_SystemX11::processEvent(XEvent *xe)
}
gkey = convertXKey(key_sym);
-
- GHOST_TEventType type = (xke->type == KeyPress) ?
- GHOST_kEventKeyDown : GHOST_kEventKeyUp;
if (!XLookupString(xke, &ascii, 1, NULL, NULL)) {
ascii = '\0';
}
-
+#endif
+
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
/* getting unicode on key-up events gives XLookupNone status */
XIC xic = window->getX11_XIC();
@@ -1340,8 +1385,8 @@ GHOST_TSuccess
GHOST_SystemX11::
setCursorPosition(
GHOST_TInt32 x,
- GHOST_TInt32 y
- ) {
+ GHOST_TInt32 y)
+{
/* This is a brute force move in screen coordinates
* XWarpPointer does relative moves so first determine the