From 562c17d131bd99d92f1166e2a8a42d7af023d122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 15 Jan 2020 16:19:56 +0100 Subject: [PATCH] Win32: Fix no Super key release event after Win+V The Win+V hotkey brings up a clipboard history IME that consumes the key release. This adds left and right Super to the modifier keys manually polled for undetected release during event processing. Fixes #1622. --- README.md | 1 + src/win32_window.c | 41 +++++++++++++++++++++++++---------------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 15593c67..c4b57ad0 100644 --- a/README.md +++ b/README.md @@ -141,6 +141,7 @@ information on what to include when reporting a bug. - [Win32] Bugfix: The window hint `GLFW_MAXIMIZED` did not move or resize the window (#1499) - [Win32] Bugfix: Disabled cursor mode interfered with some non-client actions + - [Win32] Bugfix: Super key was not released after Win+V hotkey (#1622) - [Cocoa] Added support for `VK_EXT_metal_surface` (#1619) - [Cocoa] Added locating the Vulkan loader at runtime in an application bundle - [Cocoa] Removed dependency on the CoreVideo framework diff --git a/src/win32_window.c b/src/win32_window.c index 3a50c542..79f40d3c 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1934,30 +1934,39 @@ void _glfwPlatformPollEvents(void) } } + // HACK: Release modifier keys that the system did not emit KEYUP for + // NOTE: Shift keys on Windows tend to "stick" when both are pressed as + // no key up message is generated by the first key release + // NOTE: Windows key is not reported as released by the Win+V hotkey + // Other Win hotkeys are handled implicitly by _glfwInputWindowFocus + // because they change the input focus handle = GetActiveWindow(); if (handle) { - // NOTE: Shift keys on Windows tend to "stick" when both are pressed as - // no key up message is generated by the first key release - // The other half of this is in the handling of WM_KEYUP - // HACK: Query actual key state and synthesize release events as needed window = GetPropW(handle, L"GLFW"); if (window) { - const GLFWbool lshift = (GetAsyncKeyState(VK_LSHIFT) & 0x8000) != 0; - const GLFWbool rshift = (GetAsyncKeyState(VK_RSHIFT) & 0x8000) != 0; + int i; + const int keys[4][2] = + { + { VK_LSHIFT, GLFW_KEY_LEFT_SHIFT }, + { VK_RSHIFT, GLFW_KEY_RIGHT_SHIFT }, + { VK_LWIN, GLFW_KEY_LEFT_SUPER }, + { VK_RWIN, GLFW_KEY_RIGHT_SUPER } + }; - if (!lshift && window->keys[GLFW_KEY_LEFT_SHIFT] == GLFW_PRESS) + for (i = 0; i < 4; i++) { - const int mods = getAsyncKeyMods(); - const int scancode = _glfw.win32.scancodes[GLFW_KEY_LEFT_SHIFT]; - _glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, GLFW_RELEASE, mods); - } - else if (!rshift && window->keys[GLFW_KEY_RIGHT_SHIFT] == GLFW_PRESS) - { - const int mods = getAsyncKeyMods(); - const int scancode = _glfw.win32.scancodes[GLFW_KEY_RIGHT_SHIFT]; - _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, GLFW_RELEASE, mods); + const int vk = keys[i][0]; + const int key = keys[i][1]; + const int scancode = _glfw.win32.scancodes[key]; + + if ((GetAsyncKeyState(vk) & 0x8000)) + continue; + if (window->keys[key] != GLFW_PRESS) + continue; + + _glfwInputKey(window, key, scancode, GLFW_RELEASE, getAsyncKeyMods()); } } }