From 848596a2f478a0c162083780199a91ec4ddbdb50 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 16 Jul 2025 19:14:20 +0700 Subject: [PATCH 1/5] Send correct scancode on Windows --- plover/oslayer/windows/keyboardcontrol.py | 8 ++++---- plover/oslayer/windows/keyboardlayout.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/plover/oslayer/windows/keyboardcontrol.py b/plover/oslayer/windows/keyboardcontrol.py index e960dc10f..189e22d71 100644 --- a/plover/oslayer/windows/keyboardcontrol.py +++ b/plover/oslayer/windows/keyboardcontrol.py @@ -561,15 +561,15 @@ def _mouse_input(flags, x, y, data): # Keyboard input type to send key input @staticmethod - def _keyboard_input(code, flags): + def _keyboard_input(code, scancode, flags): if flags & KEYEVENTF_UNICODE: - # special handling of Unicode characters + # special handling of Unicode characters (scancode discarded) return KEYBDINPUT(0, code, flags, 0, None) - return KEYBDINPUT(code, 0, flags, 0, None) + return KEYBDINPUT(code, scancode, flags, 0, None) # Abstraction to set flags to 0 and create an input type def _keyboard(self, code, flags=0): - return self._input(self._keyboard_input(code, flags)) + return self._input(self._keyboard_input(code, self.keyboard_layout.vk_to_sc.get(code, 0), flags)) def _key_event(self, keycode, pressed): flags = 0 if pressed else KEYEVENTF_KEYUP diff --git a/plover/oslayer/windows/keyboardlayout.py b/plover/oslayer/windows/keyboardlayout.py index 52a75c927..4c6b6cd6d 100644 --- a/plover/oslayer/windows/keyboardlayout.py +++ b/plover/oslayer/windows/keyboardlayout.py @@ -376,7 +376,7 @@ def __init__(self, layout_id=None, debug=False): # Find virtual key code for each scan code (if any). sc_to_vk = {} - vk_to_sc = {} + self.vk_to_sc = vk_to_sc = {} for sc in range(0x01, 0x7F + 1): vk = MapVirtualKeyEx(sc, 3, layout_id) if vk != 0: From ad4e13b4a9bf55d8b51d432127ea9a9ebdcf36ff Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 16 Jul 2025 19:29:24 +0700 Subject: [PATCH 2/5] Add news entry --- news.d/bugfix/1755.windows.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 news.d/bugfix/1755.windows.md diff --git a/news.d/bugfix/1755.windows.md b/news.d/bugfix/1755.windows.md new file mode 100644 index 000000000..d60eec9b3 --- /dev/null +++ b/news.d/bugfix/1755.windows.md @@ -0,0 +1 @@ +Send correct scancode in simulated key presses. From 0cc380f50b20a71e8adef108ac578c270ce68103 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 16 Jul 2025 19:31:48 +0700 Subject: [PATCH 3/5] Fix ruff --- plover/oslayer/windows/keyboardcontrol.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plover/oslayer/windows/keyboardcontrol.py b/plover/oslayer/windows/keyboardcontrol.py index 189e22d71..62ff486e9 100644 --- a/plover/oslayer/windows/keyboardcontrol.py +++ b/plover/oslayer/windows/keyboardcontrol.py @@ -569,7 +569,11 @@ def _keyboard_input(code, scancode, flags): # Abstraction to set flags to 0 and create an input type def _keyboard(self, code, flags=0): - return self._input(self._keyboard_input(code, self.keyboard_layout.vk_to_sc.get(code, 0), flags)) + return self._input( + self._keyboard_input( + code, self.keyboard_layout.vk_to_sc.get(code, 0), flags + ) + ) def _key_event(self, keycode, pressed): flags = 0 if pressed else KEYEVENTF_KEYUP From ffb2c1a8df9723cf7aa56870c868e1a4353bc11a Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Thu, 17 Jul 2025 19:45:04 +0700 Subject: [PATCH 4/5] Fallback the modifier keys --- plover/oslayer/windows/keyboardcontrol.py | 2 +- plover/oslayer/windows/keyboardlayout.py | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/plover/oslayer/windows/keyboardcontrol.py b/plover/oslayer/windows/keyboardcontrol.py index 62ff486e9..062ecd98f 100644 --- a/plover/oslayer/windows/keyboardcontrol.py +++ b/plover/oslayer/windows/keyboardcontrol.py @@ -571,7 +571,7 @@ def _keyboard_input(code, scancode, flags): def _keyboard(self, code, flags=0): return self._input( self._keyboard_input( - code, self.keyboard_layout.vk_to_sc.get(code, 0), flags + code, self.keyboard_layout.vk_to_sc_with_fallback.get(code, 0), flags ) ) diff --git a/plover/oslayer/windows/keyboardlayout.py b/plover/oslayer/windows/keyboardlayout.py index 4c6b6cd6d..9c57888d1 100644 --- a/plover/oslayer/windows/keyboardlayout.py +++ b/plover/oslayer/windows/keyboardlayout.py @@ -383,6 +383,19 @@ def __init__(self, layout_id=None, debug=False): sc_to_vk[sc] = vk vk_to_sc[vk] = sc + from copy import copy + self.vk_to_sc_with_fallback = copy(vk_to_sc) + for vk, fallback_vk in [ + (VK.CONTROL, VK.LCONTROL), + (VK.CONTROL, VK.RCONTROL), + (VK.MENU, VK.LMENU), + (VK.MENU, VK.RMENU), + (VK.SHIFT, VK.LSHIFT), + (VK.SHIFT, VK.RSHIFT), + ]: + if fallback_vk in self.vk_to_sc_with_fallback and vk not in self.vk_to_sc_with_fallback: + self.vk_to_sc_with_fallback[vk] = self.vk_to_sc_with_fallback[fallback_vk] + state = (wintypes.BYTE * 256)() strbuf = ctypes.create_unicode_buffer(8) From c85ae7fa7f67d77bcba8ba3e49019035b7c56453 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Fri, 18 Jul 2025 08:14:17 +0700 Subject: [PATCH 5/5] Fix ruff again --- plover/oslayer/windows/keyboardlayout.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/plover/oslayer/windows/keyboardlayout.py b/plover/oslayer/windows/keyboardlayout.py index 9c57888d1..fcb2a642b 100644 --- a/plover/oslayer/windows/keyboardlayout.py +++ b/plover/oslayer/windows/keyboardlayout.py @@ -384,17 +384,23 @@ def __init__(self, layout_id=None, debug=False): vk_to_sc[vk] = sc from copy import copy + self.vk_to_sc_with_fallback = copy(vk_to_sc) for vk, fallback_vk in [ - (VK.CONTROL, VK.LCONTROL), - (VK.CONTROL, VK.RCONTROL), - (VK.MENU, VK.LMENU), - (VK.MENU, VK.RMENU), - (VK.SHIFT, VK.LSHIFT), - (VK.SHIFT, VK.RSHIFT), - ]: - if fallback_vk in self.vk_to_sc_with_fallback and vk not in self.vk_to_sc_with_fallback: - self.vk_to_sc_with_fallback[vk] = self.vk_to_sc_with_fallback[fallback_vk] + (VK.CONTROL, VK.LCONTROL), + (VK.CONTROL, VK.RCONTROL), + (VK.MENU, VK.LMENU), + (VK.MENU, VK.RMENU), + (VK.SHIFT, VK.LSHIFT), + (VK.SHIFT, VK.RSHIFT), + ]: + if ( + fallback_vk in self.vk_to_sc_with_fallback + and vk not in self.vk_to_sc_with_fallback + ): + self.vk_to_sc_with_fallback[vk] = self.vk_to_sc_with_fallback[ + fallback_vk + ] state = (wintypes.BYTE * 256)() strbuf = ctypes.create_unicode_buffer(8)