From 2bc1724c2dae72184a5d2ec070e30c70dc519f9b Mon Sep 17 00:00:00 2001 From: ppggff Date: Sun, 5 Jul 2026 08:25:47 +0800 Subject: fix: switch prefix ASCII input source on the foreground client (#1016) * fix: switch prefix ASCII input source on the foreground client The macOS prefix ASCII-switch ran in the headless server, whose TISCopyCurrentKeyboardInputSource read is a stale per-process cache (refreshed only via a main-run-loop notification the server never pumps), so prefix could leave the terminal on the wrong input source. Forward it to the foreground client, like clipboard: sync_prefix_input_source emits AppEvent::PrefixInputSource as an intent; the server forwards it to the foreground client and the monolithic app applies it in-process via RealPrefixInputSource, which pumps its main run loop before the stale TIS read. Key it on Mode::wants_ascii_input so multi-level prefix commands keep ASCII until returning to the terminal, and restore the IME for rename text entry. Adds ServerMessage::PrefixInputSource to the already-unreleased protocol 15. refs #774 * fix: keep prefix input-source switch out of the headless server process An App-internal drain (the exhaustive drain at the top of handle_api_request, reachable from prefix-key runtime mutations) can consume a queued PrefixInputSource intent before the server's forwarding drain sees it, applying the TIS switch in the headless server process and stranding the restore state. Gate the in-process switch on App.local_input_source_switch, disabled by the headless server alongside the other local side effects, so a swallowed intent degrades to a skipped switch. Widen the forwarding-bypass maintenance test to the handle_internal_event_with_prefix_sync wrapper. refs #774 * docs: clarify prefix input-source comments and flag docs refs #774 * fix: bump protocol for prefix input source refs #774 --------- Co-authored-by: Ogulcan Celik --- src/app/api.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/app/api.rs') diff --git a/src/app/api.rs b/src/app/api.rs index 96c34393..9ebbbe56 100644 --- a/src/app/api.rs +++ b/src/app/api.rs @@ -67,6 +67,22 @@ impl App { return; } + if let AppEvent::PrefixInputSource { active } = ev { + // Monolithic path applies the switch here. Server mode forwards it to the foreground + // client instead (see HeadlessServer::handle_internal_event_with_forwarding); should an + // App-internal drain consume the event before the forwarding drain, the flag keeps the + // switch out of the headless server process. + if !self.local_input_source_switch { + return; + } + if active { + self.prefix_input_source.switch_to_ascii(); + } else { + self.prefix_input_source.restore(); + } + return; + } + if let AppEvent::GitStatusRefreshed { results, cache_updates, -- cgit v1.2.3