Fix wrong scan code values in key events obtained on Windows

The scan code (Windows) value depends on the extended-key flag
(KF_EXTENDED 0x0100) in the key message. This flag was kept in scan code
value, which is wrong. It is not part of scan code, and when it's on,
another byte 0xE0 should be prepended to scan code. See:
https://learn.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input#extended-key-flag

Change-Id: Iddcabb0aae92bb784883bddc9a34fe134d787b32
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
This commit is contained in:
Li Yefeng 2023-07-04 15:50:19 +01:00
parent 0b3c5816c6
commit fbd259856d

View File

@ -88,9 +88,17 @@ QWindowsKeyMapper::~QWindowsKeyMapper()= default;
#define VK_OEM_3 0xC0
#endif
// We not only need the scancode itself but also the extended bit of key messages. Thus we need
// the additional bit when masking the scancode.
enum { scancodeBitmask = 0x1ff };
// Get scancode from the given message
static constexpr quint32 getScancode(const MSG &msg)
{
const auto keyFlags = HIWORD(msg.lParam);
quint32 scancode = LOBYTE(keyFlags);
// if extended-key flag is on, the scan code consists of a sequence of two bytes,
// where the first byte has a value of 0xe0.
if ((keyFlags & KF_EXTENDED) != 0)
scancode |= 0xE000;
return scancode;
}
// Key recorder ------------------------------------------------------------------------[ start ] --
struct KeyRecord {
@ -656,7 +664,7 @@ void QWindowsKeyMapper::updateKeyMap(const MSG &msg)
{
unsigned char kbdBuffer[256]; // Will hold the complete keyboard state
GetKeyboardState(kbdBuffer);
const quint32 scancode = (msg.lParam >> 16) & scancodeBitmask;
const quint32 scancode = getScancode(msg);
updatePossibleKeyCodes(kbdBuffer, scancode, quint32(msg.wParam));
}
@ -942,7 +950,7 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, MSG msg,
m_seenAltGr = true;
const UINT msgType = msg.message;
const quint32 scancode = (msg.lParam >> 16) & scancodeBitmask;
const quint32 scancode = getScancode(msg);
auto vk_key = quint32(msg.wParam);
quint32 nModifiers = 0;