# Key callback sometimes reports key == -1 for all function keys

**URL:** <https://discourse.glfw.org/t/key-callback-sometimes-reports-key-1-for-all-function-keys/1513>\
**Category:** support\
**Created:** [March 22, 2020, 6:46pm UTC](https://discourse.glfw.org/t/key-callback-sometimes-reports-key-1-for-all-function-keys/1513 "2020-03-22T18:46:52Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![amosnier](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/amosnier/32/318_2.png) [@amosnier](https://discourse.glfw.org/u/amosnier)\
**Post date:** [March 22, 2020, 6:46pm UTC](https://discourse.glfw.org/t/key-callback-sometimes-reports-key-1-for-all-function-keys/1513/1 "2020-03-22T18:46:52Z")

</div>

I have built GLFW from source on Linux, commit 6aca3e99 (master~4 at the time of writing).

It mostly works as intended, but I can consistently reproduce one issue if I start my application after changing the keyboard layout via XFCE’s keyboard shortcut. If I do that, pressing any function key will deliver a key value of minus one in the key callback.

More precisely, my standard configuration has a two keyboard layouts: SE (default) and US. If I stay in the default layout, no problem (pressing escape will deliver key==256 for instance). But if I toggle the keyboard layout to US via the configurable XFCE keyboard shortcut or by pressing the xfce4-xkb-plugin button, and then start my application, I systematically get the problem: the key callback delivers key==-1 for all function keys. Non-function keys still seem to work fine. When in that state, switching back to SE layout does not come around the issue. Please note that what I am using here is as far as I know the standard way to toggle the keyboard layout in XFCE.

However, the US layout is not a problem in itself. If, instead of using the XFCE utilities, I change the keyboard layout by typing `setxkbmap us` in a terminal and start my application after that, everything works fine.

I have therefore tried to understand the difference in state between these two procedures, and I have found one: when I use `setxkbmap us` (or `setxkbmap se` for that matter), my double-layout is disabled, which it is not when I use XFCE utilities: `setxkbmap -query` shows `layout: se,us` after XFCE layout switch, but shows `layout: us` or `layout: se` after the keyboard switch.

So it seems to be the combination multiple keyboard layouts + non default layout selected, that triggers the issue.

At last, it could be worth mentioning that the `scancode` always seems to be correct (the problem is only with the `key` value).

Since GLFW seems like a very good cross-platform library, I hope there exists a solution for this problem.

Thanks in advance for any help.

---

<div class="post-metadata">

**Author:** ![dougbinks](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/dougbinks/32/39_2.png) [@dougbinks](https://discourse.glfw.org/u/dougbinks)\
**Post date:** [March 23, 2020, 2:39pm UTC](https://discourse.glfw.org/t/key-callback-sometimes-reports-key-1-for-all-function-keys/1513/2 "2020-03-23T14:39:13Z")

</div>

This sounds like a bug worth posting in [the GLFW issues](https://github.com/glfw/glfw/issues).

If you’re able to debug a bit further this could help a lot. The key table is initialized in [x11\_init.c createKeyTables](https://github.com/glfw/glfw/blob/44b5d06583cd21ac237eb8f6263db03faf1726c2/src/x11_init.c#L232-L327), with the table defaulted to -1 at the start. By debugging it you might find out what’s causing this issue on your system and that would help speed up any fix.

---

<div class="post-metadata">

**Author:** ![amosnier](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/amosnier/32/318_2.png) [@amosnier](https://discourse.glfw.org/u/amosnier)\
**Post date:** [March 24, 2020, 6:56pm UTC](https://discourse.glfw.org/t/key-callback-sometimes-reports-key-1-for-all-function-keys/1513/3 "2020-03-24T18:56:06Z")

</div>

@dougbinks, I’m happy to debug more. I’m just wondering what procedure you would recommend.

My current project does not have the GLFW source files as a dependency. After building GLFW, I have “make installed” it, and I’m just relying on CMake to find the headers and link GLFW with my application.

To debug GLFW, I guess I should start from one of the examples in the GLFW source tree? Then I guess the GLFW source files would be an explicit dependency? Also, are there any particular build flags I should use to debug GLFW?

Any advice is appreciated.

---

<div class="post-metadata">

**Author:** ![amosnier](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/amosnier/32/318_2.png) [@amosnier](https://discourse.glfw.org/u/amosnier)\
**Post date:** [March 24, 2020, 7:13pm UTC](https://discourse.glfw.org/t/key-callback-sometimes-reports-key-1-for-all-function-keys/1513/4 "2020-03-24T19:13:22Z")

</div>

Actually, some good news, I guess, I can reproduce the issue with the triangle-opengl as is. Also, I am using CLion and if I open the top directory of a new clone of GLFW, it just builds everything out-of-the-box. I will now try to break in the GLFW code.

---

<div class="post-metadata">

**Author:** ![dougbinks](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/dougbinks/32/39_2.png) [@dougbinks](https://discourse.glfw.org/u/dougbinks)\
**Post date:** [March 24, 2020, 8:07pm UTC](https://discourse.glfw.org/t/key-callback-sometimes-reports-key-1-for-all-function-keys/1513/5 "2020-03-24T20:07:33Z")

</div>

Excellent - thank you for this.

Adding printf’s to x11\_init.c to see what the `name` variable is might help if all else fails.

---

<div class="post-metadata">

**Author:** ![amosnier](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/amosnier/32/318_2.png) [@amosnier](https://discourse.glfw.org/u/amosnier)\
**Post date:** [March 24, 2020, 10:07pm UTC](https://discourse.glfw.org/t/key-callback-sometimes-reports-key-1-for-all-function-keys/1513/6 "2020-03-24T22:07:39Z")

</div>

Tricky.

As far as I can see, `_glfw.x11.xkb.group` is zero when I use `se` (default). Then `XkbKeycodeToKeysym(_glfw.x11.display, scancode, _glfw.x11.xkb.group, 0)` returns the correct value (`0xff1b` for `scancode` 9).

But when I switch to `us` before starting the application, `_glfw.x11.xkb.group` is one, which looks logical, but then `XkbKeycodeToKeysym(_glfw.x11.display, scancode, _glfw.x11.xkb.group, 0)` returns zero (bad).

Note that the level parameter (the last one of XkbKeycodeToKeysym()) makes no difference. The function is invoked twice in `translateKeyCode()` with level 1 and 0 and the return value is the same in both cases.

I don’t really know why the incorrect value is returned when `group` is one. Any idea?

I have also just tried to change the `group` value to zero with the debugger before the second XkbKeycodeToKeysym() invokation, in the `us` case, but it makes no difference.

---

<div class="post-metadata">

**Author:** ![amosnier](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/amosnier/32/318_2.png) [@amosnier](https://discourse.glfw.org/u/amosnier)\
**Post date:** [March 24, 2020, 10:38pm UTC](https://discourse.glfw.org/t/key-callback-sometimes-reports-key-1-for-all-function-keys/1513/7 "2020-03-24T22:38:40Z")

</div>

I’m quite a beginner at that kind of stuff, but this [stackoverflow answer](https://stackoverflow.com/a/50539803/3246135) seems to suggest that xcb should cover all keyboard needs, without ever needing to use XKB. I have felt like learning xcb a few times. Maybe now is the occasion…

---

<div class="post-metadata">

**Author:** ![elmindreda](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/elmindreda/32/26_2.png) [@elmindreda](https://discourse.glfw.org/u/elmindreda)\
**Post date:** [March 24, 2020, 11:31pm UTC](https://discourse.glfw.org/t/key-callback-sometimes-reports-key-1-for-all-function-keys/1513/8 "2020-03-24T23:31:27Z")

</div>

Thank you for reporting this! It is indeed a bug in GLFW, with a PR in the process of being merged.

> <https://github.com/glfw/glfw/pull/1598>
>
> XkbKeycodeToKeysym in function translateKeyCode in x11\_init.c is returning keySy…m value of -1 when called with the key's scancode. This causes all function and numpad keys to be mapped to GLFW\_KEY\_UNKNOWN.
> 
> Printable keys register correctly because they are mapped explicitly, so I mapped the other keys like that too. There is no reason to use translateKeyCode now.

The PR works but is specific to the evdev keycode set so I’m expanding it right now. If you’re on a modern Linux system it will likely work for you without modification but it won’t yet on servers like Cygwin/X or on some non-PC hardware.

> [@amosnier](#):
>
> I don’t really know why the incorrect value is returned when `group` is one. Any idea?

The function keys likely only have a single group. The existing code in GLFW incorrectly assumes that every key has the same number of groups but in XKB this can vary per key. You can see the XKB version your setup with `xkbcomp -o myfilename.txt $DISPLAY`.

GLFW needs to use XKB to be able to map `GLFW_KEY_*` constants to physical keys, as key symbols vary between layouts. The core protocol only provides undifferentiated keycodes.

---

<div class="post-metadata">

**Author:** ![amosnier](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/amosnier/32/318_2.png) [@amosnier](https://discourse.glfw.org/u/amosnier)\
**Post date:** [March 25, 2020, 7:00pm UTC](https://discourse.glfw.org/t/key-callback-sometimes-reports-key-1-for-all-function-keys/1513/9 "2020-03-25T19:00:02Z")

</div>

@elmindreda, great that this is a known issue that already has a solution. It’s not like I can’t come around it, so it’s perfectly OK for me to wait for the merge. It was interesting to read that @ZenulAbidin basically was in the same situation as I was, and had pretty much drawn the same conclusion, although he obviously went much further than me, since he implemented a solution.

A few thoughts:

- I do not really understand why setting `_glfw.x11.xkb.group` to zero in the debugger did not solve the issue when I tested that yesterday, but I assume your coming fix will work for me anyway.
- I am a little confused by the GLFW release scheme. I see a mention of “milestone 3.3.3” in the pull request, but the main GLFW site seems to indicate that the next release will be 3.4 (oh maybe I get it: there are several milestones on the way to a release, right?). In any case, my current working procedure is to just pull latest master, build it myself, and install it. I supposed there is nothing wrong with that procedure?
- I’d be happy to somehow be notified when the fix is merged. What’s the best way to achieve that?

If you want me to test something, I’d be happy to do that. In that case, please tell me exactly what commit you want me to test.

Thanks a lot for your amazing work.

I guess I won’t learn xcb this time either…

---

<div class="post-metadata">

**Author:** ![ZenulAbidin](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/zenulabidin/32/294_2.png) [@ZenulAbidin](https://discourse.glfw.org/u/ZenulAbidin)\
**Post date:** [March 30, 2020, 7:49pm UTC](https://discourse.glfw.org/t/key-callback-sometimes-reports-key-1-for-all-function-keys/1513/10 "2020-03-30T19:49:35Z")

</div>

Sorry for the late response, I wasn’t following discourse lately. So let me clarify some of the issues and quirks I experienced when debugging this issue.

3.3.3 is the next bugfix release. It doesn’t have new features, those will be delayed until 3.4. Originally my PR was to be merged in 3.3.2 but for some reason it was delayed to 3.3.3.

In my case I had a primary, default arabic keyboard layout (it’s group 0 for me) and an auxiliary, secondary en\_US layout (group 1 for me). I only experienced this problem if I start a GLFW program while using my secondary, which happened to be english, keyboard layout. It doesn’t happen if I start it while using my primary arabic layout for some reason.

The commit that introduced this bug was [https://github.com/glfw/glfw/commit/b3eb6dd38b5390f3d5a5bd00b66cec1bdb56e49d](https://github.com/glfw/glfw/commit/b3eb6dd38b5390f3d5a5bd00b66cec1bdb56e49d), ( `X11: Query and keep track of Xkb group index`). This commit solves a problem where only keyboard input from the primary keyboard layout is returned correctly. Before then, input while using secondary keyboard layouts would sometimes cause the wrong characters to be returned.

Maybe when a program opens an X11 connection the X11 display initializes it to use group 0, the first keyboard layout (the “group” in X terminology). So if that’s true then the side effect of that fix was that only keys on group 0, the primary character set, were recognized, and that explains why the problem goes away when I change keyboard layouts. Since function keys were not being recognized I suspect they were only on my secondary en\_US keyboard layout “group 1”.

So what I did in `x11_init.c` was dispense with the second keycode translation, which was done in `translateKeyCode()`, and instead took all the character names from the evdev keycode set and assigned them in the first keycode translation, the one that’s done in `createKeyTables`. My assumption for doing this was that I thought GLFW doesn’t run on very old Linux systems, which I might be wrong about that, and reasoned that since most Linux kernels in circulation use only evdev, that I just make a fix specific to evdev.

I also didn’t know that not all Unix systems were using evdev, Cygwin in particular. In fact, I only just realized that GLFW can be used with package managers like Cygwin and MinGW, as I didn’t have those at hand to test against when I made this PR. But I’m still wondering what non-PC hardware can run GLFW, are they perhaps mobile operating systems?

This particular pull request also taught me a hard lesson not to merge PRs using your master branch on github, or you won’t be able to pull new changes to your fork until the PR is merged or closed. But I can live with that.

---

<div class="post-metadata">

**Author:** ![elmindreda](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/elmindreda/32/26_2.png) [@elmindreda](https://discourse.glfw.org/u/elmindreda)\
**Post date:** [April 1, 2020, 11:15pm UTC](https://discourse.glfw.org/t/key-callback-sometimes-reports-key-1-for-all-function-keys/1513/11 "2020-04-01T23:15:47Z")

</div>

Thank you for the great explanation!

> [@ZenulAbidin](#):
>
> Originally my PR was to be merged in 3.3.2 but for some reason it was delayed to 3.3.3.

I just had to learn more about XKB to be of help with this PR and 3.3.2 needed to go out quickly because of another already fixed issue.

> [@ZenulAbidin](#):
>
> But I’m still wondering what non-PC hardware can run GLFW, are they perhaps mobile operating systems?

Mostly I’m worried about the BSDs. They have GLFW packages, run on many non-PC platforms and do not use evdev. That’s a small demographic but I’d like not to break things for it if possible.

---

<div class="post-metadata">

**Author:** ![elmindreda](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/elmindreda/32/26_2.png) [@elmindreda](https://discourse.glfw.org/u/elmindreda)\
**Post date:** [April 1, 2020, 11:33pm UTC](https://discourse.glfw.org/t/key-callback-sometimes-reports-key-1-for-all-function-keys/1513/12 "2020-04-01T23:33:22Z")

</div>

> [@amosnier](#):
>
> I’d be happy to somehow be notified when the fix is merged. What’s the best way to achieve that?

You can subscribe to the GitHub issue for notifications. I’ll also post in this thread once the issue is resolved.

> [@amosnier](#):
>
> If you want me to test something, I’d be happy to do that. In that case, please tell me exactly what commit you want me to test.

Thank you!

---

<div class="post-metadata">

**Author:** ![elmindreda](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/elmindreda/32/26_2.png) [@elmindreda](https://discourse.glfw.org/u/elmindreda)\
**Post date:** [April 28, 2020, 7:41pm UTC](https://discourse.glfw.org/t/key-callback-sometimes-reports-key-1-for-all-function-keys/1513/13 "2020-04-28T19:41:23Z")

</div>

The proposed changes are now in the [x11-xkb-key-names-r2](https://github.com/glfw/glfw/tree/x11-xkb-key-names-r2) branch.
