Files
StellarX-kaifa/开发记录/模块/Module-20260409-0001-Window托管重绘与覆盖合成机制.md
T

135 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 新增功能模块 / 模块重构
> 适用场景:新增模块、重大模块重构、核心架构能力演进。
> 不适用场景:小接口或轻量功能变更,请使用“功能变更”模板。
## 基本信息
- 模块 IDModule-20260409-0001
- 模块名称:Window 托管重绘与覆盖合成机制
- 状态:已完成 / 待持续回归
- 类型:架构演进
- 所属系统 / 子系统:Window / Control / Dialog 重绘链
- 版本 / 分支:`master`
- 环境:Windows + EasyX + VS2022
- 负责人:Codex 协作修改
## 背景与目标
- 背景:
- 初始框架以控件局部即时重绘为主,非模态对话框与底层控件重叠时,容易出现底层先画、对话框后补的层级问题。
- 当前痛点:
- 对话框遮挡下的 hover / click / tooltip / 分页等交互容易闪烁
- 底层控件和上层对话框在事件里分离绘制,顺序不可控
- 目标:
- 将“事件改状态”和“绘制提交”拆开,由 `Window` 在事件尾统一提交重绘。
- 非目标:[可选]
- 暂不做真正像素级脏区裁剪
- 暂不统一布局系统
## 模块边界
- 职责:
-`Window` 主循环里托管控件重绘请求
- 选择安全的重绘 root
- 在提交阶段维护普通控件与非模态 `Dialog` 的正确层级
- 不负责什么:
- 模态 `Dialog` 自己的内部事件循环
- 布局语义统一
- 字符集问题
- 外部依赖:
- EasyX 绘制接口
- 各控件自身的快照恢复能力
- 对外能力 / API:
- `Window::requestManagedRepaint(Control* source)`
- `Window::flushManagedRepaint()`
- `Control::getManagedRepaintRoot()`
- `Control::commitManagedRepaint()`
- 关键数据 / 状态:
- `managedDispatchActive`
- `managedSceneDirty`
- `managedRepaintItems`
## 设计说明
- 核心流程:
1. `Window::runEventLoop()` 开始输入分发前,进入 `managedDispatchActive = true`
2. 控件在 `handleEvent()` 中只改状态并通过 `requestRepaint()` 上报
3. `Window::requestManagedRepaint(source)` 把 source 转换成 `root + coverage`
4. 事件收口时 `flushManagedRepaint()` 按层级提交 root
5. 最后补画和脏区相交的非模态 `Dialog`
- 关键对象 / 类关系:
- `Window`:重绘调度中心
- `Control`:提供宿主窗口回溯与 root 选择语义
- `Canvas / TabControl / Dialog`:作为安全重绘 root 的主要容器
- 生命周期:
- 托管重绘项只存在于当前分发轮次
- `clearManagedRepaintState()` 在 flush、resize 收口、对话框开关后的整场景重绘后清空
- 事件 / 渲染 / 数据流:
- 事件:Dialog 优先,普通控件其次
- 渲染:受影响普通 root 先画,Dialog 后补
- 数据流:leaf control -> requestRepaint -> Window registry -> flush
- 关键不变量:
- 分发期不直接提交托管重绘
- 顶层普通控件的提交顺序必须服从 `Window::controls` 的 z-order
- 对话框始终绘制在普通控件之上
- 降级 / 回退策略:[可选]
- `resize`、对话框打开/关闭等全局变化仍走整场景重绘
## 实现与影响
- 关键实现点:
- `Control` 增加 `hostWindow``getManagedRepaintRoot()``commitManagedRepaint()`
- `Window` 增加 `ManagedRepaintItem` 队列
- `Canvas / TabControl / Dialog` 提供局部可提交与升级为整 root 重画的判断
- 涉及文件 / 类 / 函数:
- `Window.h / Window.cpp`
- `Control.h / Control.cpp`
- `Canvas.h / Canvas.cpp`
- `TabControl.h / TabControl.cpp`
- `Dialog.h / Dialog.cpp`
- 兼容性影响:
- 行为层面更严格,底层控件不再依赖旧的“即时局部重绘”副作用
- 性能影响:
- 相比整场景重绘更细
- 相比纯即时局部重绘更稳定
- 在全局变化场景仍保留整场景兜底
- 风险点:
- root 选择错误会导致局部重绘不完整
- 嵌套容器组合场景需持续回归
## 测试与验证
- 测试范围:
- 非模态遮挡下的按钮 hover / click
- `Canvas / TabControl / Table` 组合场景
- 模态与非模态对话框 coexist 场景
- 验证步骤:
1. 编译 `Control / Canvas / TabControl / Dialog / Window` 相关源文件。
2. 回归 `KEY == 2 / 3 / 4` 的对话框与遮挡场景。
3. 检查对话框关闭、resize、hover 清理和局部重绘顺序。
- 验证结果:
- 第二阶段架构已落地,核心编译通过,主问题链路已被压住。
- 已知限制 / 遗留问题:[可选]
- 快速划过多个按钮时偶发一帧双高亮,当前接受为底层限制
- 仍未推进到真正像素级脏区裁剪
## 落地信息
- 关联功能变更 ID[可选]
- `Feature-20260409-0002`
- `Feature-20260409-0003`
- 关联 BUG / Fix[可选]
- `BUG-20260409-0001`
- `Fix-BUG-20260409-0001`
- Commit:
- `b07a4ec`
- `77a8fe5`
- 当前工作区未提交阶段
- PR[可选]
- 发布版本:[可选]
- 相关文档:[可选]
- `00-修改总览-20260409.md`