Fix Codex held-key input batching (#4732)

This commit is contained in:
Jinwoo Hong
2026-06-06 00:16:40 -04:00
committed by GitHub
parent 3e23f287a8
commit 2f7fe087a2
2 changed files with 50 additions and 3 deletions
@@ -298,7 +298,7 @@ describe('pane terminal output scheduler', () => {
stripTransientCursorShows: true
})
vi.advanceTimersByTime(31)
vi.advanceTimersByTime(15)
expect(terminal.write).not.toHaveBeenCalled()
vi.advanceTimersByTime(1)
@@ -328,7 +328,7 @@ describe('pane terminal output scheduler', () => {
coalesceForeground: true
})
vi.advanceTimersByTime(31)
vi.advanceTimersByTime(15)
expect(terminal.write).not.toHaveBeenCalled()
vi.advanceTimersByTime(1)
@@ -340,6 +340,51 @@ describe('pane terminal output scheduler', () => {
)
})
it('does not batch repeated latency-sensitive synchronized frames across key-repeat ticks', async () => {
vi.useFakeTimers()
const { writeTerminalOutput } = await loadScheduler()
const terminal = createTerminal()
writeTerminalOutput(terminal, '\x1b[?2026h\x1b[0 q\x1b[?25l\x1b[19;3Hx\x1b[?25h', {
foreground: true,
latencySensitive: true,
stripTransientCursorShows: true,
holdForeground: true
})
writeTerminalOutput(terminal, '\x1b[?2026l', {
foreground: true,
latencySensitive: true,
stripTransientCursorShows: true,
coalesceForeground: true
})
vi.advanceTimersByTime(16)
vi.runOnlyPendingTimers()
expect(terminal.write).toHaveBeenCalledTimes(1)
writeTerminalOutput(terminal, '\x1b[?2026h\x1b[0 q\x1b[?25l\x1b[19;4Hx\x1b[?25h', {
foreground: true,
latencySensitive: true,
stripTransientCursorShows: true,
holdForeground: true
})
writeTerminalOutput(terminal, '\x1b[?2026l', {
foreground: true,
latencySensitive: true,
stripTransientCursorShows: true,
coalesceForeground: true
})
vi.advanceTimersByTime(16)
vi.runOnlyPendingTimers()
expect(terminal.write).toHaveBeenCalledTimes(2)
expect(terminal.write.mock.calls.map(([data]) => data)).toEqual([
'\x1b[?2026h\x1b[0 q\x1b[?25l\x1b[19;3Hx\x1b[?25h\x1b[?2026l',
'\x1b[?2026h\x1b[0 q\x1b[?25l\x1b[19;4Hx\x1b[?25h\x1b[?2026l'
])
})
it('keeps transient cursor shows unless the caller opts into stripping', async () => {
vi.useFakeTimers()
const { writeTerminalOutput } = await loadScheduler()
@@ -71,7 +71,9 @@ const MAX_BACKGROUND_QUEUE_CHUNKS = 4096
const PARSE_SETTLE_TIMEOUT_MS = 250
const FOREGROUND_COALESCE_DELAY_MS = 1000
const FOREGROUND_HOLD_SAFETY_DELAY_MS = 250
const LATENCY_SENSITIVE_FOREGROUND_COALESCE_DELAY_MS = 32
// Why: key repeat can tick every 30-50ms; one frame catches split restores
// without batching multiple typed-character redraws behind the fallback.
const LATENCY_SENSITIVE_FOREGROUND_COALESCE_DELAY_MS = 16
const LATENCY_SENSITIVE_FOREGROUND_HOLD_SAFETY_DELAY_MS = 32
const CURSOR_SHOW_SEQUENCE = '\x1b[?25h'
const CURSOR_HIDE_SEQUENCE = '\x1b[?25l'