# fix\(desktop\): show a starting splash instead of no window while the backend boots · PR \#23392 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/pull/23392)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

State: open

Source repository: Unavailable fork

Source branch: issue-watch/23372

Target branch: main

Head commit: 79185c4b5bbd5876ceaa96c490b14590b0d1cdf4

[Discussion and reviews](https://git.cafe/pingdotgg/t3code/pull/23392)

[Commits](https://git.cafe/pingdotgg/t3code/pull/23392/commits?format=markdown)

[Files changed](https://git.cafe/pingdotgg/t3code/pull/23392/diffs?format=markdown)

## Description

---

Unproven: Windows. No packaged Windows build was run with user state (the bar from the #19706 revert note). Linux and macOS were.

Refs #23372

## Problem

With the Local environment on, the desktop app makes no window until its backend answers the readiness check. In #23372 the backend took over 8 minutes after an update, and the app sat with no window at all. Clicking the Dock icon did nothing visible, so the only thing the user could do was quit.

## Fix

The first commit re-lands #19706 by @ronak-guliani. It was reverted in #22222 only because nobody had run it on a real desktop build. The revert note asked for a fresh PR from the original commit, with before/after proof on real builds that have user state. That code is unchanged apart from a hand-resolved test conflict with current `main`.

Before starting the local backend, the app now shows the small splash it already used for WSL-only setups. It says "Starting T3 Code…" (WSL-only still says "Connecting to WSL…"). The splash closes when the main window first shows. With the Local environment off, nothing changes.

The second commit covers two cases the splash opened up:
- Closing the splash (Cmd+W on macOS) while the backend was still starting left no window again, and the Dock couldn't bring one back. Activation now shows a new splash while waiting.
- A provider sign-in return link during startup navigated the splash, because it looked up "the main window or else the first window". It now only navigates the registered main window.

## Proof on real builds

Each run used a packaged build, a separate app profile, and a T3 home seeded with a trimmed copy of real user data (`migrate-dev-db`). To make the backend hang like in the issue, I froze its process (`SIGSTOP`) as soon as it spawned, launched the app again, then unfroze it. Every run except the macOS after run waited past the 60 s readiness timeout first; that one tested Cmd+W and reopen within 20 s. The main window is blurred because it shows real thread names.

**Linux AppImage on Xvfb, 4x speed.** Before (`main` at 3b95e7831b): nothing on screen for the whole wait, including after the timeout and the relaunch. The window only appears once the backend is unfrozen.

https://github.com/user-attachments/assets/0bb19e56-deb9-4392-a00a-0ba0d53a393e

After (this branch at 79185c4b5b): the splash shows at once, stays through the timeout and the relaunch, and hands off to the main window when the backend answers.

https://github.com/user-attachments/assets/1c208143-4291-4060-a33a-e607033de218

**macOS arm64 app.** Before (`main`): `list_windows` for the app's pid returned no windows for the whole wait and after `open`. The trace showed `desktop.lifecycle.activate` → `desktop.window.activate` with no window, the same spans as the issue. After (this branch at 79185c4b5b): the splash showed, Cmd+W closed it (`list_windows` returned no windows), and `open` brought a new splash back:

![mac-reopened-splash](https://github.com/user-attachments/assets/f6939ea8-83f9-4013-b545-2177104636e7)

Once the backend resumed, the main window replaced it.

<details><summary>Run transcript</summary>

```text
Linux, main 3b95e7831b
06:15:15  backend frozen at spawn; display empty
06:16:15  "Timed out after 60000ms waiting for desktop backend readiness"
06:16:41  second launch (activation); display still has no app window
06:16:56  backend resumed -> 06:16:58 main window 1100x780 appears

Linux, this branch 79185c4b5b
06:45:08  backend frozen at spawn; splash 360x220 on screen
06:46:10  after the 60 s timeout: second launch; splash still on screen
06:46:14  backend resumed -> main window 1100x780, splash gone

macOS, main 3b95e7831b
11:53:31  backend frozen; list_windows(pid) = []
11:54:34  after the timeout: open -> desktop.window.activate span; list_windows(pid) = []

macOS, this branch 79185c4b5b
12:16:45  backend frozen; splash window 360 wide
12:16:51  Cmd+W -> list_windows(pid) = []
12:16:59  open -> new splash window 360 wide
12:17:02  backend resumed -> 12:17:07 main window 1100 wide

Normal launch, Linux, first commit (not frozen):
06:19:26.369 connecting splash shown
06:19:28.233 backend ready
06:19:28.283 main window created
```

</details>

## Tests

- The startup test from #19706 fails on `main` for native and dual mode and passes here.
- New: closing the splash and then activating shows a new splash, not the main window. Fails without the `activate` change.
- The provider-return test now has the splash as the first window and checks it is never navigated. Fails without the Clerk change.
- `vp run check:changed` passes.

## Not fixed here

This does not explain why the backend's startup recovery held a write transaction open for 658 s in #23372. The issue's trace shows the transaction's own statements finished in under 0.1 s and it closed within seconds of `SIGTERM`, so it was waiting on something asynchronous rather than slow SQL. I couldn't reproduce that stall. The splash only makes the wait visible, so the backend part of the issue stays open.

Re-landed, fixed and verified with Claude Opus 5.5 in Claude Code; reviewed by GPT-6.1-Sol in Codex.

🤖 Generated with [Claude Code](https://claude.com/claude-code)


