fix(windows): restore ENABLE_WINDOW_INPUT console flag after enable_raw_mode for IME support
This commit is contained in:
committed by
Hunter Bown
parent
1ff5db1663
commit
09d3131dc2
@@ -24,6 +24,7 @@ use crossterm::{
|
||||
use crossterm::event::{
|
||||
KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags,
|
||||
};
|
||||
#[cfg(target_os = "windows")]
|
||||
use ratatui::{
|
||||
Frame, Terminal,
|
||||
layout::{Constraint, Direction, Layout, Rect, Size},
|
||||
@@ -32,6 +33,8 @@ use ratatui::{
|
||||
widgets::Block,
|
||||
};
|
||||
use tracing;
|
||||
#[cfg(target_os = "windows")]
|
||||
use windows::Win32::System::Console::{GetConsoleMode, GetStdHandle, SetConsoleMode};
|
||||
|
||||
use crate::audit::log_sensitive_event;
|
||||
use crate::automation_manager::{AutomationManager, AutomationSchedulerConfig, spawn_scheduler};
|
||||
@@ -280,6 +283,9 @@ pub async fn run_tui(config: &Config, options: TuiOptions) -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
enable_windows_ime_console_mode();
|
||||
|
||||
let mut stdout = io::stdout();
|
||||
if use_alt_screen {
|
||||
execute!(stdout, EnterAlternateScreen)?;
|
||||
@@ -7042,6 +7048,36 @@ pub fn emergency_restore_terminal() {
|
||||
let _ = execute!(stdout, LeaveAlternateScreen);
|
||||
}
|
||||
|
||||
/// On Windows, ensure the console input handle has `ENABLE_WINDOW_INPUT`
|
||||
/// (0x0008) set. crossterm's `enable_raw_mode()` removes this flag, which
|
||||
/// breaks IME composition (Chinese/Japanese/Korean input methods cannot
|
||||
/// commit characters) on some Windows configurations (e.g. Windows Terminal
|
||||
/// in conhost compatibility mode, or the legacy console with VT input).
|
||||
///
|
||||
/// Best-effort and idempotent. Silently ignored if the console handle or
|
||||
/// mode query fails.
|
||||
#[cfg(target_os = "windows")]
|
||||
fn enable_windows_ime_console_mode() {
|
||||
use windows::Win32::System::Console::CONSOLE_MODE;
|
||||
const ENABLE_WINDOW_INPUT: CONSOLE_MODE = CONSOLE_MODE(0x0008);
|
||||
|
||||
// SAFETY: Win32 console API is safe to call from any thread.
|
||||
// Failures (console handle invalid, mode query fails) are silently
|
||||
// ignored — this is a best-effort IME compatibility tweak.
|
||||
unsafe {
|
||||
let Ok(handle) = GetStdHandle(windows::Win32::System::Console::STD_INPUT_HANDLE) else {
|
||||
return;
|
||||
};
|
||||
let mut mode = CONSOLE_MODE(0);
|
||||
if GetConsoleMode(handle, &mut mode).is_err() {
|
||||
return;
|
||||
}
|
||||
if mode.0 & ENABLE_WINDOW_INPUT.0 == 0 {
|
||||
let _ = SetConsoleMode(handle, mode | ENABLE_WINDOW_INPUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Re-establish terminal mode flags. Idempotent and best-effort: each
|
||||
/// underlying flag is silently discarded by terminals that don't support
|
||||
/// it, and a single flag's failure doesn't prevent later flags from being
|
||||
@@ -7066,6 +7102,9 @@ fn recover_terminal_modes<W: Write>(
|
||||
use_mouse_capture: bool,
|
||||
use_bracketed_paste: bool,
|
||||
) {
|
||||
#[cfg(target_os = "windows")]
|
||||
enable_windows_ime_console_mode();
|
||||
|
||||
push_keyboard_enhancement_flags(writer);
|
||||
if use_mouse_capture && let Err(err) = execute!(writer, EnableMouseCapture) {
|
||||
tracing::debug!(?err, "EnableMouseCapture ignored");
|
||||
|
||||
Reference in New Issue
Block a user