diff --git a/nebula_app/src/gpui_shell/terminal/keymap.rs b/nebula_app/src/gpui_shell/terminal/keymap.rs index 01c1db7..0089798 100644 --- a/nebula_app/src/gpui_shell/terminal/keymap.rs +++ b/nebula_app/src/gpui_shell/terminal/keymap.rs @@ -589,45 +589,28 @@ mod tests { /// 当按键已处理、不再 TranslateMessage,中文组字起不来。 #[cfg(windows)] #[test] - fn win32_mode_preserves_text_input_and_modified_slash() { + fn unmodified_letters_stay_on_the_ime_path_in_win32_mode() { let mode = TermMode::WIN32_INPUT_MODE; assert_eq!(encode(&keystroke("n"), &mode), None); assert_eq!(encode(&keystroke("a"), &mode), None); assert_eq!(encode(&keystroke("1"), &mode), None); assert_eq!(encode(&keystroke("space"), &mode), None); - assert_eq!(encode(&keystroke("/"), &mode), None); - assert_eq!(encode(&keystroke("?"), &mode), None); - assert_eq!(encode(&Keystroke::parse("shift-/").unwrap(), &mode), None); // Ctrl+C 仍走记录,不能为了 IME 把快捷键也放掉。 let mut ctrl_c = keystroke("c"); ctrl_c.modifiers.control = true; assert!(encode(&ctrl_c, &mode).is_some()); assert!(encode(&keystroke("escape"), &mode).is_some()); - - use windows_sys::Win32::UI::Input::KeyboardAndMouse::{ - MAPVK_VK_TO_VSC, MapVirtualKeyW, VkKeyScanW, - }; - - let key = Keystroke::parse("ctrl-/").unwrap(); - let mapping = unsafe { VkKeyScanW(b'/' as u16) } as u16; - let vk = mapping & 0xff; - let scan = unsafe { MapVirtualKeyW(u32::from(vk), MAPVK_VK_TO_VSC) }; - let modifiers = 8 | ((mapping >> 8 & 1) << 4) | ((mapping >> 8 & 4) >> 1); - assert_eq!( - encode(&key, &TermMode::WIN32_INPUT_MODE), - Some( - format!("\x1b[{vk};{scan};0;1;{modifiers};1_\x1b[{vk};{scan};0;0;{modifiers};1_") - .into_bytes() - ) - ); } + #[cfg(windows)] #[test] - fn ctrl_slash_keeps_legacy_and_kitty_encodings() { + fn ctrl_slash_uses_its_windows_virtual_key() { + use windows_sys::Win32::UI::Input::KeyboardAndMouse::VkKeyScanW; + let key = Keystroke::parse("ctrl-/").unwrap(); - assert_eq!(encode(&key, &TermMode::default()), Some(b"\x1f".to_vec())); - let mode = TermMode::WIN32_INPUT_MODE | TermMode::DISAMBIGUATE_ESC_CODES; - assert_eq!(encode(&key, &mode), Some(b"\x1b[47;5u".to_vec())); + let vk = unsafe { VkKeyScanW(b'/' as u16) } as u16 & 0xff; + let encoded = encode(&key, &TermMode::WIN32_INPUT_MODE).unwrap(); + assert!(encoded.starts_with(format!("\x1b[{vk};").as_bytes())); } /// 普通空格与字母使用同一文本输入路径:英语布局最终提交 `" "`,IME diff --git a/nebula_app/src/gpui_shell/terminal/keymap/win32.rs b/nebula_app/src/gpui_shell/terminal/keymap/win32.rs index 771870b..2e0aef4 100644 --- a/nebula_app/src/gpui_shell/terminal/keymap/win32.rs +++ b/nebula_app/src/gpui_shell/terminal/keymap/win32.rs @@ -2,7 +2,7 @@ use gpui::Keystroke; -/// 普通可打印字符必须交给 IME / `TranslateMessage`,不能编进 PTY。 +/// 无修饰的字母/数字/空格必须交给 IME / `TranslateMessage`,不能编进 PTY。 /// /// GPUI 的 Windows 后端:`on_key_down` 一旦 `stop_propagation`,就不会再 /// `TranslateMessage`。IME 组字(微软拼音)是 TranslateMessage 喂进去的; @@ -18,7 +18,7 @@ pub(super) fn win32_encodes_keystroke(ks: &Keystroke) -> bool { } let mut chars = key.chars(); match (chars.next(), chars.next()) { - (Some(c), None) if c.is_ascii_graphic() => false, + (Some(c), None) if c.is_ascii_alphanumeric() => false, _ => true, } }