Files
LanMountainDesktop/.trae/specs/window-slide-transition/spec.md
lincube e20462ac2b Make settings window independent and taskbar-aware
Convert the settings window into an independent top-level window with its own taskbar icon and open-or-focus semantics. Removed Owner/anchor/toggle semantics from SettingsWindowService and added ScreenReferenceWindow for centering; settings windows now ShowInTaskbar = true and are truly destroyed on close. Added SettingsWindowPlacementHelper and tests for placement/centering. Main window now respects an AppSettingsSnapshot.ShowInTaskbar flag (new setting exposed in GeneralSettings UI) and slide/visibility animations and "back to Windows" behavior no longer affect the independent settings window. Updated various callers to use OpenIndependentSettingsModule, adjusted window transitions/X offsets, and added/updated spec files documenting the feature and animation boundary.
2026-04-22 20:46:43 +08:00

7.0 KiB
Raw Blame History

窗口过渡动画 Spec

Why

当前全屏窗口在"回到 Windows"(最小化)和"恢复应用"时存在严重的视觉问题:

  1. 恢复时经历 Minimized → Normal → FullScreen 两步跳变,用户会短暂看到无框小窗口
  2. 状态切换无任何过渡动画,体验生硬
  3. OnWindowPropertyChanged 使用 Dispatcher.UIThread.Post 延迟纠正,进一步延长了 Normal 中间态的可见时间

What Changes

  • MainWindow.axamlDesktopPage 上添加 TranslateTransformTranslateTransform.X 过渡动画
  • 修改 MainWindow.axaml.csOnMinimizeClick,实现退场动画(滑出/淡出 → 最小化)
  • 修改 App.axaml.csRestoreOrCreateMainWindow,实现入场动画(全屏 → 滑入/淡入)
  • 修改 MainWindow.axaml.csOnWindowPropertyChanged,在动画期间暂停强制全屏逻辑
  • AppSettingsSnapshot 中添加 EnableSlideTransition 设置项(默认关闭)
  • GeneralSettingsPageViewModel 中添加对应 ViewModel 属性
  • GeneralSettingsPage.axaml 中添加开关 UI仅 Windows 平台显示)
  • 添加平台检测逻辑Windows 且开启设置时使用滑入滑出,其他情况使用 Opacity 淡入淡出

Impact

  • Affected specs: 窗口生命周期过渡动画
  • Affected code:
    • LanMountainDesktop/Views/MainWindow.axaml - DesktopPage 添加 TranslateTransform
    • LanMountainDesktop/Views/MainWindow.axaml.cs - OnMinimizeClick、OnWindowPropertyChanged、新增动画方法
    • LanMountainDesktop/App.axaml.cs - RestoreOrCreateMainWindow、OnMainWindowPropertyChanged
    • LanMountainDesktop/Models/AppSettingsSnapshot.cs - 新增 EnableSlideTransition 字段
    • LanMountainDesktop/ViewModels/SettingsViewModels.cs - GeneralSettingsPageViewModel 新增属性
    • LanMountainDesktop/Views/SettingsPages/GeneralSettingsPage.axaml - 新增开关 UI

ADDED Requirements

Requirement: 窗口退场过渡动画

系统 SHALL 在主窗口最小化/隐藏时播放退场过渡动画,消除窗口状态跳变的视觉闪烁。

Scenario: Opacity 淡出退场(所有平台默认)

  • WHEN 用户点击"回到 Windows"或触发最小化
  • THEN 系统将 DesktopPage.Opacity 设为 0触发淡出动画
  • AND THEN 动画完成后执行 WindowState = Minimized
  • AND THEN 最小化完成后重置 DesktopPage.Opacity = 1(窗口已不可见)

Scenario: 滑出退场Windows + 开启设置)

  • WHEN 用户点击"回到 Windows"且运行在 Windows 平台且已开启滑入滑出设置
  • THEN 系统同时将 DesktopPage.Opacity 设为 0 且 DesktopPageSlideTransform.X 设为屏幕宽度
  • AND THEN 动画完成后执行 WindowState = Minimized
  • AND THEN 最小化完成后重置 DesktopPageSlideTransform.X = 0DesktopPage.Opacity = 1

Requirement: 窗口入场过渡动画

系统 SHALL 在主窗口恢复时播放入场过渡动画,消除 Normal 中间态的视觉闪烁。

Scenario: Opacity 淡入入场(所有平台默认)

  • WHEN 主窗口从最小化/隐藏状态恢复
  • THEN 系统先将 DesktopPage.Opacity 设为 0遮住 Normal 中间态)
  • AND THEN 完成 Minimized → Normal → FullScreen 状态切换
  • AND THEN 等 FullScreen 状态生效后将 DesktopPage.Opacity 设为 1触发淡入动画

Scenario: 滑入入场Windows + 开启设置)

  • WHEN 主窗口从最小化/隐藏状态恢复且运行在 Windows 平台且已开启滑入滑出设置
  • THEN 系统先将 DesktopPage.Opacity 设为 0 且 DesktopPageSlideTransform.X 设为屏幕宽度
  • AND THEN 完成 Minimized → Normal → FullScreen 状态切换
  • AND THEN 等 FullScreen 状态生效后同时将 DesktopPage.Opacity 设为 1 且 DesktopPageSlideTransform.X 设为 0触发滑入+淡入组合动画

Requirement: 动画期间交互保护

系统 SHALL 在过渡动画播放期间防止用户交互和状态冲突。

Scenario: 动画期间禁止交互

  • WHEN 退场或入场动画正在播放
  • THEN DesktopPage.IsHitTestVisible 设为 false
  • AND THEN 动画完成后恢复为 true

Scenario: 动画期间暂停强制全屏

  • WHEN 入场动画正在播放且窗口临时处于 Normal 状态
  • THEN OnWindowPropertyChanged 不执行强制全屏纠正
  • AND THEN 入场动画完成后恢复正常强制全屏逻辑

Scenario: 防止快速连续操作

  • WHEN 用户在动画播放期间再次触发最小化或恢复
  • THEN 系统忽略重复操作,避免动画冲突

Requirement: 滑入滑出设置项

系统 SHALL 在基本设置页面提供"滑入滑出过渡效果"开关,仅 Windows 平台可见。

Scenario: 设置项可见性

  • WHEN 用户在 Windows 平台打开基本设置页面
  • THEN 显示"滑入滑出过渡效果"开关
  • WHEN 用户在非 Windows 平台打开基本设置页面
  • THEN 不显示该开关

Scenario: 设置项默认值

  • WHEN 用户首次安装应用
  • THEN EnableSlideTransition 默认为 false

Scenario: 设置持久化

  • WHEN 用户切换"滑入滑出过渡效果"开关
  • THEN 设置值立即持久化到 AppSettingsSnapshot.EnableSlideTransition
  • AND THEN 下次窗口过渡时立即生效,无需重启

Requirement: DesktopPage TranslateTransform 声明

系统 SHALL 在 DesktopPage 上声明 TranslateTransform 和对应的过渡动画。

Scenario: XAML 声明

  • WHEN MainWindow 初始化
  • THEN DesktopPage 拥有名为 DesktopPageSlideTransformTranslateTransform
  • AND THEN DesktopPage.Transitions 包含 OpacityTranslateTransform.X 两个过渡
  • AND THEN 过渡时长使用 FluttermotionToken.Duration.Page320msFluttermotionToken.Duration.Intro400ms
  • AND THEN 缓动函数使用 0.05,0.75,0.10,1.00DecelerateBezier

Requirement: 设置窗口不参与桌面壳过渡动画

系统 SHALL 将桌面壳进出场动画限制在主窗口范围内,不影响独立设置窗口。

Scenario: 设置窗口在桌面动画期间保持独立

  • WHEN 主窗口执行滑入、滑出、最小化或恢复动画
  • THEN 设置窗口不参与该动画
  • AND THEN 设置窗口不会跟随主窗口一起隐藏、最小化或重定位

MODIFIED Requirements

Requirement: OnMinimizeClick 行为

当前: 直接设置 WindowState = WindowState.Minimized,无动画

修改后: 先播放退场动画,动画完成后再设置 WindowState = WindowState.Minimized

Requirement: RestoreOrCreateMainWindow 行为

当前: Show() → Normal → FullScreen,无过渡动画,用户可见 Normal 中间态

修改后: 先将 DesktopPage 设为不可见Opacity=0 + 可选滑出位),再执行状态切换,最后播放入场动画

Requirement: OnWindowPropertyChanged 强制全屏逻辑

当前: 任何非 Minimized/FullScreen 状态立即纠正为 FullScreen

修改后: 动画期间允许临时 Normal 状态存在,动画完成后恢复强制全屏逻辑

REMOVED Requirements

无移除的需求。