Files
nyaterm/docs/window-chrome.md
T
Kang 9f4a710be6 feat(window-chrome): introduce window chrome management and drag behavior
- Added a new module `window_chrome` to manage window decorations and controls based on platform-specific behavior.
- Implemented `WindowChrome` struct to encapsulate window control logic, including minimize, maximize, and close button visibility.
- Enhanced title drag functionality with `TitleDragEvent` and `TitleDragBehavior` to support platform-specific dragging behavior.
- Updated various components to utilize the new window chrome management, ensuring consistent behavior across different window types.
- Added tests for window chrome functionality to validate behavior across platforms.
2026-10-27 11:55:01 +08:00

4.4 KiB
Raw Blame History

窗口装饰与标题栏交互

所有权与平台边界

nyaterm-desktop::window_chrome 根据 GPUI 窗口的实际装饰、按钮能力、 可缩放/可最小化标记、最大化、全屏及 Sheet 类型派生展示策略。 这些信息只在渲染时读取,不另存可修改的窗口装饰状态。

nyaterm-ui::window_chrome 提供按钮和标题栏拖动区域;desktop 回调继续负责 关闭确认、会话处理、主窗口拖动活动标记及现有 Windows 子窗口恢复修正。 主窗口、锁屏标题栏和公共子窗口标题栏使用同一策略。

Linux 主窗口及 ChildWindowSpec 子窗口请求 CSD,子窗口同时提供实际标题。 如果平台实际返回 SSD,顶部应用内容保留,自绘窗口按钮隐藏。按钮还受窗口 能力和窗口标记约束;全屏隐藏常规按钮,最大化时绘制恢复图标。 Windows 主窗口保留原生 caption hit testing,子窗口保留显式点击回调。 主窗口的最大化/恢复完整交给 Windows 原生处理;GPUI 的 Windows zoom() 仅执行最大化,不能用它替代原生恢复。其他按钮消费点击后由应用回调执行一次, 保留最小化到托盘和关闭确认;子窗口继续使用既有显式恢复修正。 macOS 保留原生按钮、拖动和双击偏好,Sheet 不添加按钮留白或拖动区域。

Linux 拖动

每个标题区域使用所属窗口的 GPUI keyed state。左键按下记录位置,移动距离 超过 4 个逻辑像素后只派发一次系统移动操作。按下后使用窗口级移动监听, 因此快速移出标题区域仍能启动拖动;监听通过无绘制、无命中区域的 canvas 在 paint 阶段注册,不增加装饰外框。

释放、区域外释放、再次在区域外按下、丢失左键状态及平台 pointer cancel 清除待拖动状态。未开始拖动的双击在释放时只派发一次最大化/恢复,且需要 窗口可缩放、平台支持最大化并处于非全屏状态。按钮、菜单及输入控件消费 按下事件,避免标题区域同时处理该次交互。

外框与几何

nya_root() 继续是唯一外框入口,加载、运行和关闭阶段都复用 gpui-kit Root 插件提供的 CSD 边框、阴影、inset 和边缘/四角缩放。窗口位置继续通过 inner_window_bounds() 保存,不把阴影尺寸写入恢复数据。

本次保留按钮顺序、尺寸和方角风格,不增加 SSD/布局配置,不改变持久化格式 或依赖 revision,不修改 temp/vendor/。

验证记录(2026-10-27)

  • 纯策略测试覆盖实际 CSD/SSD、窗口标记、平台能力、最大化、全屏和 macOS Sheet。
  • GPUI/状态测试覆盖 4px 阈值、只启动一次、跨区域移动、释放/取消、双击、 多窗口隔离、按钮单次回调、输入焦点和菜单打开。
  • cargo check --workspace -j 1:通过。
  • cargo test -p nyaterm-ui window_chrome --lib -j 1:最终 9 项通过,包含 Windows 原生最大化事件放行与应用按钮回调单次派发。
  • cargo fmt --all -- --check:通过。
  • 最终 cargo test --workspace -j 1 -- --test-threads=1:4355 项通过, 30 项按既有配置忽略,无失败。
  • 最终 cargo check --workspace -j 1、cargo clippy --workspace --all-targets -j 1:通过。
  • 追加 UI/desktop 并行回归中代理网络测试的非阻塞 socket 曾报 WouldBlock, 最终完整串行测试中该测试通过。
  • 最终 cargo build -p nyaterm-app --bin nyaterm -j 1:通过。
  • Windows 实机(独立 portable 数据目录):主窗口最小化/重新激活、关闭、 按钮最大化/恢复、拖动、标题栏双击均通过。设置子窗口拖动、按钮最大化/恢复、 标题栏双击最大化/恢复、关闭按钮、Ctrl+W 关闭与回到主窗口均通过。 模态设置窗口正确隐藏最小化按钮;主窗口重启后位置和尺寸保持一致。
  • 首次默认并发 workspace test 构建发生内存分配失败,改用 -j 1 重试。
  • Ubuntu WSLg:现有 Rust/Cargo 1.75 不支持 workspace resolver 3,Linux 构建 在解析 manifest 时失败,尚未进入运行验收。
  • GNOME/KDE 原生会话及 macOS:未验证。

Linux 实机待核对:边缘和四角缩放、光标、不可缩放窗口、模态与多窗口; 仅一层 CSD 外框;多次重启恢复尺寸不累积阴影。Windows 尚未逐一验收全部 子窗口类型;本次实机子窗口样本为设置窗口。