Skip to content

glfwSetKeyCallback() : inconsistent behavior on non QWERTY keyboard layouts #20334

@SuperUserNameMan

Description

@SuperUserNameMan

This is going to be complicated to explain, so please, be patient with me :

My keyboard is AZERTY layout.

My A key is located at the same location than the Q key of a QWERTY keyboard.
At the hardware level, they share the same scancode, because : same location = same scancode.

Using keyboard scancodes is helpful when you make a video-game that maps "WASD" keys to directions, because the location of these "WASD" keys are always the same whatever is the layout of the user's keyboard. The game can work out of the box without remapping the keyboard.

Here is the issue :

When I use GLFW in C, the callback passed to glfwSetKeyCallback() will receive correct scancodes.
When I use GLFW in Emscripten, the callback passed to glfwSetKeyCallback() will receive INCORRECT scancodes.

This is because library_glfw.js makes use of the outdated KeyboardEvent.keyCode instead of KeyboardEvent.code.

.keyCode is not an hardware scancode, and it breaks compatibility and consistency between GLFW in C and Emscripten.

onKeydown: (event) => {
GLFW.onKeyChanged(event.keyCode, 1); // GLFW_PRESS or GLFW_REPEAT
// This logic comes directly from the sdl implementation. We cannot
// call preventDefault on all keydown events otherwise onKeyPress will
// not get called
if (event.keyCode === 8 /* backspace */ || event.keyCode === 9 /* tab */) {
event.preventDefault();
}
},
onKeyup: (event) => {
GLFW.onKeyChanged(event.keyCode, 0); // GLFW_RELEASE
},
onBlur: (event) => {
if (!GLFW.active) return;
for (var i = 0; i < GLFW.active.domKeys.length; ++i) {
if (GLFW.active.domKeys[i]) {
GLFW.onKeyChanged(i, 0); // GLFW_RELEASE
}
}
},

onKeyChanged: (keyCode, status) => {
if (!GLFW.active) return;
var key = GLFW.DOMToGLFWKeyCode(keyCode);

DOMToGLFWKeyCode: (keycode) => {
switch (keycode) {
// these keycodes are only defined for GLFW3, assume they are the same for GLFW2
case 0x20:return 32; // DOM_VK_SPACE -> GLFW_KEY_SPACE
case 0xDE:return 39; // DOM_VK_QUOTE -> GLFW_KEY_APOSTROPHE
case 0xBC:return 44; // DOM_VK_COMMA -> GLFW_KEY_COMMA
case 0xAD:return 45; // DOM_VK_HYPHEN_MINUS -> GLFW_KEY_MINUS
case 0xBD:return 45; // DOM_VK_MINUS -> GLFW_KEY_MINUS
case 0xBE:return 46; // DOM_VK_PERIOD -> GLFW_KEY_PERIOD
case 0xBF:return 47; // DOM_VK_SLASH -> GLFW_KEY_SLASH
case 0x30:return 48; // DOM_VK_0 -> GLFW_KEY_0
case 0x31:return 49; // DOM_VK_1 -> GLFW_KEY_1
case 0x32:return 50; // DOM_VK_2 -> GLFW_KEY_2

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions