hajimehoshi / ebiten

Ebitengine - A dead simple 2D game engine for Go
https://ebitengine.org
Apache License 2.0
10.38k stars 633 forks source link

input: handle remapped keys on x11 #2974

Open kazzmir opened 2 months ago

kazzmir commented 2 months ago

Ebitengine Version

2.7.2

Operating System

Go Version (go version)

go version go1.22.2 linux/amd64

What steps will reproduce the problem?

Swap escape and capslock with this command

/usr/bin/setxkbmap -option "caps:swapescape"

press the capslock key in the game, and then invoke inpututil.AppendPressedKeys(keys).

What is the expected result?

The keys array should contain ebiten.KeyEscape, but instead it contains ebiten.KeyCapsLock

What happens instead?

Keys array contains ebiten.KeyCapsLock

Anything else you feel useful to add?

This situation works in SDL2, when I press the capslock key the key event correctly has event.key.keysym.sym == SDLK_ESCAPE.

Maybe the issue is in how the glfx.x11.keycodes array is set up, although the code looks plausible in that it queries xkb. https://github.com/hajimehoshi/ebiten/blob/13d15b0ed9a2b7d4a4821c02171e4269143aabec/internal/glfw/x11_init_linbsd.c#L197

FWIW this is what xev -event keyboard shows for me (after having swapped escape and capslock with the command above)

Press capslock:

KeyPress event, serial 28, synthetic NO, window 0x8e00001,
    root 0x29d, subw 0x0, time 1205629860, (65,113), root:(3652,550),
    state 0x10, keycode 66 (keysym 0xff1b, Escape), same_screen YES,
    XLookupString gives 1 bytes: (1b) "
mbLookupString gives 1 bytes: (1b) "
FilterEvent returns: False

Press escape:

KeyPress event, serial 28, synthetic NO, window 0x8e00001,
    root 0x29d, subw 0x0, time 1205638081, (65,113), root:(3652,550),
    state 0x12, keycode 9 (keysym 0xffe5, Caps_Lock), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False
hajimehoshi commented 2 months ago

Does this work with GLFW?

hajimehoshi commented 2 months ago

https://github.com/glfw/glfw/issues/2011

kazzmir commented 2 months ago

Yes I replicated the same issue in GLFW, if I run the gears example then when I press the capslock key nothing happens, but when I press the physical escape key then the gears program will quit. The gears code has

  case GLFW_KEY_ESCAPE:
    glfwSetWindowShouldClose(window, GLFW_TRUE);

But I also have the same issue when I run my game in a web browser via wasm. I would have thought that the browser would handle key remappings correctly. I guess there is little that ebiten can do about the situation with the browser.