http://bugs.winehq.org/show_bug.cgi?id=35907
--- Comment #4 from Ken Thomases ken@codeweavers.com --- Created attachment 47963 --> http://bugs.winehq.org/attachment.cgi?id=47963 Test program for behavior on Windows
The attached program (with source) helps demonstrate the behavior on Windows. When you run it, it presents a window. It logs when it gets a WM_KEYDOWN or WM_SYSKEYDOWN for VK_CAPITAL. It also checks the status of VK_CAPITAL with GetAsyncKeyState(), GetKeyState(), and GetKeyboardState(). It does that same check every 3 seconds, even with it doesn't have focus or receive WM_KEYDOWN.
On Windows, when the window has focus, turning Caps Lock on and waiting a few seconds results in:
11:12:44: WM_KEYDOWN VK_CAPITAL 11:12:44: GetKeyState(VK_CAPITAL) 0x00 -> 0x81 GetKeyboardState() VK_CAPITAL 0x00 -> 0x81 11:12:44: GetKeyState(VK_CAPITAL) 0x81 -> 0x01 GetKeyboardState() VK_CAPITAL 0x81 -> 0x01
Turning it back off:
11:12:52: WM_KEYDOWN VK_CAPITAL 11:12:52: GetKeyState(VK_CAPITAL) 0x01 -> 0x80 GetKeyboardState() VK_CAPITAL 0x01 -> 0x80 11:12:53: GetKeyState(VK_CAPITAL) 0x80 -> 0x00 GetKeyboardState() VK_CAPITAL 0x80 -> 0x00
Then, if you switch to another window and turn Caps Lock on and wait:
11:13:02: GetKeyState(VK_CAPITAL) 0x00 -> 0x01 GetKeyboardState() VK_CAPITAL 0x00 -> 0x01
And turn it off again and wait:
11:13:08: GetKeyState(VK_CAPITAL) 0x01 -> 0x00 GetKeyboardState() VK_CAPITAL 0x01 -> 0x00
So, the thread without focus does not get a WM_KEYDOWN, but its thread-specific key state changes "spontaneously".
Curiously, GetAsyncKeyState(VK_CAPITAL) never showed the key being down (having the high bit set), even when I was holding it down for long periods. It did show that the key had been pressed since the last call (low bit set), but I've masked that out as noise.