Skip to content

feat: render input at once instead of on the next frame tick - #1858

Draft
rajasatyajit wants to merge 1 commit into
charmbracelet:mainfrom
rajasatyajit:feat/render-input-immediately
Draft

rajasatyajit wants to merge 1 commit into
charmbracelet:mainfrom
rajasatyajit:feat/render-input-immediately

Conversation

@rajasatyajit

Copy link
Copy Markdown

Part of #1857.

What. After Update and View for user input (KeyPressMsg, KeyReleaseMsg, paste messages and mouse messages), the event loop signals the renderer goroutine through a 1-slot channel (renderNow) to flush immediately. Before, the flush waited for the next frame tick. All other messages still render on the ticker, so output from Send and streaming and timers is rate-limited exactly as before.

Why. At 60 fps a keystroke waits on average about 8 ms (up to 16.7 ms) before its echo is written. In a real 120×40 app we measured 13.1 ms median keystroke-to-echo.

Before / after. TestInputRendersBeforeNextFrame sets WithFPS(1), waits for a frame, types a key and requires its frame within 250 ms:

  • main: fails 3/3, "the key's frame took 999.9ms".
  • this branch: passes 3/3.
  • If isInputMsg returns false (a broken guard), it fails again with 1.0 s.

Notes.

  • A burst of input coalesces into one pending flush; the channel has 1 slot and the send doesn't block.
  • go test -race ./... passes, golangci-lint run reports 0 issues, and the examples build.

Draft until you've had a chance to say whether you want this (see #1857). The companion change that diffs only changed lines is a separate PR.

🤖 Generated with Claude Code

https://claude.ai/code/session_01VP3Hm2sePM6PrVZDNpxJ7R

The renderer flushes only on its frame ticker (60 fps by default), so the
frame for a key press waits for the next tick: up to 16.7 ms, 8.3 ms on
average, plus the flush. After Update and View for user input (keys,
paste, mouse), the event loop now asks the renderer to flush at once.
Everything else still renders on the tick, so streaming output and timers
are rate-limited as before.

TestInputRendersBeforeNextFrame: at 1 fps, a key typed just after a frame
is now written within 250 ms; before, it waited for the next tick (1.0 s).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VP3Hm2sePM6PrVZDNpxJ7R
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant