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.
This commit is contained in:
Neil
2026-08-17 21:23:26 -07:00
parent b9e59c8537
commit 2ae1e05df5
2 changed files with 10 additions and 2 deletions
@@ -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)
})
})
@@ -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<string, string> }