fix(picker): no layout or palette shift on the first frame - #56
Merged
Merged
Conversation
The Picker drew its first frame with dark false, so a dark terminal saw one washed-out frame — pale selected row, preview border bright enough to draw a box that then vanished — before tea.BackgroundColorMsg landed and repainted it. Dark is the safer assumption, and the one lipgloss makes when a terminal will not answer. themeSet went with it: it was written on the report and never read. Part of #55 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Bubble Tea reports the terminal background a frame or two in, so a light terminal still repainted itself on launch. Query it synchronously on the screen the Picker is about to draw on: lipgloss sends a device-attributes query alongside, so a terminal that ignores the background query ends this one promptly rather than waiting out the timeout. The asynchronous report stays as the correction for a query that goes unanswered. ttyProgramOptions became openScreen, which hands back the files as well as the options, and dropped an error it never returned. Part of #55 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Row statuses land one at a time with the Picker already on screen, and the column was sized to whichever of them had arrived: one column wide while the git fan-out was in flight, six once clusters like "✓ ? ↑1" came back, taking the names, the times and the preview's edge two columns right with it. Hold it at "✓ ? ↑1↓1" from the start; glyphs now fill a column that is already their size, and a wider cluster still grows it. Part of #55 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Measured against a terminal that answers neither the background query nor the device-attributes query alongside it: lipgloss waits out its own two-second timeout, and the Picker paints nothing at all until it expires. A two-second blank launch is a worse bug than the frame it was fixing. The next commit holds the first frame on a deadline of the Picker's own instead, which is bounded whatever the terminal does. Part of #55 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The terminal reports its background a frame or two into the Picker's life, so the frame drawn before it landed was repainted in the other palette right after: the flash on launch. Draw nothing until the report arrives, with a 50ms deadline of the Picker's own so a terminal that never answers gets the dark frame promptly rather than a blank screen. Measured in a pty that answers, one that answers late and one that stays silent: the first paint lands at ~0.1s in all three, against ~0.08s and a full light-palette repaint before. View tests now settle the palette through sizedModel, and the two tests that name the deadline message sit in the package. Closes #55 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #55.
Launching
cddpainted one frame in the light palette and with a one-column status gutter, then repainted it dark with the gutter at its real width — the flash in the screencast, ~50ms long.Palette.
Model.darkstartedfalseandtea.BackgroundColorMsgonly lands a frame or two in, so a dark terminal saw a washed-out frame, preview border box and all. The Picker now opens dark (as lipgloss assumes when a terminal will not answer) and draws nothing at all until the report lands, with a 50ms deadline of its own so a silent terminal is not left staring at a blank screen.A middle commit here queried the background synchronously with
lipgloss.HasDarkBackgroundbefore the program started, which is the tidier fix on paper. Measured against a terminal that answers neither that query nor the device-attributes query alongside it, lipgloss waits out its own two-second timeout and nothing is drawn until it expires, so it is reverted in favour of the Picker's own deadline. The commit and its revert are kept so the trade-off is on the record.Status column.
computeLayoutsized the column to whichever statuses had come back, so it grew from one column to six as the git fan-out returned, taking the names, the times and the preview's edge with it. It is now reserved at the width of✓ ? ↑1↓1from the first frame and still grows for anything wider.Verification
Driven under a pty that answers OSC 11 and DA1 like a real terminal, replayed through a terminal emulator frame by frame:
Every column sits at the same x from the first paint onwards; only the glyphs fill in. A terminal that answers late (0.4s) and one that never answers both paint at ~0.11s, dark.
go test ./...passes; the three new tests fail against the code they fix.🤖 Generated with Claude Code