已关闭
fix(tuix): inflight 重绘改走 cell-diff, 消除光标闪烁 #1104
郑育强创建于 9月21日关闭于 6 天前
fix(tuix): inflight 重绘改走 cell-diff, 消除光标闪烁 #1104
已关闭
当前Pull Request已关闭, 关闭人@郑育强
atomgit-bot
9月21日 评论:
9月21日 评论:
变更摘要
本 PR 修复了工具调用进行中时 TUI 光标闪烁的问题。根因是 render_inflight_tool 的 in-place 分支在更新模型之外,还直接向终端裸写 \x1b[{r};1H\x1b[2K 加行内容,绕过了 render_diff 的 DECSET 2026 同步帧与光标隐藏,导致物理光标滞留在 Running 行尾,在高延迟链路上以约 10Hz 在 Running 行与输入框之间乒乓闪烁。修复方式是让 in-place 分支只做模型更新(body_lines 替换、sentinel invalidate_rows_from、dirty),重绘统一交由 cell-diff 在同步帧内完成,与 live spinner 路径 push_or_update_live_spinner 保持一致,并补充回归测试。
主要改动
- 移除 inflight in-place 分支的终端裸写: 删除了逐行
\x1b[{r};1H\x1b[2K与serialize_row的直写循环,避免绕过屏幕模型与 DECSET 2026 同步帧。 - in-place 分支改为纯模型更新 + sentinel 失效: 仅替换
body_lines尾部切片并触发invalidate_rows_from,由后续flush_deferred经 cell-diff 在同步帧内重绘,保持帧原子化。 - 新增回归测试: 新增
retained_inflight_inplace_rewrite_stays_inside_sync_envelope,断言 inflight tick 输出不再包含裸写签名\x1b[2K,同时校验 Running 行仍正常重绘。


不准确?
atomgit-bot
9月21日 评论:
9月21日 评论:
atomgit-bot
9月21日 评论:
9月21日 评论:
郑育强
6 天前 评论:
6 天前 评论:
关闭说明: 本 MR 修复的 render_inflight_tool in-place 裸写路径已随 atomcode-tuix 整体退役 (f465a43ec) 从 main 删除, 目标文件 crates/atomcode-tuix/src/render/retained.rs 在上游已不存在, 冲突形态为 modify/delete。
对替代实现 crates/atomcode-tui 的核查结论: 不存在同类问题, 无需迁移重做。
- 渲染路径上没有任何裸写 \x1b[2K 的 in-place 更新 (仅测试断言与终端能力探测使用该序列);
- DECSET 2026 同步帧是新架构的不变量: SYNC_BEGIN/SYNC_END 包裹整帧, 且有测试 a_frame_is_one_synchronized_update 守护;
- spinner/运行状态行走同一帧 diff 路径 (ansi.rs 按行 diff, 文档以"两帧只差一个 spinner 行"为典型用例), 不存在绕过同步帧的第二通道。
旧 bug 的成因通道 (在同步帧外裸写导致物理光标滞留) 已被新架构从设计上消除, 本修复无迁移价值, 故关闭。


问题
工具调用进行中(如长 bash 命令), TUI 的 Running liveness 行每 ~100ms 重绘。实测(本机与高延迟链路均可复现)可见光标在 Running 行尾与输入框之间以 ~10Hz 乒乓闪烁。
根因:
render_inflight_tool的 in-place 分支在更新模型之外, 还直接向终端裸写\x1b[{r};1H\x1b[2K+ 行内容(retained.rs)。这段裸写:render_diff的 DECSET 2026 同步帧与?25l光标隐藏;live spinner 此前已修复过同款问题(
push_or_update_live_spinner, 改走 cell-diff), inflight 路径是它遗漏的孪生分支。修复
in-place 分支只做模型更新(
body_lines替换 + sentinelinvalidate_rows_from+dirty), 重绘统一由 cell-diff 在 DECSET 2026 同步帧内完成。sentinel 本就强制 strip 每格出 patch, 裸写删除后视觉无损失; 唯一差异是重绘推迟到 ≤5ms 的合并帧, 不可感知。验证
retained_inflight_inplace_rewrite_stays_inside_sync_envelope: 断言 inflight tick 输出不再出现裸写签名\x1b[2K(该序列全仓仅裸写路径使用), 且 Running 行仍正常重绘 —— 修复前红、修复后绿cargo test -p atomcode-tuix: 2134 通过; 3 个失败(dir_picker ×2、kitty_keyboard ×1)经 stash 基线对照确认是 main 上已有的环境相关失败, 与本改动无关cargo fmt --all -- --check通过已知未验证范围