@@ -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<String>, 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<String> {