From 2ae1e05df511aee52f9e853ef15a117ba60f4b5f Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Mon, 17 Aug 2026 21:23:26 -0700 Subject: [PATCH] fix(terminal): require more than one touch point before skipping the forwarder The gate used maxTouchPoints > 0, which is looser than the idiom already in this repo. isIOSWebView in mobile/src/terminal/terminal-webview-html.ts requires more than one, because a Mac with a touch-capable peripheral can report exactly one, and such a Mac must keep the forwarder: it is a real Mac running the input method this workaround exists for. Under the old threshold that Mac silently lost native text substitution - a macOS regression introduced by a fix aimed at iPadOS. A captured iPad reports five, so the stricter bound costs nothing on the device this targets. The check stays user-agent based rather than adopting that helper's platform check, because an iPhone reports platform "iPhone" rather than "MacIntel" and would slip through. --- .../terminal-pane/use-terminal-pane-lifecycle.test.ts | 6 ++++++ .../components/terminal-pane/use-terminal-pane-lifecycle.ts | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/renderer/src/components/terminal-pane/use-terminal-pane-lifecycle.test.ts b/src/renderer/src/components/terminal-pane/use-terminal-pane-lifecycle.test.ts index 54e87d693bf..8e18ece6f2e 100644 --- a/src/renderer/src/components/terminal-pane/use-terminal-pane-lifecycle.test.ts +++ b/src/renderer/src/components/terminal-pane/use-terminal-pane-lifecycle.test.ts @@ -579,4 +579,10 @@ describe('isTouchIOSUserAgent', () => { isTouchIOSUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 5) ).toBe(false) }) + + it('keeps the forwarder on a Mac whose touch peripheral reports a single point', () => { + expect( + isTouchIOSUserAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15', 1) + ).toBe(false) + }) }) diff --git a/src/renderer/src/components/terminal-pane/use-terminal-pane-lifecycle.ts b/src/renderer/src/components/terminal-pane/use-terminal-pane-lifecycle.ts index 41ff4202534..a61b9ad131f 100644 --- a/src/renderer/src/components/terminal-pane/use-terminal-pane-lifecycle.ts +++ b/src/renderer/src/components/terminal-pane/use-terminal-pane-lifecycle.ts @@ -451,9 +451,11 @@ export function resolvePaneSeedCwd(splitPaneCwd: string | undefined, fallbackCwd return splitPaneCwd ?? fallbackCwd } -/** iPadOS reports a desktop "Macintosh" UA and iOS reports "like Mac OS X" — maxTouchPoints is the only signal a real Mac never sets. */ +// Why > 1, matching isIOSWebView in mobile/src/terminal/terminal-webview-html.ts: a Mac with a +// touch peripheral can report exactly 1, and it must keep the forwarder. Real iPads report 5. +// Why UA rather than that helper's platform check: an iPhone reports platform "iPhone", not "MacIntel". export function isTouchIOSUserAgent(userAgent: string, maxTouchPoints: number): boolean { - return userAgent.includes('Mac') && maxTouchPoints > 0 + return userAgent.includes('Mac') && maxTouchPoints > 1 } type SplitStartupPayload = { command: string; env?: Record }