diff --git a/README.md b/README.md index 0e3bf45c..ed23baf2 100644 --- a/README.md +++ b/README.md @@ -137,7 +137,12 @@ 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) + - [Wayland] Bugfix: Retrieving partial framebuffer size would segfault + - [Wayland] Bugfix: Scrolling offsets were inverted compared to other platforms + (#1463) ## Contact @@ -276,6 +281,7 @@ skills. - ndogxj - Kristian Nielsen - Kamil Nowakowski + - onox - Denis Ovod - Ozzy - Andri Pálsson @@ -300,8 +306,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/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); } diff --git a/src/wl_window.c b/src/wl_window.c index e30f947f..c57b0d78 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1096,8 +1096,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, diff --git a/src/x11_platform.h b/src/x11_platform.h index cc61a835..ec5af01d 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -205,8 +205,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 eeb845d1..8e815cf1 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) @@ -2587,13 +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)) - { - return GLFW_FALSE; - } + _glfwGrabErrorHandlerX11(); - if (w == window->x11.handle) + 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; + else if (!result) + return GLFW_FALSE; + else if (w == window->x11.handle) return GLFW_TRUE; }