Linux: Fix release event for the final key in a compose sequence not being reported. Fixes #4285

This commit is contained in:
Kovid Goyal
2021-11-29 19:26:16 +05:30
parent cdb1138465
commit bd288bd18f
6 changed files with 38 additions and 25 deletions

40
glfw/input.c vendored
View File

@@ -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;
}