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

4.8 KiB
Raw Blame History

新增功能模块 / 模块重构

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

基本信息

  • 模块 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 增加 hostWindowgetManagedRepaintRoot()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