[PATCH 0/1] MR11105: winewayland: Fix handling of numlock and right shift.
See user32 tests. MSDN says only numlock behaves this way, but right shift also does. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11105
From: Etaash Mathamsetty <etaash.mathamsetty@gmail.com> --- dlls/winewayland.drv/wayland_keyboard.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dlls/winewayland.drv/wayland_keyboard.c b/dlls/winewayland.drv/wayland_keyboard.c index 0a6eea2fa73..25e8a54dd4b 100644 --- a/dlls/winewayland.drv/wayland_keyboard.c +++ b/dlls/winewayland.drv/wayland_keyboard.c @@ -880,6 +880,15 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, input.ki.wScan = (scan & 0x300) ? scan + 0xdf00 : scan; input.ki.dwFlags = KEYEVENTF_SCANCODE; if (scan & ~0xff) input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY; + /* these keys are extended despite not having an extended scan code */ + else switch (key) + { + case KEY_NUMLOCK: + case KEY_RIGHTSHIFT: + input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY; + break; + default: break; + } if (state == WL_KEYBOARD_KEY_STATE_RELEASED) input.ki.dwFlags |= KEYEVENTF_KEYUP; NtUserSendHardwareInput(hwnd, 0, &input, 0); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11105
Rémi Bernon (@rbernon) commented about dlls/winewayland.drv/wayland_keyboard.c:
input.ki.wScan = (scan & 0x300) ? scan + 0xdf00 : scan; input.ki.dwFlags = KEYEVENTF_SCANCODE; if (scan & ~0xff) input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY; + /* these keys are extended despite not having an extended scan code */ + else switch (key) + { + case KEY_NUMLOCK: + case KEY_RIGHTSHIFT: + input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY; + break; + default: break; + }
I think driver should only need to care about sending some normalized scancodes to wineserver, and the rest of native behavior be implemented over that. So, this probably would better be done in wineserver or win32u, and it would benefit all drivers at once. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11105#note_142594
On Wed Jun 10 06:59:33 2026 +0000, Rémi Bernon wrote:
I think driver should only need to care about sending some normalized scancodes to wineserver, and the rest of native behavior be implemented over that. So, this probably would better be done in wineserver or win32u, and it would benefit all drivers at once. That was my original idea, but the tests in user32 seemed to show that sending hardware input of 0x36 scancode with no `KEYEVENTF_EXTENDEDKEY` would lead to VK_LSHIFT.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/11105#note_142601
On Wed Jun 10 08:30:46 2026 +0000, Etaash Mathamsetty wrote:
That was my original idea, but the tests in user32 seemed to show that sending hardware input of 0x36 scancode with no `KEYEVENTF_EXTENDEDKEY` would lead to VK_LSHIFT.
struct send_input_keyboard_test rshift_scan[] =
{
{.scan = 0x36, .flags = KEYEVENTF_SCANCODE, .expect_state = {[VK_SHIFT] = 0x80, [VK_LSHIFT] = 0x80},
.expect = {KEY_HOOK(WM_KEYDOWN, 0x36, VK_RSHIFT), KEY_MSG(WM_KEYDOWN, 0x36, VK_SHIFT), {0}}},
{.scan = scan, .flags = KEYEVENTF_SCANCODE, .expect_state = {[VK_SHIFT] = 0x80, [VK_LSHIFT] = 0x80, /*[vkey] = 0x80*/},
.expect = {KEY_HOOK(WM_KEYDOWN, scan, vkey), KEY_MSG(WM_KEYDOWN, scan, vkey), WIN_MSG(WM_CHAR, wch_shift, MAKELONG(1, scan)), {0}}},
{.scan = scan, .flags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP, .expect_state = {[VK_SHIFT] = 0x80, [VK_LSHIFT] = 0x80},
.expect = {KEY_HOOK(WM_KEYUP, scan, vkey), KEY_MSG(WM_KEYUP, scan, vkey), {0}}},
{.scan = 0x36, .flags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP,
.expect = {KEY_HOOK(WM_KEYUP, 0x36, VK_RSHIFT), KEY_MSG(WM_KEYUP, 0x36, VK_SHIFT), {0}}},
{0},
};
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/11105#note_142602
On Wed Jun 10 08:32:09 2026 +0000, Etaash Mathamsetty wrote:
``` struct send_input_keyboard_test rshift_scan[] = { {.scan = 0x36, .flags = KEYEVENTF_SCANCODE, .expect_state = {[VK_SHIFT] = 0x80, [VK_LSHIFT] = 0x80}, .expect = {KEY_HOOK(WM_KEYDOWN, 0x36, VK_RSHIFT), KEY_MSG(WM_KEYDOWN, 0x36, VK_SHIFT), {0}}}, {.scan = scan, .flags = KEYEVENTF_SCANCODE, .expect_state = {[VK_SHIFT] = 0x80, [VK_LSHIFT] = 0x80, /*[vkey] = 0x80*/}, .expect = {KEY_HOOK(WM_KEYDOWN, scan, vkey), KEY_MSG(WM_KEYDOWN, scan, vkey), WIN_MSG(WM_CHAR, wch_shift, MAKELONG(1, scan)), {0}}}, {.scan = scan, .flags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP, .expect_state = {[VK_SHIFT] = 0x80, [VK_LSHIFT] = 0x80}, .expect = {KEY_HOOK(WM_KEYUP, scan, vkey), KEY_MSG(WM_KEYUP, scan, vkey), {0}}}, {.scan = 0x36, .flags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP, .expect = {KEY_HOOK(WM_KEYUP, 0x36, VK_RSHIFT), KEY_MSG(WM_KEYUP, 0x36, VK_SHIFT), {0}}}, {0}, }; ```
Hmm, then maybe wineserver should check hardware input origin (IMO_HARDWARE vs IMO_INJECTED) to decide to translate to VK_RSHIFT even without extended bit. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11105#note_142603
On Wed Jun 10 08:40:31 2026 +0000, Rémi Bernon wrote:
Hmm, then maybe wineserver should check hardware input origin (IMO_HARDWARE vs IMO_INJECTED) to decide to translate to VK_RSHIFT even without extended bit. That makes sense; I will try this. How would you approach key repeat if you do this? Does something like right shift have a key repeat? I havent checked
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/11105#note_142605
participants (3)
-
Etaash Mathamsetty -
Etaash Mathamsetty (@etaash.mathamsetty) -
Rémi Bernon (@rbernon)