diff --git a/crates/gpui/src/platform/windows/events.rs b/crates/gpui/src/platform/windows/events.rs index 2a962b0c235e9900ded1496352521033fa8de667..4e6df63106f4c650ad3130e39d410670ddc4687d 100644 --- a/crates/gpui/src/platform/windows/events.rs +++ b/crates/gpui/src/platform/windows/events.rs @@ -1332,21 +1332,13 @@ fn parse_normal_key( lparam: LPARAM, mut modifiers: Modifiers, ) -> Option<(Keystroke, bool)> { - let mut key_char = None; + let (key_char, prefer_character_input) = process_key(vkey, lparam.hiword()); + let key = parse_immutable(vkey).or_else(|| { let scan_code = lparam.hiword() & 0xFF; - key_char = generate_key_char( - vkey, - scan_code as u32, - modifiers.control, - modifiers.shift, - modifiers.alt, - ); get_keystroke_key(vkey, scan_code as u32, &mut modifiers) })?; - let prefer_character_input = should_prefer_character_input(vkey, lparam.hiword() & 0xFF); - Some(( Keystroke { modifiers, @@ -1357,11 +1349,11 @@ fn parse_normal_key( )) } -fn should_prefer_character_input(vkey: VIRTUAL_KEY, scan_code: u16) -> bool { +fn process_key(vkey: VIRTUAL_KEY, scan_code: u16) -> (Option, bool) { let mut keyboard_state = [0u8; 256]; unsafe { if GetKeyboardState(&mut keyboard_state).is_err() { - return false; + return (None, false); } } @@ -1372,21 +1364,25 @@ fn should_prefer_character_input(vkey: VIRTUAL_KEY, scan_code: u16) -> bool { scan_code as u32, Some(&keyboard_state), &mut buffer_c, - 0x5, + 0x4, ) }; + + if result_c == 0 { + return (None, false); + } + + let c = &buffer_c[..result_c.unsigned_abs() as usize]; + let key_char = String::from_utf16(c) + .ok() + .filter(|s| !s.is_empty() && !s.chars().next().unwrap().is_control()); + if result_c < 0 { - return false; + return (key_char, true); } - let c = &buffer_c[..result_c as usize]; - if char::decode_utf16(c.iter().copied()) - .next() - .and_then(|ch| ch.ok()) - .map(|ch| ch.is_control()) - .unwrap_or(true) - { - return false; + if key_char.is_none() { + return (None, false); } // Workaround for some bug that makes the compiler think keyboard_state is still zeroed out @@ -1395,9 +1391,10 @@ fn should_prefer_character_input(vkey: VIRTUAL_KEY, scan_code: u16) -> bool { let alt_down = (keyboard_state[VK_MENU.0 as usize] & 0x80) != 0; let win_down = (keyboard_state[VK_LWIN.0 as usize] & 0x80) != 0 || (keyboard_state[VK_RWIN.0 as usize] & 0x80) != 0; + let has_modifiers = ctrl_down || alt_down || win_down; if !has_modifiers { - return false; + return (key_char, false); } let mut state_no_modifiers = keyboard_state; @@ -1417,15 +1414,15 @@ fn should_prefer_character_input(vkey: VIRTUAL_KEY, scan_code: u16) -> bool { scan_code as u32, Some(&state_no_modifiers), &mut buffer_c_no_modifiers, - 0x5, + 0x4, ) }; - if result_c_no_modifiers <= 0 { - return false; - } - let c_no_modifiers = &buffer_c_no_modifiers[..result_c_no_modifiers as usize]; - c != c_no_modifiers + let c_no_modifiers = &buffer_c_no_modifiers[..result_c_no_modifiers.unsigned_abs() as usize]; + ( + key_char, + result_c != result_c_no_modifiers || c != c_no_modifiers, + ) } fn parse_ime_composition_string(ctx: HIMC, comp_type: IME_COMPOSITION_STRING) -> Option {