fix(mobile): keep iOS terminal inputs on the default keyboard (#5876)

* fix(mobile): keep iOS terminal inputs on the default keyboard

iOS treated keyboardType="ascii-capable" as an ASCII-only input surface,
which hides non-Latin keyboards (Zhuyin, Japanese, Korean) from the iOS
keyboard switcher, so terminal users could not switch away from English.

Use the system default keyboard for terminal inputs on every platform so
IMEs stay selectable, while keeping autoCorrect/spellCheck off so commands,
flags, and paths are not rewritten by the OS keyboard. The keyboard-type
helpers now return a single 'default' value; their dead per-platform
branching was removed.

Fixes #5525.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(mobile): tighten terminal keyboard comment

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
audichuang
2026-06-22 13:24:43 -07:00
committed by GitHub
co-authored by Claude Opus 4.8 Orca Jinwoo-H
parent 338540bf73
commit 423c2befe1
4 changed files with 25 additions and 16 deletions
@@ -4899,8 +4899,6 @@ export default function SessionScreen() {
autoCorrect={autocompleteEnabled}
spellCheck={autocompleteEnabled}
smartInsertDelete={false}
// Why: Android's default keyboard is required for CJK IME
// composition; iOS can still use ASCII when autocomplete is off.
keyboardType={getTerminalCommandKeyboardType(
Platform.OS,
autocompleteEnabled
@@ -0,0 +1,14 @@
import { readFileSync } from 'node:fs'
import { describe, expect, it } from 'vitest'
const sessionRouteSource = readFileSync(
new URL('../../app/h/[hostId]/session/[worktreeId].tsx', import.meta.url),
'utf8'
)
describe('terminal iOS IME keyboard', () => {
it('does not force terminal inputs onto the ASCII-only iOS keyboard', () => {
expect(sessionRouteSource).not.toContain("'ascii-capable'")
expect(sessionRouteSource).not.toContain('"ascii-capable"')
})
})
@@ -14,9 +14,9 @@ describe('terminal keyboard type', () => {
expect(getTerminalCommandKeyboardType('android', true)).toBe('default')
})
it('keeps the iOS ASCII keyboard when terminal autocomplete is disabled', () => {
expect(getTerminalLiveInputKeyboardType('ios')).toBe('ascii-capable')
expect(getTerminalCommandKeyboardType('ios', false)).toBe('ascii-capable')
it('keeps iOS IME keyboards available for terminal input', () => {
expect(getTerminalLiveInputKeyboardType('ios')).toBe('default')
expect(getTerminalCommandKeyboardType('ios', false)).toBe('default')
expect(getTerminalCommandKeyboardType('ios', true)).toBe('default')
})
})
+8 -11
View File
@@ -1,20 +1,17 @@
export type TerminalKeyboardPlatform = 'android' | 'ios' | 'web' | 'windows' | 'macos'
export type TerminalKeyboardType = 'ascii-capable' | 'default'
export type TerminalKeyboardType = 'default'
// Why: default keyboards keep non-Latin IMEs selectable; ASCII-only keyboards hide them.
// Parameters stay for call-site stability while autocomplete no longer changes the keyboard.
export function getTerminalLiveInputKeyboardType(
platform: TerminalKeyboardPlatform
_platform: TerminalKeyboardPlatform
): TerminalKeyboardType {
// Why: Android CJK IMEs need the normal system keyboard; password-style
// input types suppress composition and break Chinese terminal input.
return platform === 'ios' ? 'ascii-capable' : 'default'
return 'default'
}
export function getTerminalCommandKeyboardType(
platform: TerminalKeyboardPlatform,
autocompleteEnabled: boolean
_platform: TerminalKeyboardPlatform,
_autocompleteEnabled: boolean
): TerminalKeyboardType {
if (autocompleteEnabled) {
return 'default'
}
return platform === 'ios' ? 'ascii-capable' : 'default'
return 'default'
}