Files
LanMountainDesktop/.trae/specs/launcher-shell-hardening/spec.md
2026-05-12 16:46:49 +08:00

4.3 KiB
Raw Blame History

Launcher 外壳托管、托盘兜底与高分屏动画修复

背景

当前桌面应用在以下场景存在明显不稳定性:

  • 设置页或升级后的“重启”没有统一回到 Launcher。
  • 已有实例处于托盘时,再次启动容易误报“窗口未显示”,甚至重复拉起。
  • 托盘初始化失败或运行中丢失时,应用可能进入无恢复入口状态。
  • Launcher 和宿主的版本来源不一致,发布后容易出现 UI 版本错乱。
  • 高分屏和混合缩放环境下Launcher OOBE、主窗口入场和通知动画存在像素/DIP 混用问题。

目标

  • Launcher 成为正式环境唯一的启动与重启入口。
  • 进入 TrayOnly 前必须先确认托盘可恢复。
  • Launcher UI 显示的版本号等于应用版本号。
  • 发布工作流显式同步主程序、Launcher、manifest 和产物版本。
  • 动画和定位统一按 DIP 与缩放计算。

行为要求

1. 重启接管

  • 应用内重启、插件升级后的重启都必须优先回到 Launcher。
  • Launcher 对 SecondaryActivationSucceeded 只认定为一次成功重定向,不允许再做 fallback 二次拉起。
  • Launcher 启动成功判定区分三类场景:
    • 前台启动:DesktopVisibleActivationRedirected
    • 重启到最小化:BackgroundReady
    • 重启到托盘:TrayReady + BackgroundReady

2. 托盘硬约束

  • 托盘状态机必须至少覆盖:
    • Unavailable
    • Initializing
    • Ready
    • Recovering
    • Failed
  • HideMainWindowToTray、关闭到托盘、重启恢复到托盘前都必须先执行托盘就绪检查。
  • 如果托盘不可用:
    • 优先回退到任务栏最小化
    • 若任务栏入口也不可用,则强制恢复前台可见
  • 托盘处于隐藏态期间必须运行 watchdog连续恢复失败时自动恢复主窗口。

3. 版本来源

  • Launcher 只能显示应用版本,不能显示 Launcher 自身硬编码版本。
  • 版本解析优先顺序:
    • version.json
    • 主程序文件版本 / 信息版本
    • app-<version> 部署目录
  • Release 工作流必须显式打版本补丁,避免仓库默认占位值被误当成正式版本。

4. 高分屏动画

  • 主窗口、通知、Launcher OOBE 的动画位移必须使用 DIP 或基于缩放换算后的尺寸。
  • 不允许直接把 PixelRect 宽高当作 TranslateTransformDesiredSize 的输入。
  • 淡入和位移动画应并行执行,避免先淡入后滑动造成观感异常。

验收

  • 已在托盘中的实例再次通过 Launcher 启动时,只激活已有实例。
  • 设置页重启和插件升级重启后,不再出现“窗口未显示但后台已有多个进程”。
  • 托盘失败时应用仍保持可恢复。
  • Launcher 与应用设置页显示相同版本。
  • 100% / 150% / 200% / 250% 缩放下Launcher OOBE、主窗口入场、通知位置与动画正常。

5. Launcher IPC and error surface follow-up

  • The legacy LanMountainDesktop_Launcher named-pipe startup progress channel is retired. Public IPC notifications and host exit codes are the only startup state sources.
  • Normal Launcher launches must probe public IPC for an existing Host before starting a new Host process. Host no longer owns multi-instance policy, activation prompts, or the old single-instance pipe.
  • SecondaryActivationSucceeded is a success terminal state. SecondaryActivationFailed and RestartLockNotAcquired may surface as failures only after public IPC recovery has failed.
  • Launcher startup errors must use FluentAvalonia resources, Fluent icons, an InfoBar recovery hint, and copyable diagnostics instead of the old hard-coded dark panel.

6. Multi-instance behavior setting

  • App settings include MultiInstanceLaunchBehavior with default NotifyAndOpenDesktop.
  • General settings exposes the behavior under Basic Settings with four choices: restart app, open desktop silently, prompt only, and notify plus open desktop.
  • Launcher reads the Host settings.json before a normal launch and applies the selected behavior when public IPC reports an existing Host.
  • PromptOnly shows a Fluent Launcher prompt and does not open the desktop automatically.
  • NotifyAndOpenDesktop activates the existing Host and shows the already-running notice from Launcher.
  • RestartApp requests restart through public IPC and must not create a second Host if the restart request fails.