Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news.d/bugfix/1755.windows.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Send correct scancode in simulated key presses.
12 changes: 8 additions & 4 deletions plover/oslayer/windows/keyboardcontrol.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
21 changes: 20 additions & 1 deletion plover/oslayer/windows/keyboardlayout.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
Loading