Skip to content

长截图:改用系统画面流(第一阶段),离线重放工具与真机验收 - #24

Merged
Cocoon-break merged 14 commits into
mainfrom
feat/long-shot-auto
Nov 1, 2026
Merged

Cocoon-break merged 14 commits into
mainfrom
feat/long-shot-auto

Conversation

@Cocoon-break

Copy link
Copy Markdown
Owner

设计:docs/specs/2026-11-01-长截图自动滚动-设计.md(第 6 节阶段 0、1);计划:docs/plans/2026-11-01-长截图画面流.md。规格说明 v0.1.42(M23 规则 13)。

改动

  • 排查工具:stitch_replay 离线重放(cargo run -p xpaste-core --example stitch_replay -- <帧目录>),真实帧回归测试(xPaste README 网页,22 帧,2.0 MB);开发构建 XPASTE_LONG_DUMP=<目录> 逐帧存图。
  • 区域画面流(平台层 stream.rs):只留最新一帧的槽位;macOS 用 ScreenCaptureKit(排除边框窗口,sRGB);Windows 11(build ≥ 20348)用 Windows.Graphics.Capture(关黄框,分辨率变化时中断);Windows 10 与启动失败退回每 40 ms 逐帧截屏。
  • 长截图改用画面流:画面不动时不算没接上;停手后没接上满 3 秒照样提示“这里一直接不上”;画面流中断按完成收尾;各退出路径先收边框与回车/Esc 快捷键再停流。
  • 真机验收后的优化:PNG 快速压缩(release 下 2818 × 3872 编码 1845 → 86 ms);近似比对缓存上一帧的边缘(终端帧平均 29.5 → 9.2 ms);选区较矮时提示慢一点滚。

验证

  • make check 通过(含 Windows 交叉 clippy)。
  • 每个任务都经过独立审查,最后整分支审查;结论与取舍记在验收记录与设计第 8 节。
  • macOS 真机(开发构建,四次长截图):都走画面流;带背景图的终端 92 帧没接上 10(改动前同类场景 215 帧没接上 109),文字连续;Chrome 正常滚 759 帧没接上 60(只在一次甩动时),长图 1738 × 9012;回车、Esc 立即生效。详见验收记录“长截图画面流”。

还没做的

  • Windows 代码只经交叉编译,没在实机上跑过;本 PR 的 Windows CI 是它第一次编译运行。实机步骤见验收记录(待用户)。
  • 停手 3 秒后的“这里一直接不上”提示真机上没留意到,仅有单元测试。
  • 选区很矮又甩得快时手动滚动跟不上,留给第二阶段自动滚动。

🤖 Generated with Claude Code

Cocoon-break and others added 14 commits November 1, 2026 18:15
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
M23 规则 13:start_native_stream 的 macOS 实现放在 macos_stream.rs。
SCContentFilter 排除边框窗口;sourceRect 为选区,宽高 round(w×scale)、
round(h×scale),最多 60 帧/秒,BGRA、sRGB、不带光标;只收状态为
complete 的帧,BGRA 转 RGBA 后放进最新一帧槽位;didStopWithError 置失败;
停止闭包等 stopCapture 回调,上限 CALLBACK_WAIT。

录屏的取可录制内容、找显示器与排除窗口抽成 content_filter,
ns_err、wait_done、CMSampleBufferGetImageBuffer 改为两处共用。

颜色比对(2 倍屏,主屏 (100,100,200,120) 点,静止画面,400×240):
与 capture_rect 逐通道最大差 3,差 ≤ 2 的占 99.8%(差 3 的 694 个通道),
两边各自做 sRGB 转换的舍入差;不设 sRGB 时最大差 10。同一次长截图的帧
都来自画面流,不影响拼接。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 新增 windows_stream.rs:按显示器创建采集项,自由线程帧池(BGRA8,2 个缓冲),
  关掉黄色边框与光标;每帧在 GPU 上按选区裁到暂存纹理、读回转 RGBA 放进槽位。
  选区取 AreaOptions::native 减显示器左上角,取整与 capture_rect 相同,输出尺寸一致。
  build < 20348、选区跨屏、采集尺寸与显示器矩形不符或任一步失败时返回 Err,回退逐帧截屏(M23 规则 13)
- windows.rs:抽出 monitors()(freeze_displays 共用,下标即显示器序号),新增 windows_build()(RtlGetVersion)
- 跨平台的带行补齐 BGRA → RGBA 移到 stream.rs,macOS 与 Windows 共用
- 集成测试 area_stream_matches_capture_rect 放开到 Windows:按系统版本断言模式,CI 上截不到只跳过

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 帧池缓冲尺寸固定,分辨率或缩放中途变了只能从 ContentSize 看出:与开始时的显示器尺寸不符就结束画面流
- 离上次处理的帧不到 16 ms 的帧取出后直接丢掉,Windows 11 24H2 之前也不超过 60 帧/秒(M23 规则 13)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
WGC 只在画面变化时送帧,滚动停下前的最后一帧丢了就不会再来;24H2 之前按屏幕刷新率送帧,
槽位只留最新一帧不积压(设计文档第 7 节允许“60 或屏幕刷新率”,M23 规则 13)。保留 SetMinUpdateInterval 与 ContentSize 检查。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 截屏线程从 start_area_stream 取帧,去掉 40 ms 定时截屏;等帧最多 100 ms,回车、Esc 及时生效
- 画面不变时画面流不出帧:不算没接上、状态不变;第一帧等不到新帧时沿用上一帧判断画面稳定
- 画面流中途断了按完成收尾,保留已拼好的部分
- 进度按 should_emit 节流:状态变化立即发,高度变化至少隔 100 ms,不变时每秒补发
- 开发构建设 XPASTE_LONG_DUMP 时后台线程逐帧存 PNG,结束时等写完
- 完成日志带画面流模式、帧数与平均处理耗时(M23 规则 13)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
画面流在画面不变时不出帧,停住不滚时状态一直停在“没接上”。空闲时按 lost_since 计时,满 STUCK 改为 stuck(M23 规则 13)。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
真机验收后的优化:release 下 2818 × 3872 编码 1845 → 86 ms;终端帧重放平均每帧 29.5 → 9.2 ms,
结果不变;选区矮于 250 逻辑像素时提示“选区较矮,慢一点滚”。验收记录补上 macOS 真机结果。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Cocoon-break
Cocoon-break merged commit dd03776 into main Nov 1, 2026
2 checks passed
@Cocoon-break
Cocoon-break deleted the feat/long-shot-auto branch November 1, 2026 14:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant