From 606c0fc03e05d8260aceec188fb1d9074527de0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 30 Jun 2020 20:57:24 +0200 Subject: [PATCH 1/5] 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. (cherry picked from commit 9a3664b4a992a5a9b669179098542b0f882dece7) --- README.md | 4 ++++ src/x11_platform.h | 5 +++-- src/x11_window.c | 16 ++++++++++------ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 9f82fce2..3a269d40 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,8 @@ information on what to include when reporting a bug. non-printable keys (#1598) - [X11] Bugfix: Function keys were mapped to `GLFW_KEY_UNKNOWN` for some layout combinaitons (#1598) + - [X11] Bugfix: Keys pressed simultaneously with others were not always + reported (#1112,#1415,#1472,#1616) - [Wayland] Bugfix: Repeated keys could be reported with `NULL` window (#1704) @@ -295,8 +297,10 @@ skills. - Eddie Ringle - Max Risuhin - Jorge Rodriguez + - Luca Rood - Ed Ropple - Aleksey Rybalkin + - Mikko Rytkönen - Riku Salminen - Brandon Schaefer - Sebastian Schuberth diff --git a/src/x11_platform.h b/src/x11_platform.h index 7377b2c0..4873bd74 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -199,8 +199,9 @@ typedef struct _GLFWwindowX11 // The last position the cursor was warped to by GLFW int warpCursorPosX, warpCursorPosY; - // The time of the last KeyPress event - Time lastKeyTime; + // The time of the last KeyPress event per keycode, for discarding + // duplicate key events generated for some keys by ibus + Time keyPressTimes[256]; } _GLFWwindowX11; diff --git a/src/x11_window.c b/src/x11_window.c index 37c34fae..9df28973 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -1275,16 +1275,20 @@ static void processEvent(XEvent *event) if (window->x11.ic) { - // HACK: Ignore duplicate key press events generated by ibus - // These have the same timestamp as the original event - // Corresponding release events are filtered out - // implicitly by the GLFW key repeat logic - if (window->x11.lastKeyTime < event->xkey.time) + // HACK: Do not report the key press events duplicated by XIM + // Duplicate key releases are filtered out implicitly by + // the GLFW key repeat logic in _glfwInputKey + // A timestamp per key is used to handle simultaneous keys + // NOTE: Always allow the first event for each key through + // (the server never sends a timestamp of zero) + // NOTE: Timestamp difference is compared to handle wrap-around + Time diff = event->xkey.time - window->x11.keyPressTimes[keycode]; + if (diff == event->xkey.time || (diff > 0 && diff < (1 << 31))) { if (keycode) _glfwInputKey(window, key, keycode, GLFW_PRESS, mods); - window->x11.lastKeyTime = event->xkey.time; + window->x11.keyPressTimes[keycode] = event->xkey.time; } if (!filtered) From 539f4bdca28ba959dd631dd2e90fded528cfc942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 8 Jul 2020 15:53:01 +0200 Subject: [PATCH 2/5] X11: Fix race in window hovered query The window decoration window can go away between calls to XQueryPointer, for example if the GLFW_DECORATED window attribute was just cleared. (cherry picked from commit ceb20c7f97994106db17cc66bd8abad331bc355e) --- src/x11_window.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/x11_window.c b/src/x11_window.c index 9df28973..9ffb5e9e 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -2591,11 +2591,19 @@ int _glfwPlatformWindowHovered(_GLFWwindow* window) int rootX, rootY, childX, childY; unsigned int mask; - if (!XQueryPointer(_glfw.x11.display, w, - &root, &w, &rootX, &rootY, &childX, &childY, &mask)) - { + _glfwGrabErrorHandlerX11(); + + const Bool result = XQueryPointer(_glfw.x11.display, w, + &root, &w, &rootX, &rootY, + &childX, &childY, &mask); + + _glfwReleaseErrorHandlerX11(); + + if (_glfw.x11.errorCode == BadWindow) + w = _glfw.x11.root; + + if (!result) return GLFW_FALSE; - } if (w == window->x11.handle) return GLFW_TRUE; From 85a169ff5080e5a3a6e511978f3a0a5b6a8b3f0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 10 Jul 2020 00:03:53 +0200 Subject: [PATCH 3/5] X11: Fix cursor hover query retry behavior XQueryPointer returns zero on BadWindow so the retry did not happen. Related to ceb20c7f97994106db17cc66bd8abad331bc355e. (cherry picked from commit 49dbcfcb8c5a0f16fc914a114c8d5cfc1a5f97c8) --- src/x11_window.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/x11_window.c b/src/x11_window.c index 9ffb5e9e..90c4d9be 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -2601,11 +2601,9 @@ int _glfwPlatformWindowHovered(_GLFWwindow* window) if (_glfw.x11.errorCode == BadWindow) w = _glfw.x11.root; - - if (!result) + else if (!result) return GLFW_FALSE; - - if (w == window->x11.handle) + else if (w == window->x11.handle) return GLFW_TRUE; } From bd2fb9ebaf86448a216b47a2b6e25650e3fb52cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 15 Jul 2020 21:56:52 +0200 Subject: [PATCH 4/5] Wayland: Fix partial framebuffer size retrieval (cherry picked from commit 5f60c22cfa5c3d62e2cb2f281fd057384fc58f54) --- README.md | 1 + src/wl_window.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3a269d40..5e16933e 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,7 @@ information on what to include when reporting a bug. - [X11] Bugfix: Keys pressed simultaneously with others were not always reported (#1112,#1415,#1472,#1616) - [Wayland] Bugfix: Repeated keys could be reported with `NULL` window (#1704) + - [Wayland] Bugfix: Retrieving partial framebuffer size would segfault ## Contact diff --git a/src/wl_window.c b/src/wl_window.c index 0cc725a5..f811fffc 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1118,8 +1118,10 @@ void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) { _glfwPlatformGetWindowSize(window, width, height); - *width *= window->wl.scale; - *height *= window->wl.scale; + if (width) + *width *= window->wl.scale; + if (height) + *height *= window->wl.scale; } void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, From 114704262c188fdaa63e1af257712296694f3ff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 15 Jul 2020 23:11:19 +0200 Subject: [PATCH 5/5] Wayland: Fix scroll offsets being inverted Scrolling offsets were inverted compared to X11 and Win32. Fixes #1463. (cherry picked from commit f760b124ca849d99effbedb91fb8d10a828aea00) --- README.md | 3 +++ src/wl_init.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5e16933e..263d63e7 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,8 @@ information on what to include when reporting a bug. reported (#1112,#1415,#1472,#1616) - [Wayland] Bugfix: Repeated keys could be reported with `NULL` window (#1704) - [Wayland] Bugfix: Retrieving partial framebuffer size would segfault + - [Wayland] Bugfix: Scrolling offsets were inverted compared to other platforms + (#1463) ## Contact @@ -274,6 +276,7 @@ skills. - ndogxj - Kristian Nielsen - Kamil Nowakowski + - onox - Denis Ovod - Ozzy - Andri Pálsson diff --git a/src/wl_init.c b/src/wl_init.c index 97b53673..49e7cc52 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -347,9 +347,9 @@ static void pointerHandleAxis(void* data, axis == WL_POINTER_AXIS_VERTICAL_SCROLL); if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL) - x = wl_fixed_to_double(value) * scrollFactor; + x = -wl_fixed_to_double(value) * scrollFactor; else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL) - y = wl_fixed_to_double(value) * scrollFactor; + y = -wl_fixed_to_double(value) * scrollFactor; _glfwInputScroll(window, x, y); }