#1400·mosh

Display::new_frame 的滚动检测可能在无法区分的空行上产生假阳性,从而破坏客户端显示状态

作者: joshw创建于 2026年7月23日更新于 2026年9月4日

□ 总结

’Display:: new frame ()' 的"屏幕刚刚滚动了吗?" 快速路径 ( " src/terminal/terminaldisplay.cc " ,大致为166-250行)可能会误向 完全普通的重新绘制,从未滚动过,导致摩什客户端 以虚假金额和错误内容滚动真实终端 在错误的行上。 腐败不是一面之花: 内部行记错误, 并保持错误—— 内容上 受影响的行在后续的 diff 上被跳过—— 直到一个无关的后补全 屏幕清空正好重设它。

以1.4.0摩什为单位复制: 和本地回路会话(关于 同样的机器)—— 两种结果相同,所以这不是网络刺激 具体,只是写作时间 具体(见"为什么分割事项") 页:1 相同的字节流在真实 pty 下直接重放( 无) mosh)或通过从擦出 VT100 模拟器 [`Charmbracelet/x/vt'](https://GitHub.com/Charmbracelet/x/tree/master/vt)] (中文(简体) ). 每次都是错的

□ 根源

在逐行分解前, “ new frame( ) ” 尝试快速路径: 新路径是否 帧行 0 匹配一些行 “ K ” 在先前播放的相框中吗 ? 如果是的话, 它假设屏幕被 " K " 行滚动, 显示真实的滚动区域 + n " 排序到实体终端,并重新索引自己的账簿 (`rows.at(一) =行.at(i + K)'),而不是通常对这些行进行分解:

翻译: 为(一行=0;一行 < f.ds.get height ();一行++){ 相接行 * 新行 = f. get row( 0) ; 缩放行 * 旧行 = QQrows.at(行); 如果! (新出自"新出自"旧出自"新出自"新出自"旧出自"新出自"新出自"旧出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自"新出自""新出自"新出自"新出自"新出自"新出自"新出自". 继续; {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? 如果(行==0){断开;} 行 滚动=行; 滚动 高=1; / *... 扩展滚动 高度, 而后续行也匹配... */


匹配测试是指针身份, 或 ('Row: operator') 一代
计数器加单元格内容。 仍然空白的行,因为这些行
从未 * 单独 * 写到(新建、改型或生产)
改为“插入-行”/“删除-行”——所有这些字段都来自
a 共享的“ Row” 对象;见“ Framebuffer:: newrow () ” 及其调用者在
`terminalframebuffer.cc')是字面上相同的物体,所以它们微不足道。
满足此检查 。 循环取取 * 第 1 *行( 从上方扫描)
匹配,没有最小区域面积,没有排除
仍然未触摸到的填充行,因此无法区分“实际上这些内容”
从"0"和"K"两行都碰巧还是
空白,出于无关的原因。" 一个屏幕,一个以上的无法区分
空白区域——在内容稀少的任何TUI中极为常见(空地)
回滚, 空状态区域等) —— 足以产生假
相匹配的。 匹配的。

一旦起火 摩什就用一个
与发生的事情不符的金额,并重新索引
它自己的"什么在屏幕上"模式来匹配——所以它现在相信行
. . . . . . .

内容来源: mobile-shell/mosh