Files
LanMountainDesktop/.trae/specs/launcher-shell-hardening/startup-visuals-addendum.md
lincube 33591a0a63 Add startup visual modes and attempt registry
Implement startup visual behavior, de-duplicate startup attempts, and improve failure UX.

Key changes:
- Add spec and docs for startup visuals and timing contract (.trae/specs and docs/LAUNCHER_STARTUP_VISUALS.md).
- Introduce StartupVisualPreferences contract and resolver; create SplashWindow via resolved mode.
- Add StartupAttemptRecord model and a file-backed StartupAttemptRegistry to persist and coordinate in-progress startup attempts (attach/adopt, soft/hard timeouts, IPC/connect state, lifecycle updates).
- Update LauncherFlowCoordinator to: adopt/attach to existing attempts, track IPC connection and soft/hard timeouts (30s/120s), show delayed UI state, attempt foreground recovery via public IPC, compose detailed launch result metadata, and mark registry states (soft timeout, detached waiting, succeeded, failed).
- Add TryActivateExistingInstanceAsync to attempt activating an existing desktop via IPC.
- Change failure flow: ShowFailureWindowAsync now returns user choice; ErrorWindow updated to present Activate/Wait/Open Logs/Exit semantics and new layouts/styles; improved button wiring and debug/dev mode handling.
- Add UI and resource tweaks (ErrorWindow and SplashWindow changes), project asset link for nightly logo, and unit tests for StartupVisualPreferences.

These changes prevent duplicate desktop processes during slow startups, provide clearer UX for delayed startups, and persist startup attempt state across Launcher invocations for safer recovery/attach behavior.
2026-04-23 09:03:35 +08:00

1.4 KiB

Launcher Slow-Startup And Startup Visual Addendum

New startup timing contract

  • 30s is a soft timeout, not a failure threshold.
  • After 30s, if the desktop process is still alive or Public IPC is connected, Launcher must stay in a waiting state and must not start another host process.
  • 120s is the hard timeout.
  • Before returning desktop_not_visible, Launcher must attempt one foreground recovery through ActivateMainWindowAsync().

Startup attempt de-duplication

  • Launcher persists the current startup attempt in %LocalAppData%\LanMountainDesktop\.launcher\state\startup-attempt.json.
  • A second Launcher process must attach to a live pending attempt instead of calling Process.Start() again.
  • Closing the splash window does not cancel startup; it transitions the attempt into detached waiting and preserves recovery state for the next Launcher run.

Startup visual modes

  • EnableSlideTransition = true forces StartupVisualMode.SlideSplash and automatically disables fade.
  • EnableSlideTransition = false && EnableFadeTransition = false resolves to StartupVisualMode.StaticSplash.
  • EnableSlideTransition = false && EnableFadeTransition = true resolves to StartupVisualMode.Fade.

UX safeguards

  • If the host process is still alive at failure time, the failure dialog must prefer:
    • Activate
    • Wait
    • Open Logs
    • Exit
  • Retry is only valid when Launcher is not about to create a duplicate desktop process.