问题修复(INCR分片:Incremental Transfer(增量传输)无法粘贴彩色图片Failed to paste image)
https://github.com/shangxiang0907/codex-wsl-clipboard-bridgehttps://github.com/shangxiang0907/codex-wsl-clipboard-bridge/commit/fabfb4af94ef1e3cb3e8901e49344785742a8536文章目录一张彩色截图为什么让 Codex 误报“剪贴板没有图片”现象先把链路拆开几次合理但错误的猜测会不会是会话上下文太长会不会是 Wayland 和 X11 后端选错会不会是颜色太丰富PNG 压缩算法有问题抓住 X11 selection 的所有权变化真正的根因分片之间只等 10 毫秒修复绕开 INCR而不是牺牲图片验证对系统其他服务的影响排障方法上的收获一张彩色截图为什么让 Codex 误报“剪贴板没有图片”从 WSLg、X11 selection、xclip到 Codexarboard的 10 毫秒超时现象在 WSLg 中运行 Codex CLI 时同样使用CtrlV一些界面截图可以正常粘贴一张2520×1490的游戏指南页面截图却反复失败Codex 报错称剪贴板为空或没有它请求的图片格式Failed to paste image: no image on clipboard: The clipboard contents were not available in the requested format or the clipboard is empty.这条错误很容易让人怀疑图片分辨率、颜色数量、PNG 大小甚至会话上下文长度。实际根因都不在这些地方。先把链路拆开这个环境中的完整数据流是Windows 截图 → WSLg Wayland image/bmp → ImageMagick PNG32 → X11 CLIPBOARD image/png → Codex CLI / arboard服务日志已经确认 BMP 读取、PNG 转换和 X11 发布成功bridged 2520x1490 image (11264454 byte BMP) to X11 as PNG在发生故障的同一个终端中xclip也能完整读出图片xclip-selectionclipboard-tTARGETS-o|tr\0\nxclip-selectionclipboard-timage/png-o/tmp/clipboard-test.pngfile/tmp/clipboard-test.pngstat-c%s bytes/tmp/clipboard-test.png结果是有效的2520×1490RGBA PNG大小约 1.37 MB。这排除了格式缺失、文件损坏和超大输入限制。几次合理但错误的猜测会不会是会话上下文太长不会。错误发生在图片进入对话之前是本地剪贴板读取失败。conversation recap和模型上下文还没有机会处理这张图片。会不会是 Wayland 和 X11 后端选错强制删除WAYLAND_DISPLAY并让 Codex 使用DISPLAY:0后仍然失败。这说明后端选择不是这次问题的充分解释。会不会是颜色太丰富PNG 压缩算法有问题同尺寸合成图测试确实显示内容熵会显著改变 PNG 大小内容BMPPNG32纯色11.26 MB17.9 KB渐变11.26 MB18.8 KB照片式纹理11.26 MB7.58 MB随机颜色11.26 MB12.92 MB但实际失败截图只有约 1.37 MB而且 ImageMagick、file、identify和xclip都能正常处理。颜色丰富度只是增加故障概率的相关因素不是根因。我们一度实现了自适应 PNG8 量化实测没有解决问题随后完整撤销。这一点很重要没有端到端证据时不应以损失画质来掩盖传输层缺陷。抓住 X11 selection 的所有权变化X11 剪贴板不是一块永久保存数据的共享内存。当前 selection owner 必须在消费方请求格式时现场提供数据。通过 XFixes 监听复现过程得到如下事件19:30:00 eventchanged TIMESTAMP,TARGETS,UTF8_STRING,TEXT 19:30:02 eventchanged TARGETS,image/png xclip -selection clipboard -t image/png -i candidate.png第二个事件之后没有其他程序覆盖 selection。Codex 失败时PNG owner 仍然存在并且image/png仍在TARGETS中。问题因此被压缩到最后一段Codex 如何从 X11 owner 读取 PNG。真正的根因分片之间只等 10 毫秒Codex CLI 0.152.0 包含arboard 3.6.1。检查该版本的src/platform/linux/x11.rs可以看到constLONG_TIMEOUT_DUR:DurationDuration::from_millis(4000);constSHORT_TIMEOUT_DUR:DurationDuration::from_millis(10);读取开始时arboard最多等待 4 秒。如果 selection owner 使用 X11INCR协议分片发送大属性每收到一个有效分片后下一分片的等待时间却被重置为仅10 毫秒*timeout_endInstant::now()SHORT_TIMEOUT_DUR;WSLg、X server 或低优先级xclip只要有一次调度间隔超过 10 毫秒arboard就返回ContentNotAvailable。Codex 将它格式化成“no image onclipboard”掩盖了真实的分片超时。这也解释了为什么故障看似与颜色和大小有关PNG 越大INCR 分片越多撞上一次10 毫秒调度空隙的概率越高。但它不是稳定的字节阈值同一张图也可能偶发成功。在 X11 协议X Window System的上下文中INCR 是 Incremental Transfer增量传输机制的缩写。它是 X11 剪贴板Selection协议中用于处理大数据量传输的一种握手协议。修复绕开 INCR而不是牺牲图片从消费者侧看理想修复是让arboard使用合理的分片超时例如每个有效分片后重新等待 14 秒。不过桥接器不能修改用户当前安装的 Codex。本项目采用生产者侧兼容修复用一个小型 Python/ctypesX11 PNG selectionowner 替代xclip。新 owner只操作当前用户的 X11CLIPBOARD只声明TARGETS、image/png和TIMESTAMP调用XExtendedMaxRequestSize启用 X11 BIG-REQUESTS在安全上限内用一次XChangeProperty返回完整 PNG不使用 INCR因此不会触发arboard的 10 毫秒分片超时selection 被其他程序接管时收到SelectionClear并退出服务停止时由 systemd control group 一并清理。本机 X server 报告的最大请求大小约为 16.7 MB。实现额外预留了请求头和 Xlib封装空间超过安全上限时明确失败不会截断或静默损坏图片。验证先用一张约 7.58 MB 的高复杂度 PNG 做逐字节往返测试direct owner round-trip: 7578809 bytes随后执行仓库验证XFixes event delivery: OK Static and runtime verification: OK最后重新截取同一个2520×1490Dungeon Lootr Beginner Guide 页面Codex立即成功粘贴并能正确识别页面导航、状态卡、地下城主图和页面目录。对系统其他服务的影响新 owner 的权限和作用范围与原来的xclipowner 基本一致不监听网络不创建系统级服务不操作 X11PRIMARY或SECONDARYselection不读取图片以外的剪贴板内容新的复制操作会自然取代它并使其退出PNG 只在用户私有运行目录和 owner 进程内存中短暂存在。它改变的是图片数据的 X11 传输方式而不是桌面的剪贴板语义。排障方法上的收获这次问题最值得保留的不是某一条 ImageMagick 参数而是分层验证的方法源格式是否存在 → 转换结果是否有效 → selection owner 是否仍存在 → TARGETS 是否包含消费方请求的 MIME → 直接读取是否成功 → 消费方具体依赖如何处理协议“没有图片”只是上层错误文案不代表剪贴板真的为空。只有把 Wayland、X11 selection、MIME 转换、INCR/BIG-REQUESTS 和消费库逐层拆开才能找到真正需要修改的那一行。