Reveal the main window only after the splash has painted #38

Merged
parkerhdavis merged 1 commit from startup-flash-fix into main 2026-06-01 13:38:41 -06:00
parkerhdavis commented 2026-06-01 13:38:27 -06:00 (Migrated from github.com)

What

On launch the window was created visible, so the OS showed a run of ugly intermediate frames before the splash ever appeared: the unpainted webview (black + desktop bleed-through), the static index.html "Loading Garnet…" fallback, the live set_size resize in .setup(), then finally React's splash.

This creates the window hidden and reveals it from the frontend once React has committed the splash, so its first on-screen frame is the splash itself.

How

  • tauri.conf.json: window created with visible: false + backgroundColor set to the splash color (#0c0b09).
  • main.rs: new show_main_window command (idempotent), plus a 5s setup-side safety timer that reveals the window anyway if the frontend never calls.
  • App.tsx: reveal scheduled with setTimeout, not requestAnimationFrame — webkit2gtk doesn't service rAF while the window is hidden, so an rAF-gated reveal never fires (that bug made the splash play out entirely off-screen). The splash's minimum dwell is now anchored to the reveal moment, not React mount, so it always shows for its full duration. The error boundary also reveals the window so render failures still surface.
  • index.html: pre-paint background set to the splash color and the visible loading text dropped.

Testing

tsc, Biome, and cargo check all pass. Verified visually via make dev on Linux (webkit2gtk): the pre-splash frames are gone and the splash plays in full.

## What On launch the window was created visible, so the OS showed a run of ugly intermediate frames before the splash ever appeared: the unpainted webview (black + desktop bleed-through), the static `index.html` "Loading Garnet…" fallback, the live `set_size` resize in `.setup()`, then finally React's splash. This creates the window hidden and reveals it from the frontend once React has committed the splash, so its **first on-screen frame is the splash itself**. ## How - `tauri.conf.json`: window created with `visible: false` + `backgroundColor` set to the splash color (`#0c0b09`). - `main.rs`: new `show_main_window` command (idempotent), plus a 5s setup-side safety timer that reveals the window anyway if the frontend never calls. - `App.tsx`: reveal scheduled with `setTimeout`, **not** `requestAnimationFrame` — webkit2gtk doesn't service rAF while the window is hidden, so an rAF-gated reveal never fires (that bug made the splash play out entirely off-screen). The splash's minimum dwell is now anchored to the reveal moment, not React mount, so it always shows for its full duration. The error boundary also reveals the window so render failures still surface. - `index.html`: pre-paint background set to the splash color and the visible loading text dropped. ## Testing `tsc`, Biome, and `cargo check` all pass. Verified visually via `make dev` on Linux (webkit2gtk): the pre-splash frames are gone and the splash plays in full.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
parker/garnet!38
No description provided.