Files
ELY-Browser/crates/ely_app
ZacharyZhang-NY 8aa9ddaeb2 fix(shell): debounce viewport resize so animations stop flashing
Sidebar / window-edge animations emit a new viewport bounds on every
GPUI paint. The previous flow fired `runtime.ensure_tab` synchronously
on every change, which reached down into Servo's surfman backend and
destroyed + reallocated the rendering framebuffer 50+ times per second
— each cycle leaving the NSView with an empty surface until Servo's
next paint completed. The user saw the page strobe blank-then-content
on every gesture, plus a one-time Metal driver warning about an
unloadable texture (the previous framebuffer caught mid-recreate).

Track `viewport_size_changed_at` on `PerTabSurface` and propagate the
debounce on two seams:

- `record_viewport_size` returns `Buffered` for a transition that
  arrives inside the 80 ms window of the previous one, so the
  synchronous `flush_external_web_surface_tick` from the GPUI paint
  callback skips the resize altogether. The very first measurement
  and the first transition after a quiet period still return `Applied`
  so a single drag step or page-load is not delayed.
- `ensure_surface` skips while the viewport is settling, but only
  *after* the initial ensure has installed `last_ensure_key`. The
  first ensure must fire even mid-gesture or the page never loads.
- `next_tick_delay` clamps the poll cadence to `ACTIVE_POLL_INTERVAL`
  while any visible tab is settling, so the trailing-edge resize
  fires within a frame of the gesture stopping instead of waiting
  for an 80 ms idle tick.

The synchronous `record + ensure` pattern in
`failed_surface_ensure_waits_for_a_new_key_before_retrying` can't
advance an `Instant`, so it now calls a `#[cfg(test)]`
`clear_viewport_resize_debounce_for_test` to simulate the
trailing edge and exercise the retry-on-new-key business rule in
isolation. Adds `rapid_viewport_changes_buffer_until_gesture_settles`
to lock the new behaviour.
2026-05-18 14:53:56 -04:00
..
2026-05-18 13:58:36 -04:00