Skip to content

Commit 9a3664b

Browse files
committed
X11: Fix detection of key events duplicated by XIM
Background: The IM will filter out key events, instead sending exact duplicate events that are not filtered. It does not send these for every event, however, so the duplicate events cannot be relied on for key input. Instead we need to identify and discard them. Since they are identical, they have the same timestamp as the originals. The previous duplicate event detection would consume unrelated key events if the keys were pressed simultaneously, as it only tracked a single timestamp. This fixes that issue for any combination of keys, at the expense of a 1 KB array per GLFW window. This fix is a stopgap until explicit IME support is done. Based on #1472 by @LucaRood. Fixes #1112. Fixes #1415. Fixes #1616. Fixes #1663. Closes #1472.
1 parent 6ce2070 commit 9a3664b

File tree

3 files changed

+17
-8
lines changed

3 files changed

+17
-8
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ information on what to include when reporting a bug.
190190
non-printable keys (#1598)
191191
- [X11] Bugfix: Function keys were mapped to `GLFW_KEY_UNKNOWN` for some layout
192192
combinaitons (#1598)
193+
- [X11] Bugfix: Keys pressed simultaneously with others were not always
194+
reported (#1112,#1415,#1472,#1616)
193195
- [Wayland] Removed support for `wl_shell` (#1443)
194196
- [Wayland] Bugfix: The `GLFW_HAND_CURSOR` shape used the wrong image (#1432)
195197
- [Wayland] Bugfix: `CLOCK_MONOTONIC` was not correctly enabled
@@ -364,8 +366,10 @@ skills.
364366
- Eddie Ringle
365367
- Max Risuhin
366368
- Jorge Rodriguez
369+
- Luca Rood
367370
- Ed Ropple
368371
- Aleksey Rybalkin
372+
- Mikko Rytkönen
369373
- Riku Salminen
370374
- Brandon Schaefer
371375
- Sebastian Schuberth

src/x11_platform.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,8 +402,9 @@ typedef struct _GLFWwindowX11
402402
// The last position the cursor was warped to by GLFW
403403
int warpCursorPosX, warpCursorPosY;
404404

405-
// The time of the last KeyPress event
406-
Time lastKeyTime;
405+
// The time of the last KeyPress event per keycode, for discarding
406+
// duplicate key events generated for some keys by ibus
407+
Time keyPressTimes[256];
407408

408409
} _GLFWwindowX11;
409410

src/x11_window.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,16 +1265,20 @@ static void processEvent(XEvent *event)
12651265

12661266
if (window->x11.ic)
12671267
{
1268-
// HACK: Ignore duplicate key press events generated by ibus
1269-
// These have the same timestamp as the original event
1270-
// Corresponding release events are filtered out
1271-
// implicitly by the GLFW key repeat logic
1272-
if (window->x11.lastKeyTime < event->xkey.time)
1268+
// HACK: Do not report the key press events duplicated by XIM
1269+
// Duplicate key releases are filtered out implicitly by
1270+
// the GLFW key repeat logic in _glfwInputKey
1271+
// A timestamp per key is used to handle simultaneous keys
1272+
// NOTE: Always allow the first event for each key through
1273+
// (the server never sends a timestamp of zero)
1274+
// NOTE: Timestamp difference is compared to handle wrap-around
1275+
Time diff = event->xkey.time - window->x11.keyPressTimes[keycode];
1276+
if (diff == event->xkey.time || (diff > 0 && diff < (1 << 31)))
12731277
{
12741278
if (keycode)
12751279
_glfwInputKey(window, key, keycode, GLFW_PRESS, mods);
12761280

1277-
window->x11.lastKeyTime = event->xkey.time;
1281+
window->x11.keyPressTimes[keycode] = event->xkey.time;
12781282
}
12791283

12801284
if (!filtered)

0 commit comments

Comments
 (0)