Linux: Fix release event for the final key in a compose sequence not being reported. Fixes #4285
This commit is contained in:
parent
cdb1138465
commit
bd288bd18f
@ -1250,7 +1250,7 @@ is_ascii_control_char(char x) {
|
||||
const bool process_text = !window->ns.textInputFilterCallback || window->ns.textInputFilterCallback(key, mods, keycode, flags) != 1;
|
||||
_glfw.ns.text[0] = 0;
|
||||
if (keycode == 0x33 /* backspace */ || keycode == 0x35 /* escape */) [self unmarkText];
|
||||
GLFWkeyevent glfw_keyevent = {.key = key, .native_key = keycode, .action = GLFW_PRESS, .mods = mods};
|
||||
GLFWkeyevent glfw_keyevent = {.key = key, .native_key = keycode, .native_key_id = keycode, .action = GLFW_PRESS, .mods = mods};
|
||||
if (!_glfw.ns.unicodeData) {
|
||||
// Using the cocoa API for key handling is disabled, as there is no
|
||||
// reliable way to handle dead keys using it. Only use it if the
|
||||
@ -1357,7 +1357,7 @@ is_ascii_control_char(char x) {
|
||||
action = GLFW_PRESS;
|
||||
}
|
||||
|
||||
GLFWkeyevent glfw_keyevent = {.key = key, .native_key = [event keyCode], .action = action, .mods = mods};
|
||||
GLFWkeyevent glfw_keyevent = {.key = key, .native_key = [event keyCode], .native_key_id = [event keyCode], .action = action, .mods = mods};
|
||||
_glfwInputKeyboard(window, &glfw_keyevent);
|
||||
}
|
||||
|
||||
@ -1367,7 +1367,7 @@ is_ascii_control_char(char x) {
|
||||
const uint32_t key = translateKey(keycode, true);
|
||||
const int mods = translateFlags([event modifierFlags]);
|
||||
|
||||
GLFWkeyevent glfw_keyevent = {.key = key, .native_key = keycode, .action = GLFW_RELEASE, .mods = mods};
|
||||
GLFWkeyevent glfw_keyevent = {.key = key, .native_key = keycode, .native_key_id = keycode, .action = GLFW_RELEASE, .mods = mods};
|
||||
add_alternate_keys(&glfw_keyevent, event);
|
||||
debug_key("\x1b[32mRelease:\x1b[m native_key: 0x%x (%s) glfw_key: 0x%x %s\n",
|
||||
keycode, safe_name_for_keycode(keycode), key, format_mods(mods));
|
||||
|
||||
4
glfw/glfw3.h
vendored
4
glfw/glfw3.h
vendored
@ -1245,6 +1245,10 @@ typedef struct GLFWkeyevent
|
||||
// A value of GLFW_IME_PREEDIT_CHANGED means the pre-edit text for the input event has been changed.
|
||||
// A value of GLFW_IME_COMMIT_TEXT means the text should be committed.
|
||||
GLFWIMEState ime_state;
|
||||
|
||||
// For internal use only. On Linux it is the actual keycode reported by the windowing system, in contrast
|
||||
// to native_key which can be the result of a compose operation. On macOS it is the same as native_key.
|
||||
uint32_t native_key_id;
|
||||
} GLFWkeyevent;
|
||||
|
||||
/*! @brief The function pointer type for error callbacks.
|
||||
|
||||
40
glfw/input.c
vendored
40
glfw/input.c
vendored
@ -274,11 +274,11 @@ static bool parseMapping(_GLFWmapping* mapping, const char* string)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void
|
||||
set_key_action(_GLFWwindow *window, uint32_t key, int val, int idx) {
|
||||
set_key_action(_GLFWwindow *window, const GLFWkeyevent *ev, int action, int idx) {
|
||||
const unsigned sz = arraysz(window->activated_keys);
|
||||
if (idx < 0) {
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
if (window->activated_keys[i].key == 0) {
|
||||
if (window->activated_keys[i].native_key_id == 0) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
@ -286,18 +286,18 @@ set_key_action(_GLFWwindow *window, uint32_t key, int val, int idx) {
|
||||
if (idx < 0) {
|
||||
idx = sz - 1;
|
||||
memmove(window->activated_keys, window->activated_keys + 1, sizeof(window->activated_keys[0]) * (sz - 1));
|
||||
window->activated_keys[sz - 1].key = key;
|
||||
window->activated_keys[sz - 1].native_key_id = 0;
|
||||
}
|
||||
}
|
||||
if (val == GLFW_RELEASE) {
|
||||
if (action == GLFW_RELEASE) {
|
||||
memset(window->activated_keys + idx, 0, sizeof(window->activated_keys[0]));
|
||||
if (idx < (int)sz - 1) {
|
||||
memmove(window->activated_keys + idx, window->activated_keys + idx + 1, sizeof(window->activated_keys[0]) * (sz - 1 - idx));
|
||||
memset(window->activated_keys + sz - 1, 0, sizeof(window->activated_keys[0]));
|
||||
}
|
||||
} else {
|
||||
window->activated_keys[idx].key = key;
|
||||
window->activated_keys[idx].action = val;
|
||||
window->activated_keys[idx] = *ev;
|
||||
window->activated_keys[idx].text = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -305,30 +305,39 @@ set_key_action(_GLFWwindow *window, uint32_t key, int val, int idx) {
|
||||
//
|
||||
void _glfwInputKeyboard(_GLFWwindow* window, GLFWkeyevent* ev)
|
||||
{
|
||||
if (ev->key > 0)
|
||||
if (ev->native_key_id > 0)
|
||||
{
|
||||
bool repeated = false;
|
||||
int idx = -1;
|
||||
int current_action = GLFW_RELEASE;
|
||||
const unsigned sz = arraysz(window->activated_keys);
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
if (window->activated_keys[i].key == ev->key) {
|
||||
if (window->activated_keys[i].native_key_id == ev->native_key_id) {
|
||||
idx = i;
|
||||
current_action = window->activated_keys[i].action;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ev->action == GLFW_RELEASE && current_action == GLFW_RELEASE)
|
||||
return;
|
||||
if (ev->action == GLFW_RELEASE) {
|
||||
if (current_action == GLFW_RELEASE) return;
|
||||
if (idx > -1) {
|
||||
const GLFWkeyevent *press_event = window->activated_keys + idx;
|
||||
if (press_event->action == GLFW_PRESS || press_event->action == GLFW_REPEAT) {
|
||||
// Compose sequences under X11 give a different key value for press and release events
|
||||
// but we want the same key value so override it.
|
||||
ev->native_key = press_event->native_key;
|
||||
ev->key = press_event->key;
|
||||
ev->shifted_key = press_event->shifted_key;
|
||||
ev->alternate_key = press_event->alternate_key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ev->action == GLFW_PRESS && current_action == GLFW_PRESS)
|
||||
repeated = true;
|
||||
|
||||
if (ev->action == GLFW_RELEASE && window->stickyKeys)
|
||||
set_key_action(window, ev->key, _GLFW_STICK, idx);
|
||||
else
|
||||
set_key_action(window, ev->key, ev->action, idx);
|
||||
set_key_action(window, ev, (ev->action == GLFW_RELEASE && window->stickyKeys) ? _GLFW_STICK : ev->action, idx);
|
||||
|
||||
if (repeated)
|
||||
ev->action = GLFW_REPEAT;
|
||||
@ -823,7 +832,8 @@ GLFWAPI GLFWKeyAction glfwGetKey(GLFWwindow* handle, uint32_t key)
|
||||
if (current_action == _GLFW_STICK)
|
||||
{
|
||||
// Sticky mode: release key now
|
||||
set_key_action(window, key, GLFW_RELEASE, idx);
|
||||
GLFWkeyevent ev = {0};
|
||||
set_key_action(window, &ev, GLFW_RELEASE, idx);
|
||||
current_action = GLFW_PRESS;
|
||||
}
|
||||
|
||||
|
||||
7
glfw/internal.h
vendored
7
glfw/internal.h
vendored
@ -402,11 +402,6 @@ struct _GLFWcontext
|
||||
_GLFWcontextOSMesa osmesa;
|
||||
};
|
||||
|
||||
typedef struct GLFWKeyState {
|
||||
uint32_t key;
|
||||
char action;
|
||||
} GLFWKeyState;
|
||||
|
||||
// Window and context structure
|
||||
//
|
||||
struct _GLFWwindow
|
||||
@ -437,7 +432,7 @@ struct _GLFWwindow
|
||||
bool lockKeyMods;
|
||||
int cursorMode;
|
||||
char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1];
|
||||
GLFWKeyState activated_keys[16];
|
||||
GLFWkeyevent activated_keys[16];
|
||||
// Virtual cursor position when cursor is disabled
|
||||
double virtualCursorPosX, virtualCursorPosY;
|
||||
bool rawMouseMotion;
|
||||
|
||||
2
glfw/xkb_glfw.c
vendored
2
glfw/xkb_glfw.c
vendored
@ -866,7 +866,7 @@ glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t
|
||||
const xkb_keysym_t *syms, *clean_syms, *default_syms;
|
||||
xkb_keysym_t xkb_sym, shifted_xkb_sym = XKB_KEY_NoSymbol, alternate_xkb_sym = XKB_KEY_NoSymbol;
|
||||
xkb_keycode_t code_for_sym = xkb_keycode, ibus_keycode = xkb_keycode;
|
||||
GLFWkeyevent glfw_ev = {.action = GLFW_PRESS};
|
||||
GLFWkeyevent glfw_ev = {.action = GLFW_PRESS, .native_key_id = xkb_keycode};
|
||||
#ifdef _GLFW_WAYLAND
|
||||
code_for_sym += 8;
|
||||
#else
|
||||
|
||||
4
kitty/glfw-wrapper.h
generated
4
kitty/glfw-wrapper.h
generated
@ -983,6 +983,10 @@ typedef struct GLFWkeyevent
|
||||
// A value of GLFW_IME_PREEDIT_CHANGED means the pre-edit text for the input event has been changed.
|
||||
// A value of GLFW_IME_COMMIT_TEXT means the text should be committed.
|
||||
GLFWIMEState ime_state;
|
||||
|
||||
// For internal use only. On Linux it is the actual keycode reported by the windowing system, in contrast
|
||||
// to native_key which can be the result of a compose operation. On macOS it is the same as native_key.
|
||||
uint32_t native_key_id;
|
||||
} GLFWkeyevent;
|
||||
|
||||
/*! @brief The function pointer type for error callbacks.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user