Files
StellarX-kaifa/开发记录/Fix/Fix-BUG-20260109-0002-TabControl切换后Table新旧内容重叠.md

4.3 KiB
Raw Permalink Blame History

Fix-BUG-20260109-0002

适用场景:记录某个 BUG 的修复方案、影响评估、验证结果与落地信息。

关联信息

  • Fix ID: Fix-BUG-20260109-0002
  • 关联 BUG ID: BUG-20260109-0002
  • 修复目标: 修复 TabControl 页签切换与 Table 重置数据后出现的新旧内容像素叠加,确保快照机制不被污染。
  • 状态:已完成
  • 负责人: 未记录
  • 分支 / 版本: master / v3.0.0

根因分析

  • 根因: Control::setIsVisible(true) 立即向上 requestRepaint(),导致页签切换 / 关闭过程中,父容器可能处于 hasSnap=0、dirty=1 或刚 discardBackground() 的快照未就绪状态。此时 Canvas::requestRepaint(partial) 直接对子控件 Table 调用 draw(),随后 saveBackground() 又把已经包含旧表格像素的屏幕区域截入快照,形成背景快照污染。
  • 触发条件: 切换到按钮1页签 -> 重置表格数据 -> 切换 / 关闭其他页签 -> 再切回按钮1;或重置数据当次容器快照未就绪时触发局部重绘。
  • 为什么之前没发现:[可选] 历史版本 setIsVisible(true) 不会立即 requestRepaint();常规交互未必同时满足页签切换 / 表格重置 / Null 填充 / 透明文字背景的组合条件。
  • 关键证据:[可选] 日志中出现 Canvas 丢弃快照后,Table show=1 立即触发局部重绘,随后保存 Table 背景快照。

修复方案

  • 修复思路: 回退 show=true 立即请求重绘的行为,并为 Canvas / TabControl 的局部重绘增加快照就绪护栏;当容器快照未就绪或 dirty 未清理时,禁止 partial fast-path,降级为 full draw。
  • 关键改动:
    • Control::setIsVisible() 中 show=true 时不再立即 requestRepaint(),改为仅置脏;show=false 保持擦除逻辑。
    • Canvas::requestRepaint() 增加护栏,dirty / 无快照 / 无缓存图时将 partial 降级为 full draw。
    • TabControl::requestRepaint() 同步增加局部重绘护栏。
    • 可选修正 Table::setData(vector<string>) 列补齐 off-by-one,降低潜在越界或异常噪声。
  • 涉及文件 / 类 / 函数:
    • Control.cpp
    • Canvas.cpp
    • TabControl.cpp
    • Table::setData()(可选)
  • 影响的 API / 行为:[可选] 对外 API 不变;显示时序与局部重绘降级策略发生内部调整。
  • 关键约束 / 不变量:[可选]
    • 局部重绘前,父容器必须持有有效快照且不处于 dirty 未清理状态。
    • setIsVisible(true) 不得在快照未就绪阶段触发子控件抢跑绘制。
  • 回滚点 / 开关:[可选] 回退 visible 置脏与 partial 降级护栏。

影响评估

  • 影响范围: TabControl 页签切换、Canvas 局部重绘、Table 数据重置、背景快照捕获。
  • 兼容性影响:无 API 变化;若外部依赖 show=true 即刻刷新,需要确保后续绘制收口会触发重绘。
  • 行为变化:有(快照未就绪时局部重绘降级为全量重绘)
  • 性能影响:在快照未就绪阶段单次重绘成本增加;稳定交互阶段仍保留局部重绘路径。
  • 回归风险:
    • 降级条件过宽可能导致频繁全量重绘。
    • 显示状态更新后,如果外部没有触发任何重绘,可能存在视觉延迟。
    • 程序化页签激活流程可能受重绘时序影响,需要回归。

验证结果

  • 验证步骤:
  1. 按稳定复现路径:按钮1 -> 重置表格数据 -> 切换 / 关闭其他页签 -> 切回按钮1,重复 50 次以上。
  2. 在按钮1停留时连续快速点击重置 100 次,并穿插页签切换、窗口最小化 / 恢复、拖拽 / resize。
  3. 反复对 Table / Canvas 调用 setIsVisible(false / true),确认隐藏擦除正确、显示后无残影。
  4. 分别在 TableFillMode 为 Null 与非 Null 模式下验证。
  • 验证结果: PDF 历史记录标记已修复。
  • 回归检查:[可选] TabControl 切换 / 关闭 / 重复打开、Canvas 添加 / 移除控件与 resize、Table clearData / setData / 翻页、全局窗口 resize / 最小化恢复。
  • 验证证据:[可选] PDF 记录中关联 QQ202619-144430.mp4。

落地信息

  • Commit: 5cb59b3652
  • PR:[可选] git 推送
  • 发布版本: v3.0.0
  • 备注: 来源原始 Fix 记录未包含 -XXXX 后缀,入库时按 BUG ID 补充为 Fix-BUG-20260109-0002。