# 新增功能模块 / 模块重构

> 适用场景：新增模块、重大模块重构、核心架构能力演进。
> 不适用场景：小接口或轻量功能变更，请使用“功能变更”模板。

## 基本信息

- 模块 ID：Module-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`
