Files
StellarX-kaifa/开发记录/Fix/Fix-BUG-20260409-0001-对话框重绘快照与遮挡交互异常.md

94 lines
3.5 KiB
Markdown
Raw Permalink 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.
# Fix-BUG-20260409-0001
> 适用场景:记录某个 BUG 的修复方案、影响评估、验证结果与落地信息。
## 关联信息
- Fix ID: Fix-BUG-20260409-0001
- 关联 BUG ID: BUG-20260409-0001
- 修复目标: 收紧对话框快照、遮挡、事件分发和统一提交重绘链
- 状态:已完成 / 待持续回归
- 负责人:Codex 协作修改
- 分支 / 版本:`master`
## 根因分析
- 根因:
- 旧实现中“作废快照”和“回贴旧背景”混在一起,resize 时容易把旧画面贴回屏幕。
- 非模态对话框与底层控件之间缺少明确的事件阻断和 hover 清理机制。
- 重绘长期依赖控件即时局部绘制,导致底层先画、对话框后补,容易闪烁或层级错乱。
- 标题曾作为独立 `Label` 存在,导致额外一层背景快照,时序敏感。
- 触发条件:
- 非模态遮挡下的 hover / click
- 模态或非模态 resize
- 对话框打开 / 关闭
- 为什么之前没发现:
- 问题主要集中在“高频交互 + 对话框遮挡 + resize”组合路径
## 修复方案
- 修复思路:
- 拆分快照语义
- 收紧对话框事件消费
-`Dialog` 在窗口变化时只重新居中
- 将标题绘制并入 `Dialog`
- 把重绘推进到窗口统一收口
- 关键改动:
- `discardBackground()``invalidateBackgroundSnapshot()` 分离
- `Dialog` 标题改为直接绘制,不再使用独立 `Label`
- `Dialog::handleEvent()` 对自身区域内鼠标事件统一吞掉
- 对话框关闭及遮挡场景补发合成 `WM_MOUSEMOVE`,清理底层 hover
- `Window` 引入托管重绘,先重绘受影响 root,再补画相交对话框
- 涉及文件 / 类 / 函数:
- `Window.h / Window.cpp`
- `Dialog.h / Dialog.cpp`
- `Control.h / Control.cpp`
- `Canvas.cpp`
- `TabControl.cpp`
- `Button.cpp`
- `TextBox.cpp`
- 影响的 API / 行为:
- `Dialog` 在窗口变化时的语义固定为“只重新居中,不拉伸”
- 非模态对话框覆盖区域内不再允许鼠标事件穿透到底层
- 关键约束 / 不变量:
- 对话框始终绘制在普通控件之上
- 托管分发期间控件不直接提交绘制
- resize 和对话框开关仍走整场景重绘兜底
## 影响评估
- 影响范围:
- 所有包含 `Dialog`、按钮 hover、遮挡重绘的场景
- 兼容性影响:有(行为更严格,底层控件不再穿透响应)
- 行为变化:有(对话框 resize 只居中;遮挡区域 hover 不再透传)
- 性能影响:有正向变化(减少无意义整场景补画);同时在某些兜底场景仍保留整场景重绘
- 回归风险:
- 托管重绘 root 选择不当可能导致嵌套容器局部重绘异常
- 需持续回归 `Canvas / TabControl / Table / Dialog` 组合场景
## 验证结果
- 验证步骤:
1.`KEY == 2 / 4` 中打开非模态对话框,快速在遮挡区域附近 hover 和点击。
2.`KEY == 3 / 4` 中打开模态对话框并拖动窗口大小。
3. 关闭对话框后观察底层按钮 hover 恢复。
- 验证结果:
- 穿透、残影、关闭后 hover 不恢复等主问题已压住。
- 回归检查:
- 保留对“快速划过多个按钮时偶发一帧双高亮”的已知限制记录。
- 验证证据:
- 静态推演 + 多轮编译验证 + 用户回归反馈
## 落地信息
- Commit:
- `4a6e153`
- `7f8431a`
- `b07a4ec`
- 当前工作区未提交阶段
- PR[可选]
- 发布版本:[可选]
- 备注:该修复跨多个阶段逐步收敛,不是一次性完成