diff --git a/glfw/glfw3.h b/glfw/glfw3.h index c29f4e1ef..be509da1d 100644 --- a/glfw/glfw3.h +++ b/glfw/glfw3.h @@ -1211,8 +1211,8 @@ typedef struct GLFWkeyevent // The [keyboard key](@ref keys) that was pressed or released. int key; - // The system-specific scancode of the key. - int scancode; + // The native key identifier of the key. + int native_key; // The event action. Either `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`. int action; diff --git a/glfw/input.c b/glfw/input.c index 87820b57a..0a4e07cc2 100644 --- a/glfw/input.c +++ b/glfw/input.c @@ -257,10 +257,10 @@ static bool parseMapping(_GLFWmapping* mapping, const char* string) ////// GLFW event API ////// ////////////////////////////////////////////////////////////////////////// -void _glfwInitializeKeyEvent(GLFWkeyevent *ev, int key, int scancode, int action, int mods) +void _glfwInitializeKeyEvent(GLFWkeyevent *ev, int key, int native_key, int action, int mods) { ev->key = key; - ev->scancode = scancode; + ev->native_key = native_key; ev->action = action; ev->mods = mods; ev->text = NULL; diff --git a/glfw/internal.h b/glfw/internal.h index bb54b151c..c64a923cb 100644 --- a/glfw/internal.h +++ b/glfw/internal.h @@ -758,7 +758,7 @@ void _glfwInputWindowDamage(_GLFWwindow* window); void _glfwInputWindowCloseRequest(_GLFWwindow* window); void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor); -void _glfwInitializeKeyEvent(GLFWkeyevent *ev, int key, int scancode, int action, int mods); +void _glfwInitializeKeyEvent(GLFWkeyevent *ev, int key, int native_key, int action, int mods); void _glfwInputKeyboard(_GLFWwindow *window, GLFWkeyevent *ev); void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset, int flags); void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods); diff --git a/glfw/xkb_glfw.c b/glfw/xkb_glfw.c index a1981810d..854131e3e 100644 --- a/glfw/xkb_glfw.c +++ b/glfw/xkb_glfw.c @@ -549,10 +549,10 @@ glfw_xkb_key_from_ime(_GLFWIBUSKeyEvent *ev, bool handled_by_ime, bool failed) { xkb_keycode_t prev_handled_press = last_handled_press_keycode; last_handled_press_keycode = 0; bool is_release = ev->glfw_ev.action == GLFW_RELEASE; - debug("From IBUS: scancode: 0x%x name: %s is_release: %d\n", ev->glfw_ev.scancode, glfw_xkb_keysym_name(ev->glfw_ev.key), is_release); - if (window && !handled_by_ime && !(is_release && ev->glfw_ev.scancode == (int) prev_handled_press)) { + debug("From IBUS: native_key: 0x%x name: %s is_release: %d\n", ev->glfw_ev.native_key, glfw_xkb_keysym_name(ev->glfw_ev.key), is_release); + if (window && !handled_by_ime && !(is_release && ev->glfw_ev.native_key == (int) prev_handled_press)) { debug("↳ to application: glfw_keycode: 0x%x (%s) keysym: 0x%x (%s) action: %s %s text: %s\n", - ev->glfw_ev.scancode, _glfwGetKeyName(ev->glfw_ev.scancode), ev->glfw_ev.key, glfw_xkb_keysym_name(ev->glfw_ev.key), + ev->glfw_ev.native_key, _glfwGetKeyName(ev->glfw_ev.native_key), ev->glfw_ev.key, glfw_xkb_keysym_name(ev->glfw_ev.key), (ev->glfw_ev.action == GLFW_RELEASE ? "RELEASE" : (ev->glfw_ev.action == GLFW_PRESS ? "PRESS" : "REPEAT")), format_mods(ev->glfw_ev.mods), ev->glfw_ev.text ); @@ -560,7 +560,8 @@ glfw_xkb_key_from_ime(_GLFWIBUSKeyEvent *ev, bool handled_by_ime, bool failed) { ev->glfw_ev.ime_state = 0; _glfwInputKeyboard(window, &ev->glfw_ev); } else debug("↳ discarded\n"); - if (!is_release && handled_by_ime) last_handled_press_keycode = ev->glfw_ev.scancode; + if (!is_release && handled_by_ime) + last_handled_press_keycode = ev->glfw_ev.native_key; } void @@ -635,8 +636,17 @@ glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t xkb_sym, glfw_xkb_keysym_name(xkb_sym) ); + // NOTE: On linux, the reported native key identifier is the XKB keysym value. + // Do not confuse `native_key` with `xkb_keycode` (the native keycode reported for the + // glfw event VS the X internal code for a key). + // + // We use the XKB keysym instead of the X keycode to be able to go back-and-forth between + // the GLFW keysym and the XKB keysym when needed, which is not possible using the X keycode, + // because of the lost information when resolving the keycode to the keysym, like consumed + // mods. + glfw_ev.native_key = xkb_sym; + glfw_ev.action = action; - glfw_ev.scancode = xkb_sym; glfw_ev.key = glfw_sym; glfw_ev.mods = sg->modifiers; glfw_ev.text = key_text;