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. diff --git a/plover/oslayer/windows/keyboardcontrol.py b/plover/oslayer/windows/keyboardcontrol.py index e960dc10f..062ecd98f 100644 --- a/plover/oslayer/windows/keyboardcontrol.py +++ b/plover/oslayer/windows/keyboardcontrol.py @@ -561,15 +561,19 @@ 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_with_fallback.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..fcb2a642b 100644 --- a/plover/oslayer/windows/keyboardlayout.py +++ b/plover/oslayer/windows/keyboardlayout.py @@ -376,13 +376,32 @@ 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: 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)