Skip to content

Commit

Permalink
Win32: Fix no Super key release event after Win+V
Browse files Browse the repository at this point in the history
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 glfw#1622.
  • Loading branch information
elmindreda committed Jan 16, 2020
1 parent 7da87aa commit 562c17d
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 16 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
41 changes: 25 additions & 16 deletions src/win32_window.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

if (!lshift && window->keys[GLFW_KEY_LEFT_SHIFT] == GLFW_PRESS)
int i;
const int keys[4][2] =
{
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)
{ VK_LSHIFT, GLFW_KEY_LEFT_SHIFT },
{ VK_RSHIFT, GLFW_KEY_RIGHT_SHIFT },
{ VK_LWIN, GLFW_KEY_LEFT_SUPER },
{ VK_RWIN, GLFW_KEY_RIGHT_SUPER }
};

for (i = 0; i < 4; i++)
{
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());
}
}
}
Expand Down

0 comments on commit 562c17d

Please sign in to comment.