diff options
| author | JJ Liebig <jonathan.liebig@gmail.com> | 2026-09-03 17:20:57 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-09-03 17:20:57 +0200 |
| commit | 0496636dc75db14a99aa71a7cadb006dc027d5c6 (patch) | |
| tree | 943d44ed4474ccc9e39ee527a44f00365c81dfbb /src/platform | |
| parent | 0f8ad128b65869d683253753a477c0ccafca9bf2 (diff) | |
fix(windows): preserve ctrl+slash key identity (#3578)
refs #2954
Diffstat (limited to 'src/platform')
| -rw-r--r-- | src/platform/windows.rs | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/src/platform/windows.rs b/src/platform/windows.rs index b05b9e6f..890c24ca 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -105,8 +105,8 @@ use windows_sys::{ Input::{ Ime::ImmGetDefaultIMEWnd, KeyboardAndMouse::{ - GetKeyboardLayout, SendInput, INPUT, INPUT_0, INPUT_KEYBOARD, KEYBDINPUT, - KEYEVENTF_KEYUP, + GetKeyboardLayout, SendInput, ToUnicodeEx, INPUT, INPUT_0, INPUT_KEYBOARD, + KEYBDINPUT, KEYEVENTF_KEYUP, }, }, Shell::{ @@ -134,6 +134,32 @@ pub(crate) fn terminal_title_for_presentation(title: &str) -> &str { title.strip_prefix("Administrator: ").unwrap_or(title) } +/// Resolves against the current foreground layout because asynchronous console +/// records do not retain the layout that was active when the key was pressed. +pub(crate) fn resolve_base_printable_key(vk: u16, scan: u16) -> Option<char> { + // SAFETY: Win32 owns the handles; the fixed buffers match the API lengths. + unsafe { + let thread_id = GetWindowThreadProcessId(GetForegroundWindow(), null_mut()); + let layout = GetKeyboardLayout(thread_id); + + let key_state = [0u8; 256]; + let mut output = [0u16; 2]; + let written = ToUnicodeEx( + vk.into(), + scan.into(), + key_state.as_ptr(), + output.as_mut_ptr(), + output.len() as i32, + 0x4, + layout, + ); + let units = output.get(..usize::try_from(written).ok()?)?; + let mut chars = char::decode_utf16(units.iter().copied()); + let ch = chars.next()?.ok()?; + (chars.next().is_none() && !ch.is_control()).then_some(ch) + } +} + const MAX_PROCESS_ENVIRONMENT_BYTES: usize = 256 * 1024; const PROCESS_ENVIRONMENT_READ_CHUNK_BYTES: usize = 16 * 1024; const PROCESS_RUNTIME_MARKER_CACHE_CAPACITY: usize = 1_024; |
