当 Wayland 没有滚动截屏,我用 AI 写了一个

Wayland 生态里找不到滚动截屏工具怎么办?与其等别人填坑,不如让 AI 帮忙写一个。wayscrollshot 是一个用 Rust 实现的 Wayland 原生滚动截屏工具,内置五种拼接算法,已发布到 AUR。本文记录了从发现生态位缺口到完成开源贡献的全过程。

缺失的拼图

切换到 Wayland 之后,一切都很美好。输入延迟更低、动画更流畅、每个窗口都有自己的独立缓冲区。直到某天需要截取一张长长的网页,才意识到——Wayland 下没有滚动截屏软件。

这就像搬进了一间设计精良的新公寓,却发现少了一扇门。

X11 时代有 Flameshot 的滚动截屏插件,有各种成熟的方案。Wayland 的安全模型把每个窗口隔离开来,那些 X11 下靠抓取全局屏幕再按像素比对偏移量的工具全部失效。这个生态位,就这么空置了数年。

AI 时代的补位逻辑

放在两年前,面对这个缺口,要么用回 X11,要么等着上游慢慢实现。但现在不一样了。

AI 辅助开发已经成熟到可以正经干活的程度——不是生成玩具 Demo,而是写出可以上生产环境的工具。复杂的需求拆解、架构设计、性能优化、跨库绑定、CI/CD 配置,AI 都能参与其中。过去缺位软件只能等开发者贡献,现在自己就可以是那个开发者。

这种模式有个天然的好处:你做的是解决自己真实痛点的事。不会出现"功能做了一堆但核心体验稀烂"的情况,因为你就是第一个用户。

方案选型:从零开始,而不是修修补补

调研后发现有几个相近的项目。screenshot-splicing 用 Python 实现,但需要额外的屏幕录制步骤,体验不够原生。snow-shot 用 Rust 重写了一版,但已经停更,而且只支持单显示器。

与其在别人的代码基础上缝缝补补,不如从零开始,吃透底层原理再动手。选了 Rust 作为语言——需要直接操作 Wayland 协议、处理图像数据、做计算机视觉计算,这些用 C/C++ 太费劲,用 Python 性能不够,Rust 正好卡在两者之间。

怎么判断两张图有没有重叠?

这是整个项目的核心难题。用户在屏幕某个区域滚动,每一帧和上一帧的内容有部分重叠但不是完全一样。怎么找到新内容从哪一行开始?

第一种思路是列采样——从图像左中右三个位置取几列灰度值做滑动比对,计算平均绝对差值。简单粗暴,在纯色背景的终端页面表现不错,但遇到内容复杂的网页就频频失配。

第二种思路是模板匹配——从新帧顶部切一小块当模板,在老帧里逐像素滑动找最佳匹配位置。准确度比列采样高不少,但计算量也大,而且如果背景有重复图案就容易误判。

第三种是边缘检测——在列采样的基础上用垂直梯度替换灰度值,对终端背景透明或渐变场景更鲁棒。

第四种FAST 角点 + 近似最近邻搜索是实验性质的——提取两帧的 FAST 角点,构建描述子,用 HNSW 索引做匹配。理论上应该更好,但实际对帧间相似度的要求太高,稍有变化就崩。

最后转向了计算机视觉领域的标准答案:ORB 特征 + RANSAC 仿射估计。检测 ORB 特征点,用暴力匹配加 Lowe 比值检验过滤错误匹配对,再用 RANSAC 估计仿射变换矩阵。OpenCV 的 Rust 绑定虽然有点重,但准确度碾压其他方案。

超过 80% 重叠加低特征帧的场景还不够——专门加了一条宽松重试路径和基于 NCC 模板匹配的回退链,三层保险。

Wayland 的原生界面

拼接算法只是内核,用户交互同样重要。用 wlr-layer-shell 协议做了两个覆盖层:一个在选定区域周围画蓝色边框,另一个显示底部控制栏。

控制栏用 tiny-skia 纯 CPU 渲染——四个圆角按钮,保存(绿)、复制(蓝)、暂停(黄)、取消(红)。按钮上的字母用位图字形手工绘制,没有额外的字体依赖。鼠标悬停高亮和点击处理一应俱全。

多显示器适配踩了不少坑。Wayland 的输出几何信息需要手动探测并计算全局坐标,预览窗口要找到包含(或最接近)选区中心的那个输出,然后在该输出的坐标空间里定位。放右侧、放不下放左侧、两边都放不下就 clamp。

它现在长什么样

# 安装
paru -S wayscrollshot-bin

# 使用
wayscrollshot
# slup 选区域 -> 滚动 -> 点保存/复制

# 换个算法
wayscrollshot -a template
wayscrollshot -a edge
wayscrollshot -a col-sample

五种算法可选,默认 ORB,绝大多数场景不用调。

开源与持续交付

项目从一开始就配了完整的 CI/CD。每次推送自动编译 x86_64 和 aarch64 的 release 二进制,自动生成 AUR PKGBUILD 并推送到 wayscrollshot-bin 的 AUR 仓库。从代码提交到 Arch 用户能 paru -S 安装,中间零手动操作。

MIT 协议,代码在 GitHub 上公开。

AI 协作的心得

这个项目一千多行 Rust 代码,从第一行到发布 AUR 包,全部由 AI 辅助完成。但"AI 辅助完成"不等于"AI 独立完成"。

AI 擅长:写模块代码、生成测试、配 CI 配置、查 API 文档、翻译双语文档。AI 不擅长:理解底层协议语义(Wayland 的 wl_buffer 生命周期坑了好几轮)、判断算法在实际场景中的边界条件、拍板架构决策。

最有效率的分工是:人做"什么是对的"和"为什么这样对"的判断,AI 做"把这些写出来"的执行。

回到补位逻辑

Wayland 的生态位缺口还有很多——滚动截屏只是其中一个。但在 AI 工具的加持下,"我用的东西缺一块"已经不再是"那就忍着"的理由了。你现在就有能力去补上它,然后共享出去让更多人受益。

开源社区的本质从来不是等待大厂投喂,而是每个有痛点的人自己动手,然后彼此受益。AI 让这个循环快了一个数量级。


wayscrollshot 已在 AUR 可用:paru -S wayscrollshot-bin

GitHub: jswysnemc/wayscrollshot(代码开源,MIT 协议) 感谢 totrytakeoff 大佬提供的ORB 特征匹配 + RANSAC拼接算法

Interaction

读完之后

分享海报
Interaction

评论区