Skip to content

Commit

Permalink
X11: Query and keep track of Xkb group index
Browse files Browse the repository at this point in the history
For users with multiple keyboard layouts configured, glfwGetKeyName
works fine only with the primary layout.  Switching layouts results in
changing the group index.  This commit querries the current group index
when initializing keyboard input and keeps track of any change to it.

As a result the scancode -> keyname mapping may change while the program
is running (needs to be documented).

Fixes #1462.
Closes #1528.

(cherry picked from commit 36f9080)
  • Loading branch information
db47h authored and elmindreda committed Jul 16, 2019
1 parent 84fa724 commit b3eb6dd
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 10 deletions.
12 changes: 10 additions & 2 deletions src/x11_init.c
Expand Up @@ -54,7 +54,7 @@ static int translateKeyCode(int scancode)
// Note: This way we always force "NumLock = ON", which is intentional
// since the returned key code should correspond to a physical
// location.
keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 1);
keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, _glfw.x11.xkb.group, 1);
switch (keySym)
{
case XK_KP_0: return GLFW_KEY_KP_0;
Expand All @@ -76,7 +76,7 @@ static int translateKeyCode(int scancode)

// Now try primary keysym for function keys (non-printable keys)
// These should not depend on the current keyboard layout
keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 0);
keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, _glfw.x11.xkb.group, 0);
}
else
{
Expand Down Expand Up @@ -659,6 +659,14 @@ static GLFWbool initExtensions(void)
if (supported)
_glfw.x11.xkb.detectable = GLFW_TRUE;
}

_glfw.x11.xkb.group = 0;
XkbStateRec state;
if (XkbGetState(_glfw.x11.display, XkbUseCoreKbd, &state) == Success)
{
XkbSelectEventDetails(_glfw.x11.display, XkbUseCoreKbd, XkbStateNotify, XkbAllStateComponentsMask, XkbGroupStateMask);
_glfw.x11.xkb.group = (unsigned int)state.group;
}
}

#if defined(__CYGWIN__)
Expand Down
15 changes: 8 additions & 7 deletions src/x11_platform.h
Expand Up @@ -323,13 +323,14 @@ typedef struct _GLFWlibraryX11
} randr;

struct {
GLFWbool available;
GLFWbool detectable;
int majorOpcode;
int eventBase;
int errorBase;
int major;
int minor;
GLFWbool available;
GLFWbool detectable;
int majorOpcode;
int eventBase;
int errorBase;
int major;
int minor;
unsigned int group;
} xkb;

struct {
Expand Down
11 changes: 10 additions & 1 deletion src/x11_window.c
Expand Up @@ -1180,6 +1180,15 @@ static void processEvent(XEvent *event)
}
}

if (_glfw.x11.xkb.available && event->type == _glfw.x11.xkb.eventBase)
{
if (((XkbEvent *)event)->any.xkb_type == XkbStateNotify &&
((XkbEvent *)event)->state.changed & XkbGroupStateMask)
{
_glfw.x11.xkb.group = ((XkbEvent *)event)->state.group;
}
}

if (event->type == GenericEvent)
{
if (_glfw.x11.xi.available)
Expand Down Expand Up @@ -2780,7 +2789,7 @@ const char* _glfwPlatformGetScancodeName(int scancode)
if (!_glfw.x11.xkb.available)
return NULL;

const KeySym keysym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 0);
const KeySym keysym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, _glfw.x11.xkb.group, 0);
if (keysym == NoSymbol)
return NULL;

Expand Down

0 comments on commit b3eb6dd

Please sign in to comment.