From f5e66b251fa8ec24989bf25861bcf4e38a561470 Mon Sep 17 00:00:00 2001 From: sf-jin-ku Date: Wed, 3 Jun 2026 09:13:01 -0700 Subject: feat: switch input source during prefix mode (#434) On macOS, opt-in under [experimental], temporarily switch the host input source to the current ASCII-capable layout while prefix mode is active so prefix commands register even when a CJK IME is composing, then restore the previous input source when prefix mode exits or is cancelled. No-op when the current source is already ASCII-capable, on non-macOS platforms, or when any input source call fails. Pane text input is unaffected. Also pin next_resize_poll in next_loop_deadline_includes_selection_autoscroll_deadline so the selection autoscroll deadline stays the earliest; the default resize poll could otherwise beat it and flake the assertion. refs #400 Co-authored-by: Can Celik --- src/platform/mod.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'src/platform/mod.rs') diff --git a/src/platform/mod.rs b/src/platform/mod.rs index a836ed81..12c275f0 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -96,6 +96,49 @@ mod fallback; #[cfg(not(any(target_os = "linux", target_os = "macos")))] pub use fallback::*; +#[cfg(not(target_os = "macos"))] +#[derive(Debug)] +pub(crate) struct InputSourceRestore; + +#[cfg(not(target_os = "macos"))] +pub(crate) fn switch_to_ascii_input_source() -> Option { + None +} + +/// Switches the host keyboard input source while prefix mode is active. +/// +/// `App` drives this through a trait so the prefix-mode transitions can be +/// tested with a fake, without touching the real macOS APIs or leaking a +/// platform-specific restore type into `App`. +pub(crate) trait PrefixInputSource { + /// Switch to an ASCII-capable input source for prefix commands. No-op if + /// the current source is already ASCII-capable, the platform is + /// unsupported, or the switch fails. Calling it again before `restore` + /// keeps the source saved by the first call. + fn switch_to_ascii(&mut self); + + /// Restore whatever `switch_to_ascii` saved. No-op if nothing was switched. + fn restore(&mut self); +} + +/// Production [`PrefixInputSource`] backed by the per-platform API. +#[derive(Default)] +pub(crate) struct RealPrefixInputSource { + restore: Option, +} + +impl PrefixInputSource for RealPrefixInputSource { + fn switch_to_ascii(&mut self) { + if self.restore.is_none() { + self.restore = switch_to_ascii_input_source(); + } + } + + fn restore(&mut self) { + let _ = self.restore.take(); + } +} + #[cfg(test)] mod tests { use super::*; -- cgit v1.2.3