Stop sampling a live animation in the dropdown fixed-point checks - #14
Merged
Merged
Conversation
`Tests (Cargo.toml profile) (macos-latest)` went red on master with a menu measured 158px tall where the line before had measured 157, on a commit that changed no Rust. The profile was innocent too: the cause is the wall clock. The panel is wrapped in `entering_zoom(Motion::POPOVER_IN)`, which reproduces v3's `zoom-in-90` by growing the panel's own vertical padding from 90% to 100% over 150ms, so the menu is a different height on every frame while it runs. gpui drives a oneshot `Animation` from `scheduler::Instant` -- the real clock -- and neither `run_until_parked` nor `advance_clock` moves it, so `settle` never settled the zoom. It sampled it wherever the clock happened to be. Locally the test finishes inside 10ms and every sample lands at 157; a runner that stalls about 50ms between two samples gets 157 and then 158. Injecting a 30ms stall into the unmodified test reproduces the CI assertion exactly, origin and all. So there is no geometry defect: the resting panel is a fixed point at 158px, and the height change is the animation doing its job. What was wrong is that assertions about the positioner were reading a surface that was still moving, and passing on timing luck. Every host in the file now opens with the entry zoom off through the public `MenuStyle` theme default -- the same switch an application would use, and the motionless layout is the animated resting layout. The fixed-point samples are now taken across 30ms of real time, which strengthens them: they mean "nothing moves on its own" rather than "nothing moved within a microsecond". No assertion was loosened, ignored or profile-gated. `the_entry_zoom_lands_on_the_motionless_layout` keeps the stock theme, waits the zoom out, and pins both halves -- a finished zoom is a fixed point, and it converges on exactly the motionless layout. Mutation-tested both ways: leaving the zoom running fails 8 tests deterministically, and a `POPOVER_IN` that never settles fails the new one with the original 158-against-157. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
6 tasks
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.
Fixes master's red
Tests (Cargo.toml profile) (macos-latest)job.Root cause: the wall clock, not the profile
The job failed with a menu measured
220px × 158pxwhere the line before measured220px × 157px, same origin — on a commit (8e64c0c2) that changed no.rs, no manifest and no toolchain, and after the same job had passed twice on identical Rust.The Dropdown panel is wrapped in
entering_zoom(Motion::POPOVER_IN), which reproduces v3'szoom-in-90by growing the panel's own vertical padding from 90% to 100% over 150ms (anim::ZoomBox::panel). Content is 146.2px, so the layout height runs 157.0 → 158.2px and crosses the rounding boundary ~50ms after the menu opens.gpui drives a oneshot
Animationfromscheduler::Instant— the real wall clock. Neitherrun_until_parkednorexecutor().advance_clock()moves it, sosettle()never settled the zoom; it sampled it wherever the clock happened to be. Locally the test finishes in ~10ms and every sample lands at 157. A runner that stalls ~50ms between two samples gets 157 then 158.Reproduced deterministically: injecting a 30ms stall into the unmodified test reproduces the CI assertion exactly, origin and all. A 25ms stall also takes down
an_open_submenu_is_its_own_popover_and_stays_inside(86 vs 85) — same latent bug, second assertion.There is no geometry defect
The resting panel is a true fixed point at 158px, and the height change is the animation doing its job. What was wrong is that assertions about the positioner were reading a surface that was still moving, and passing on timing luck.
MenuStyletheme default — the same switch an application would use.Dropdowncomposes itsMenuinternally and never sets the instance flag, so the theme is the correct lever. No source change, no new API, and the motionless layout is the animated resting layout (verified 220×158 both ways).assert_eq!is untouched. Nothing is ignored, loosened, or profile-gated.the_entry_zoom_lands_on_the_motionless_layoutkeeps the stock theme, waits the zoom out, and pins both halves: a finished zoom is a fixed point across real-time gaps, and it converges on exactly the motionless layout.Mutation-tested both directions
POPOVER_IN.msbumped so the zoom never settles → the new test fails with the original158 vs 157.Verification
run-tests.sh --workspace --locked0 (113/113) · the same with the failing job's knobsCARGO_PROFILE_DEV_DEBUG=0 CARGO_PROFILE_DEV_CODEGEN_UNITS=160 (113/113) ·dropdown_viewport_deep19/19, three consecutive runs under those knobs · clippy-D warnings0 · fmt 0 ·gpui_patches --check0 · inventory 0 · coverage 0 · all parity audits 0.Separate defect found, deliberately not fixed here
Reduced motion changes the menu's layout: with motion
220 × 158, withreduce_motion443 × 110.anim::pressedreturns the row untouched under reduced motion, so thew_fullpress slot disappears; with the slot present its percentage width contributes nothing to aMaxContentmeasurement and the panel collapses tomin_w220, wrapping the descriptions. The reduced-motion figure is the one matching the pinned CSS, so the normal path is the wrong one. Blast radius is everypressed()control's intrinsic width — worth its own change.🤖 Generated with Claude Code