ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Cua Driver 在 Linux 上的后台计算机使用:AT-SPI 2、XTEST 输入注入与合成光标全解析

2026/9/13 16:34:03 拓冰建站 浏览量
Cua Driver 在 Linux 上的后台计算机使用:AT-SPI 2、XTEST 输入注入与合成光标全解析 Cua Driver 在 Linux 上的后台计算机使用AT-SPI 2、XTEST 输入注入与合成光标全解析【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cua本篇文章围绕 inside-linux-computer-use.md 展开深入拆解 Cua Driver 在 Linux 上实现后台驱动真实桌面应用的完整技术方案如何用 AT-SPI 2 通过 D-Bus 读取可访问性元素树、如何用 XTEST/XSendEvent 实现不抢焦点的输入注入、如何用独立的合成代理光标与物理指针解耦以及安装、诊断、systemd 常驻与 Wayland 预览的实战细节。读完你将掌握 Linux 桌面后台自动化从架构选型到落地上线的完整路径。Cua Driver 是 Cua 项目面向跨操作系统后台桌面自动化的驱动层。在 macOS 与 Windows 后台计算机使用功能落地之后Linux 后端于 release 0.5.7 起提供任何 AgentClaude Code、Codex 或你自己的循环都能通过 MCP 或 CLI 在后台驱动真实 Linux 桌面应用——你继续在前台工作光标不动、焦点大部分操作不被抢占Agent 拥有自己的合成光标。Linux 为什么难在另一个维度Windows 上一篇博客里有一句话Windows 内部装着很多个 Windows。Linux 有同样的问题只是表现在别处没有一个统一的 Linux 桌面 API 可供瞄准。真实环境里同时存在会话、合成器、显示服务器、可访问性服务、D-Bus 总线、各工具包自己的焦点行为以及click this element含义各不相同的应用GTK3 与 GTK4 行为不同Qt5 有自己的一套形态Tk 更古老更直接Electron、Chrome、VS Code、Slack、Discord、Obsidian 全部基于 ChromiumChromium 又拖进自己的一整套可访问性模型有些应用通过 AT-SPI 暴露了足够多的结构、可以按名字寻址有些暴露了树却拒绝直接激活有些只接受从真实指针同一路径到达的合成输入。因此 Linux 后端最终同样做成了一个路由器而非单一配方——这正是 Windows 后端被迫形成的形态。流程先问应用暴露了什么结构元素若可通过 AT-SPI 到达就按可访问名、角色、索引与边界而不是像素寻址若动作可通过可访问性触发驱动优先走这条路。应用拒绝该路径时回退到 X11 输入键盘输入从XSendEvent迁移到 XTEST 注入因为更多应用认为 XTEST 足够真实XSendEvent 与 X11 回退仍然保留用于它是最佳路径的场景。这种设计背后是诚实原则当应用不可见、AT-SPI 被禁用、会话是纯原生 Wayland、或应用绕过 XWayland 时驱动返回明确的错误而不是假装动作已发生。Agent 可以从它读得懂的错误中恢复却无法从静默什么都不做却报成功的驱动中恢复——后者正是作者花最多精力设计掉的一种失败模式。在源码层面这对应 delivery.rs 中结构化的background_unavailable错误携带code、detail、suggestion与escalation字段调用方可以按code分支处理与 Windows 的静默丢弃错误保持同一形状。先走捷径走不远直接驱动 X11阻力最小的路径是直接驱动 X11枚举窗口、读取标题、移动鼠标、发送按键事件没有结构时就回退到图像匹配。Demo 可行随后迅速崩坏。X11 能告诉你窗口存在却无法可靠告诉你侧边栏里有没有一个叫 Run 的按钮、文本框里有没有占位符文本、对话框背后有没有一个破坏性动作。大量现代应用通过 X11 hint 根本不暴露有意义的 UI 结构于是你又退回像素匹配——这正是计算机使用要绕开的脆弱之物。这就是 AT-SPI 2 登场的地方。AT-SPI 2 是 Linux 上架在 D-Bus 之上的可访问性层最接近 macOS Accessibility 与 Windows UI Automation屏幕阅读器等辅助技术已经在使用它。通过它驱动能看到一棵由可访问对象组成的树应用、窗口、面板、按钮、输入框、文本区、菜单项、标签页等等。树并不总是完整但远比把桌面当位图好。这正是像素自动化与计算机使用的真正区别像素自动化说在坐标 (842, 513) 附近点击元素自动化说点击这个窗口里名为 Save 的按钮——Agent 可以推理它并在布局变动后重新找到它。Linux 仍然需要像素来做边界、截图与拖拽但 AT-SPI 给了驱动一个语义起点而不是一张截图加一句祈祷。在实现上驱动通过atspi/zbus crate 原生访问 AT-SPI 2 的 D-Bus 接口运行时不需要 Python、pyatspi或 GObject-introspection typelib见 platform-linux/src/atspi/mod.rs。元素树结果以 Markdown 树形式暴露每个节点携带element_index、role、name、value、actions、bounds等字段树的遍历被默认 5000 节点上限与无限深度保护Issue #22865 说明防止 Electron 等大 Web 应用生成上万元素树撑爆上下文窗口并在 Qt6/GTK 冷启动时注册延迟的情况下自动重试最多 4 次、150ms 退避避免首次get_window_state拿到空树。Chromium 可访问性开关一个下午换来的教训Chromium 系应用有一个特别尖锐的边作者为此花掉一个下午。Chrome、VS Code、Slack、Discord、Obsidian 以及大多数 Electron/CEF 应用默认不保持完整的 AT-SPI 树。Chromium 一直等到它检测到辅助技术存在才开始构建树。这对性能是合理的对写驱动的人却极其困惑应用开着、窗口就在那儿但树就是缺失的——直到会话宣布有辅助技术在监听。在 Linux 上这个信号位于会话可访问性状态之下。cua-driver serve启动时守护进程把会话的org.a11y.Status可访问性标志打开——这正是屏幕阅读器会设置的信号。有用之处在于 Chromium 是追溯响应的已经打开的 Chromium 与 Electron 应用无需重启、无需任何按应用设置的 flag 就会构建 AT-SPI 树GTK 与 Qt 应用读取同一信号预热自己的可访问性路径。这一个细节就是后端不再脆弱的大部分原因。仍然需要会话总线上可达的 AT-SPIGNOME 上还可能需要gsettings set org.gnome.desktop.interface toolkit-accessibility truecua-driver doctor会检查这条路径并报告所见。源码层面这个机制实现在 a11y.rs驱动通过org.a11y.Bus服务的org.a11y.Status接口写入ScreenReaderEnabled与IsEnabled两个属性Chromium 看前者GTK/Qt 看后者。写入是幂等且 best-effort 的——失败只会记录日志绝不能导致守护进程启动失败。值得注意的桌面差异GNOME/COSMIC会话服务会把ScreenReaderEnabled当作真实用户请求而启动 Orca因此默认只写IsEnabledCinnamon设置守护进程从屏幕阅读器设置推导工具包可访问性写任何信号都可能进入高频设置写循环因此默认完全不写其他桌面含 KDE保留完整 Chromium 信号以兼容。上述策略可通过CUA_DRIVER_RS_A11Y_ADVERTISE_MODEall/is_enabled_only/none显式覆盖CUA_DRIVER_RS_DISABLE_A11Y_ADVERTISE可直接关闭。这些行为都有对应单元测试见同文件 tests 模块。不抢焦点的文本输入每个工具包各有一套点击只是问题的一半。文本输入通常是后台自动化崩掉的地方如果 Agent 每次写入前都必须把焦点给目标应用就会打断你——前台光标跳动、活动窗口切换后台 Agent 的前提被削弱。因此 Linux 后端为常见工具包家族准备了免焦写入路径这意味着要分别处理 GTK3、GTK4、Qt5、Tk部分控件通过可访问性动作接受文本有些需要GrabFocus但不提升整个应用有些需要合成焦点事件有些需要控件点击回退有些在工具包 IPC 可用时最好走工具包 IPC。作者坦言这底下没有一个干净的抽象是一堆按工具包的特例每个都是慢慢摸索出来的。这正是 Windows 那课在 Linux 的重演每个应用形状不同驱动必须为目标控件挑选干扰最小的合法路径没有诚实路径时返回清晰错误。目标不是假装焦点从不重要它仍然重要有些应用只在工具包相信可编辑控件获得焦点时才接受文本而是在平台允许时尽量不偷走你的前台焦点。实践中Agent 可以填表、往对话框打字、操作简单桌面应用而不用不断接管你的会话。从源码看atspi/mod.rs 与 LINUX.mdtype_text的分派顺序是优先走 AT-SPIEditableText对 Qt6/GTK4 而言免焦即可落入未聚焦窗口的可编辑控件当焦点落在不可编辑控件上电子表格单元格、终端、画布时通过 XTEST 合成键入到聚焦控件终端则走免焦的 pty 注入路径。此外用insert_text时AT-SPI 的EditableText.insertText可以返回effect:confirmed并带value_readback证据可访问性层从控件模型读回插入值而键盘/XTEST 等路径只能返回effect:unverifiable需要通过verify_state或多模态读取确认。delivery_mode后台/前台阶梯所有输入工具click、type_text、press_key、hotkey、double_click、right_click、scroll都接受可选的delivery_mode参数——按调用传入绝不是存储的全局设置的尽力后台阶梯档位与 macOS、Windows 表面一致delivery_mode行为X11 实现何时使用background默认不激活、不提升目标窗口注入AT-SPI /XSendEvent/ XInput2 MPX 指针等无抢焦路径默认选择后台 Agent 的正确起点foreground先激活目标注入再恢复先前活动窗口EWMH_NET_ACTIVE_WINDOWwmctrl -a等价物 正确处理时间戳以对抗 WM 的防抢焦后台注入落地失败时的显式升级例如 GTK 对话框按钮或只在聚焦时读取输入的控件foreground是用户可见的接管边界绝不自动选择只在你已授权前台控制或征得同意后使用。若后台投递拒绝且无授权返回拒绝而不是改变用户的焦点、工作区或合成器光标——这与 delivery.rs 的模块注释完全一致。单元测试还验证了一个防呆设计缺省字段、垃圾值、null以及已移除的历史值auto一律解析为background——默认绝不前台契约。合成光标Agent 光标不是你的物理指针Linux 后端与 macOS、Windows 使用同一光标模型Agent 光标不是你的物理指针。驱动为 Agent 绘制一个叠加光标每个 Agent 有自己的cursor_id物理指针留在你手放的地方而 Agent 光标移动到别处点击、拖拽、按住按钮、松开。如果 Agent 共享你的真实指针它在工作时你就会失去桌面有了独立的绘制光标你可以看着它行动而不交出会话光标所有权保持显式——这正是多 Agent 与后台工作流可推理的前提。后端还提供后台拖拽与按住按钮工具足以在桌面上移动条目、拖拽选中文本、测试滑块或驱动不暴露良好可访问性动作的自定义控件。叠加层是驱动行为的可视化轨迹不是输入路径本身真实输入仍走受支持后端——目前即 X11 与 XWayland经 XTEST 及相关 X11 路由。在源码中Linux 的 Agent 光标是一个 X11 RGBA override-redirect 窗口overlay.rs后台线程以约 60Hz 渲染光标局部瓦片、软件合成时读取每块瓦片下的根窗口、ShapeInput 透传保证光标自身不拦截输入。值得一提的细节X11 上还有一种更彻底的并行指针机制——通过 XInput2XIAddMaster创建独立的 MPX master pointer evdev uinput 从指针input/mod.rs让 Agent 拥有真正独立的指针设备含 REL_WHEEL/REL_HWHEEL 以驱动 GTK 平滑滚动且仅在/dev/uinput可访问、非 Xvfb/非 Xtigervnc 且非 KDE Plasma X11 热插拔风险会话时启用KDE/X11 上为规避会话级崩溃风险而禁用 MPX保留 XTEST 前台路径。这套机制也被用于parallel_mouse_drag与函数曲线拖拽如y f(x)采样为连续弧长插值轨迹。Linux 上守护进程问题更小Windows 因 Session 0 隔离需要 daemon 代理服务无法触及交互桌面这一约束塑造了 Windows 驱动的大量设计。Linux 没有同样的问题如果你 SSH 进一台机器且该会话有显示服务器sshd可以干净地继承DISPLAY只要会话总线与显示可达cua-driver serve就能直接从 SSH 会话连接桌面没有 Session 0 那一套。这让远程开发比 Windows 简单SSH 进带桌面会话的 Linux 桌面或 runner启动驱动把 MCP 客户端指向它。持久会话用systemd --userunit无头或 CI 风格机器启用 lingering让服务在注销后继续存活loginctl enable-linger $USER然后在用户会话下运行cua-driver serve。cua-driver autostart命令族目前仅限 WindowsLinux 上 systemd 是受支持路径。一个与会话总线相关的坑在 LINUX.md 有专门章节AT-SPI 树完全活在桌面会话的 D-Bus上驱动经DBUS_SESSION_BUS_ADDRESS到达。在容器入口、无头机、runuser/su进桌面用户、systemdsystemunit 或自带临时总线的 VNC 会话里该变量未设置AT-SPI 注册表遍历会返回空、get_window_state报每个窗口都没有元素。驱动现在启动时自动发现会话总线与XAUTHORITY恢复对偶变量未设置时采用/run/user/uid/bus或从运行中的桌面会话进程xfce4-session、gnome-session…的/proc/pid/environ读取地址。仍需成立的两个条件该会话中必须运行着可访问性总线且toolkit-accessibility已开启驱动启动时会广播屏幕阅读器信号去翻转它但完全没有 a11y 总线——/usr/libexec/at-spi-bus-launcher不存在——的会话无法暴露树cua-driver doctor现在会真实探测org.a11y.Bus不只是有没有总线并告诉你两者缺哪个守护进程必须以桌面用户身份运行才能读该用户的会话进程 environ 与/run/user/uid/bussocket。以 root 身份对用户会话运行守护进程就是 Windows Session 0 隔离问题在 Linux 的对偶。AT-SPI 遍历为空现在也被诚实呈现get_window_state设置degraded: truedegraded_reason而不是光秃秃的elements: []调用方可以区分这个窗口真没有控件与a11y 桥没起来 / 守护进程不在会话总线上。已校验的模态矩阵X11 / XFCE每档输入阶梯及其稳定公开路由源自 LINUX.md模态delivery_mode路由后置条件证明元素点击element_indexbackgroundaccessibility用verify_state仅调用不能算确认元素像素动作x,ybackgroundAT-SPI-at-point 命中时accessibility否则global_input用verify_state或多模态读取像素px点击已升级foregroundglobal_input用verify_state或多模态读取对可编辑控件的type_textbackgroundaccessibility仅在有value_readback证据时confirmedtype_text不可编辑焦点background/foregroundsynthetic_events或global_input用verify_state或多模态读取要点背景元素像素动作在 X11 上是能落地的——对暴露 AX 的应用走免焦的 AT-SPIdo_action-at-point 路径x11_atspi与 macOS/Windows 背景像素点击完全一致仅对非 AX 表面回退到 MPX 虚拟指针路径x11_pixel且该路径需要真实 Xorg /dev/uinput——在 Xvnc / 无 uinput 的最小容器里请升级delivery_mode:foreground。不可编辑控件上的type_text在background档位依赖焦点是唯一真实的背景局限foreground是文档化升级。用它能做什么首批 demo 刻意做得小先夯实原语。两个示例与文档结论互相印证1. XFCE 上的多光标拖拽。Agent 光标在 XFCE 桌面上拖拽 Cua 一词作者继续工作。重点在于分离绘制的 Agent 光标自行移动物理指针纹丝不动。2. 构建、启动、动作、验证。一个编码 Agent 构建一个计算器桌面应用启动它然后用 Cua Driver 通过应用自己的 Linux UI 做 QA。这与 Windows WPF demo 是同一个循环Agent 不止步于代码生成而是真的运行它、检查它。对桌面应用来说 diff 不是证据Agent 必须启动应用并展示发生了什么。这些 demo 不意味着每个 Linux 应用都被解决了它们展示的是受支持的形态真实桌面应用、尽量元素感知、需要时指针感知、以与 macOS/Windows 相同的契约驱动。还坏着什么原生 Wayland、AT-SPI 与无头原生 Wayland 仍在预览。受支持路径今天仍是 X11 或 XWayland在 Wayland 桌面上驱动与 XWayland 通信并把会话当 X11 处理。这对跑在 XWayland 下的应用有效但绕过它的纯原生 Wayland 应用——包括某些新版 Firefox 与 GTK4 构建——可能对后端完全不可见。原生 Wayland 路径在CUA_DRIVER_RS_ENABLE_WAYLAND1之后默认关闭屏幕捕获与完整 AT-SPI 对齐仍在落地中。这也是外部帮助最有效的地方如果你跑纯 Wayland 环境打开 flag、报告问题、发 PR——issue 与后端都是开放的。源码显示 Wayland 侧已铺开相当广的探索面platform-linux/src/wayland/Sway/wlroots 走 foreign-toplevel 发现 wlr-screencopy virtual pointer/keyboardHyprland 有独立发现与捕获适配器可选插件默认仅发现opt-in 输入 v3 源候选有严格的合格化与验证边界GNOME/Mutter 用内置 WinRects Shell helper 做目标几何与激活加 portal/libei 前台原始输入KDE/KWin 走 AT-SPI 与 portal。标准 Wayland 没有通用的、面向任意被遮挡表面的原始输入客户端协议背景 AX 动作仍可经 AT-SPI 送达PX 左键在命中测试解析到可动作 AT-SPI 控件时也可送达其他受焦点约束的背景指针与键盘形态返回精确的background_unavailable——它们不会在静默丢弃后报成功。AT-SPI 必须在会话总线上启用且可达。若可访问性总线缺失或工具包可访问性设置关闭驱动仍能看到一些 X11 级信息但会失去让后端真正有用的元素树。无头仍处于早期。更广泛的私有显示故事尚未交付。纯无头Xvfb配方如xvfb-run -a cua-driver serve可用于 CI 实验但它不等于完全受支持的后台桌面产品探索过私有 Xvfb 与 Hyprland 后台捕获的社区分支被关闭而非合并。glibc 下限已降低、二进制在 Debian 11 容器内构建但作者仍预期发行版、工具包与合成器缺口会浮现。cua-driver doctor存在的意义就是让你把这些缺口作为事实而非猜测上报。安装、诊断与运行macOS 用的同一个安装器现在会检测 Linux 并路由到 Rust 后端/bin/bash -c $(curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/cua-driver/scripts/install.sh)在 Linux 上脚本下载x86_64 linux-gnu二进制并符号链接到~/.local/bin/cua-driver。请确保~/.local/bin在PATH中。仓库内对应的安装脚本位于 libs/cua-driver/scripts/install.sh。前置条件# Debian / Ubuntu sudo apt-get install -y at-spi2-core # Fedora / Rocky / RHEL family sudo dnf install -y at-spi2-core按需启用工具包可访问性gsettings set org.gnome.desktop.interface toolkit-accessibility true检查会话cua-driver doctor cua-driver status cua-driver list_appsdoctor子命令运行一组平台感知探针并输出结构化报告纯文本默认、--json输出 JSON每项探针一行[ok]/[warn]/[err]标签方便 grep退出码仅在存在[err]时非零见 cua-driver/src/doctor.rs。Linux 相关探针覆盖DISPLAY/WAYLAND_DISPLAY存在性、X11 连接可达性与 AT-SPI 总线可用性提示在 LINUX.md 的快速分诊里doctor会报告显示服务器X11/Wayland、org.a11y.Bus是否真的在会话总线上应答、发现的DBUS_SESSION_BUS_ADDRESS以及ffmpeg可用性用于录制。空 AT-SPI 树的排查顺序是(a) 守护进程不在桌面会话总线无头/容器/runuser/root 对用户会话doctor 会显示DBUS_SESSION_BUS_ADDRESS unset(b) a11y 桥关闭toolkit-accessibility true(c) GTK4/Qt6/Chromium 惰性填充——交互或 AX 启用稳定后重新快照。启动驱动cua-driver serve持久 Linux 用户服务systemdmkdir -p ~/.config/systemd/user cat ~/.config/systemd/user/cua-driver.service EOF [Unit] DescriptionCua Driver [Service] ExecStart%h/.local/bin/cua-driver serve Restarton-failure [Install] WantedBydefault.target EOF systemctl --user daemon-reload systemctl --user enable --now cua-driver无头/CI 用户需要服务在注销后继续运行loginctl enable-linger $USER接入 Claude Codeclaude mcp add --transport stdio cua-driver -- cua-driver mcp其他 MCP 客户端cua-driver mcp-config每个 MCP 工具也都暴露为顶层 CLI 子命令同样操作可直接脚本化cua-driver list_apps cua-driver doctor cua-driver status发布二进制面向 glibc 2.31 及更新版本在debian:11容器内构建应能在 Debian 11、Ubuntu 20.04 与 RHEL/Rocky/Alma 8 上运行已实测 Debian 12glibc 2.36与 Rocky 9glibc 2.34并在 Debian 12、Ubuntu 22.04、Ubuntu 24.04、Rocky 9 与 Fedora 41 上完成测试。仓库内完整的 Linux 能力矩阵X11/Openbox、Sway/wlroots、Hyprland/Omarchy、GNOME/Mutter、KDE/KWin、嵌套cua-compositor各自的基础能力与主要限制见 LINUX.md。进一步阅读Linux 后端完整技能文档免焦契约、输入投递、Wayland 边界、快速分诊libs/cua-driver/rust/Skills/cua-driver/LINUX.md跨平台循环与失败模式快照前后、像素点击契约libs/cua-driver/rust/Skills/cua-driver/SKILL.mdLinux 平台实现源码libs/cua-driver/rust/crates/platform-linux/src/AT-SPI 树、输入投递、叠加层、Wayland 适配器Windows 版后台计算机使用Session 0 与 daemon 代理问题的对照blog/inside-windows-computer-use.mdmacOS 版后台计算机使用私有框架与路由技巧的对照blog/inside-macos-window-internals.md如果拿它对一个暴露了奇怪树、拒绝输入或跨工具包行为不一致的 Linux 应用请附上cua-driver doctor输出、发行版、桌面会话与应用名开 issue——这些报告是把早期覆盖变成无聊、可靠的平台支持的最快途径。作者最想听到的正是尚未碰到的工具包角落。【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cua创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考