☰
UOS 20 ARM64下KeymouseGo鼠标键盘录制回放与X11适配实战
2026/10/11 2:30:15 网站建设 项目流程

最近一直在折腾一台 UOS 20(ARM64 版本)的桌面终端,处理器是麒麟 9000C,显示协议走的是 X11。设备本身倒没什么问题,真正让我花了不少时间的,是让 KeymouseGo 这种开源的鼠标键盘录制回放工具在上面稳定跑起来。你可能会觉得,这种小工具不就拿来即用?其实放到国产 ARM 平台上,坑比想象中多得多。

这篇文章就把我整个适配和排查过程记录下来,从环境准备、依赖安装、原理拆解到实战操作都有。如果你手头也有一台 UOS 20 的 ARM64 机器,想在 X11 桌面下做重复性操作的自动化,这篇文章应该能帮你少踩不少弯路。无论是想快速跑通一个录制脚本,还是想搞清楚它背后是怎么工作的,下面这些内容都值得一看。

1. 项目目标与适用场景拆解

1.1 KeymouseGo 到底解决什么问题

KeymouseGo 是一个用 Python 写的鼠标键盘录制回放工具。核心逻辑很简单:你手动操作一遍电脑,它把每一次移动鼠标、点击按钮、敲击键盘的动作连同时间间隔都记录下来,存成一个脚本文件。以后需要重复同样操作时,一键回放,它就能把刚才那套操作原样重跑一遍。

我听不少朋友第一反应是“这不就是按键精灵吗”。方向类似,但 KeymouseGo 在 Linux 桌面环境下有它独特的优势:轻量、开源、基于系统底层输入事件实现,比模拟窗口消息的兼容性方案更“硬核”一些。它特别适合下面这些场景:

  • 软件测试人员做回归测试,反复填同一个表单、点同一个保存按钮;
  • 运维人员批量登录内部平台,重复执行某些固化操作;
  • 办公场景里每天固定处理同一批文档,比如改格式、重命名、归档到指定目录;
  • 培训演示前,需要把一段 PPT 操作录下来不断回放,给设备自己“讲”一遍。

说白了,任何一次重复到让你觉得“电脑为什么不自己动手”的操作,都适合交给这类工具。不过我得先提个醒:这类自动化工具应该用在正当的效率提升、工作流精简场景,别拿去搞游戏脚本或者刷量之类的事,那是完全不同的思路,而且很容易翻车。

1.2 从 x86 到 ARM64,适配难度在哪里

之所以要把“UOS 20(ARM64 / 麒麟 9000C)”单独拿出来说,是因为很多通用教程默认你跑在 x86 的 Ubuntu 或者 Debian 上,但国产 ARM 终端的情况不太一样。

UOS 20 本身基于 Debian 体系,桌面环境用的是 DDE(深度桌面环境),整体软件源跟 Debian 系很像。但 ARM64 版本的源里,包的丰富程度和更新速度通常不如 x86 版本来得及时。很多在 x86 上直接用 apt 就能装好的图形库、输入库,在 ARM64 上要么版本偏老,要么需要在配置里额外指定架构。

麒麟 9000C 是一颗 ARM 架构的桌面处理器,64 位指令集没问题,跑普通的 Python 程序没有任何障碍。麻烦的地方主要在这几点:

  • 部分 pip 包会依赖本地动态库,比如 libGL.so.1、libX11.so.6,如果系统里没有对应 ARM64 版本的库,安装或者运行就会报错;
  • PyQt5 这类重量级图形库,在 ARM64 源里有可能缺失,需要换用 Tkinter 之类更基础的方案;
  • 输入设备相关的事件接口,在 ARM 平台上和 x86 平台差别不大,但不同内核版本上的权限策略会有差异。

所以适配 KeymouseGo 的第一步,不是写代码,而是先把系统依赖和 Python 依赖对齐到 ARM64 平台能用的状态。

1.3 X11 与 Wayland:先把基础协议搞对

这个工具能不能跑起来,一个重要前提是桌面会话走的是 X11 而不是 Wayland。为什么?因为 KeymouseGo 在 Linux 下实现回放,依赖的是 X11 协议里的 XTest 扩展。

XTest 扩展允许程序主动向 X 服务器注入合成输入事件。简单理解为:系统内核收到这些注入事件时,会认为是一个真实的外接设备发了信号,于是目标窗口正常响应,跟真人操作几乎一模一样。这就是它能稳定控制第三方软件的根本原因。

Wayland 的桌面环境出于窗口隔离和输入安全考虑,对程序模拟全局鼠标键盘事件限制得非常严格,普通用户态程序基本拿不到 XTest 那种能力。所以如果系统默认登录进的是 Wayland 会话,这类录制回放工具基本就废了。

UOS 20 桌面默认登录的会话类型我实测是 X11,这一点对 KeymouseGo 来说非常关键。如果你拿到的机器或者是未来某个版本默认换了 Wayland,就需要先切回 X11 会话再继续下面的操作。

可以用一行命令快速确认当前会话类型:

echo $XDG_SESSION_TYPE

输出 X11 就没问题。

2. 环境准备:把依赖装到能干活的状态

2.1 先把 Python 基础环境拉齐

UOS 20 通常自带 Python 3.7 或更高版本,直接验证一下:

python3 --version

如果版本在 3.7 以上,基本够用。接下来装 pip 和 Tkinter:

sudo apt update sudo apt install python3-pip python3-tk

千万不要用 update-alternatives 把系统的 python3 软链到别的版本,UOS 的桌面组件很多都依赖系统默认 Python,乱切容易把桌面搞挂。我在这台机器上就见到过有人切了 Python 版本后,DDE 桌面直接起不来,最后只能重装。别踩这个坑。

装完后可以顺手验证一下 Tkinter 是否可用:

python3 -c "import tkinter; print('ok')"

如果能打印 ok,说明图形库没问题。

pip 源的问题也要注意。ARM64 环境下默认源下载速度可能不稳定,我个人建议直接把 pip 的索引源切换成一个速度快的社区镜像,能省不少时间。具体配置方式就是把~/.pip/pip.conf里的index-url改掉。这里不写具体地址,你选择一个自己在网络环境里实测快的源就行。

2.2 安装 X11 相关系统包

KeymouseGo 在 Linux 上做输入注入,底层要跟 X 服务器打交道,所以需要装 X11 的开发库还有 XTest 扩展相关的系统包。执行:

sudo apt install xdotool python3-xlib libx11-dev libxtst-dev

这几个包的作用分别是:

  • xdotool:命令行下调试 XTest 注入是否正常的最快工具;
  • python3-xlib:Python 访问 X11 协议的接口层;
  • libx11-dev:X11 客户端库的开发头文件,部分 Python 包编译时需要;
  • libxtst-dev:XTest 扩展的开发库,提供额外输入事件模拟能力。

装完之后,可以用这样一个命令确认 XTest 扩展在当前 X 服务器里有没有被启用:

xdpyinfo -display :0 | grep XTEST

如果能看到 XTEST,说明当前 X 服务器支持输入注入。如果搜不到任何关键字,那就要检查 Xorg 的配置或者显卡驱动里面是不是把扩展关掉了。实际运营环境中,常见的是某些优化脚本或安全策略会禁用 XTEST,所以提前验证是值得的。

2.3 获取源码并确认入口

KeymouseGo 这类开源工具的源码获取方式很常规,从项目主页把代码打包下载下来就能用。下载后先看一下目录里的 README,依赖通常写在 requirements.txt 里面。

我在这台 ARM64 机器上实测,核心依赖其实就两个方向:一个是 pynput 这类输入事件监听库,另一个是 python-xlib 或者 pyautogui 这类回放注入库。在 ARM64 上直接 pip 装就行,不需要编译任何 C 扩展,基本没有架构方面的障碍。

启动入口一般是main.py。如果项目里带 GUI 界面,运行:

python3 main.py

如果遇到某个图形依赖在 ARM64 源里找不到,我的习惯是优先搜索系统源里的同名包,能用 apt 装就别硬用 pip。你可以在源里这样搜索:

apt-cache search pyqt5

有的话直接sudo apt install python3-pyqt5,会比 pip 在 ARM 平台上省心很多。没有的话就用 Tkinter 版本,功能上完全够用。

3. 核心实现原理:录制回放是怎么做到的

3.1 事件监听与脚本记录格式

KeymouseGo 的录制阶段,核心是一个全局事件监听器。它在后台不停接收系统的输入事件,然后给每个事件打上毫秒级时间戳。

记录的事件类型大致包括:

  • 鼠标移动(move)
  • 左键按下(leftdown)
  • 左键释放(leftup)
  • 右键按下(rightdown)
  • 右键释放(rightup)
  • 键盘按键(keydown / keyup)

它记录时间的方式,不是直接记录绝对时间,而是计算相邻两个事件之间间隔了多少毫秒,把这个差值作为 delay 字段存下来。回放的时候,就靠这些间隔还原出原始操作节奏。所以你在录制过程中停顿多久、点击多快,回放时都会原样重现。

一个典型的脚本片段内容大致是这样的结构:

delay, 280 move, 960, 540 leftdown leftup delay, 150 keydown, "ctrl" keydown, "v" keyup, "v" keyup, "ctrl"

这个文本格式的好处是:可以直接用编辑器手工改。比如把某个坐标从 960 改成 1024,或者把某个多余的 delay 删掉,都不需要重新录制。这个特性在后期调参时极其有用。

3.2 回放时序与双线程设计

回放阶段有意思的地方在时序控制。程序会先加载脚本,把每一行解析成一个事件对象,然后启动一个独立的工作线程来处理。

工作线程的逻辑其实就是一个循环:

  1. 读取当前事件;
  2. 如果事件类型是 delay,就sleep对应毫秒数;
  3. 如果是鼠标移动或点击,就通过 XTest 扩展注入对应事件;
  4. 继续读下一个事件,直到脚本结束。

录制和回放之间的时间差,主要靠 delay 来控制。所以 KeymouseGo 界面上通常会有“速度倍率”这个参数,实际就是给所有 delay 统一乘一个系数。倍率设为 0.5,整个操作就变成原来的两倍速;设为 2,就是半速回放;如果设成 0,所有等待基本被忽略,脚本就会变成一轮纯操作风暴。某些性能测试场景里,这个功能非常好用。

关键的一点是:录制和回放必须在单独的线程里跑。为什么?因为 GUI 主线程在回放时还需要处理界面事件,比如你用热键请求停止、修改循环次数等等。如果回放在主线程里执行,界面会直接假死,想停都停不下来。

3.3 坐标换算与界面参数

KeymouseGo 在 X11 下默认的坐标原点在屏幕左上角,单位是像素。这个坐标系本身很直观,但 UOS 20 桌面默认开了缩放之后会带来麻烦。

举个例子:你在显示设置里把缩放设为 150%,界面里看起来某个按钮在逻辑坐标 (960, 540) 的位置,但在 X11 的物理坐标体系里,它实际对应的可能是 (1440, 810)。如果 KeymouseGo 录制时记录的是逻辑坐标,回放的时候却直接往物理坐标注入,那么点击位置就会整体偏移。

解决办法有两个:

  • 录制和回放时保持相同的缩放比例,不要中途切换;
  • 录制时不要依赖缩放后的逻辑坐标,直接以物理全屏坐标为目标。

另外还要留意多显示器的情况。X11 的全局坐标会跨多个显示器平铺计算,如果你把窗口从主屏拖到副屏,那么同样的按钮坐标已经变了,之前录好的脚本自然就失效。这种情况我建议直接重新录一遍,别想着通过改坐标硬凑,效率太低。

4. 实战记录:完整跑通一个循环点击任务

4.1 录制开始前的准备

前面原理讲了那么多,下面我把自己在这台 UOS 20(ARM64 / 麒麟 9000C)上实际跑通的一个任务完整记录下来,方便你照着操作。

我选择的演示任务是:在某个内部应用的列表页,手动点击“导出报表”按钮,然后在弹出的对话框里确认,把报表文件保存到固定目录。整个过程大概十几秒,之后我想让它自动循环执行 20 次。

录制前有几步准备工作要做:

  1. 关掉所有可能弹窗干扰的程序,包括系统更新提醒、输入法切换浮窗等。任何出现的弹窗都会成为录制内容的一部分,真实回放时反而会干扰流程;
  2. 把目标软件打开到需要的页面,窗口位置固定好,中途别移动;
  3. 确认会话类型是 X11;
  4. 启动 KeymouseGo,主界面保持打开状态。

准备好之后,我先把界面上的“录制”按钮点一下,然后迅速切换到目标应用窗口。

4.2 录制过程与脚本检查

录制开始后,我手动执行了一遍完整操作:

  • 鼠标移到列表第一行的“导出”按钮,左键单击;
  • 等待页面弹出确认对话框;
  • 鼠标移到“确认”按钮,左键单击;
  • 在弹出的文件保存窗口里,用键盘输入文件名report_0716,按下回车;
  • 等待保存完成,页面回到列表页。

操作完成后,我切回 KeymouseGo 窗口,点了“停止录制”,脚本保存到了一个文本文件里。

用文本编辑器打开看,内容大致是:

delay, 1020 move, 1280, 460 leftdown leftup delay, 950 move, 1024, 640 leftdown leftup delay, 380 keydown, "r" keydown, "e" ...

这里有几个细节值得注意。首先是 delay 的分布,操作之间如果停顿了,中间就会插入一个较大的 delay 值,一般在 300 到 1000 毫秒之间,这正常。其次是鼠标在移动的过程中,如果路径比较长,会被拆成很多个连续的 move 事件,每个之间间隔几十毫秒,这也是正常的。

如果录制过程中手抖了或者鼠标点击错了位置,不要急着停下来重录。我通常的做法是先把脚本文件放到文本编辑器里,把明显错误的 move 行删掉,或者把点击坐标改一下,比重新录制更快。

4.3 参数调整与正式回放

脚本确认无误后,我在 KeymouseGo 界面里设置了这样几个参数:

  • 循环次数:20
  • 速度倍率:1

然后点“开始回放”。回放过程中我刻意不去动鼠标和键盘,因为任何人工输入都会跟脚本注入的事件混在一起,轻则打乱节奏,重则让后续操作全部错位。

大概 5 分钟左右,20 轮循环全部跑完。打开目标目录,里面已经生成了 20 个带编号的报表文件,任务顺利完成。

如果回放过程中发现点击位置和录制时不一样,或者节奏太快导致页面响应不过来,我的调整顺序是:先确认缩放设置有没有变化,再检查是不是有些 delay 太短。把明显偏短的 delay 手动调大一点,通常就能解决。

5. 踩坑排查:ARM64 UOS 上常见问题速查

5.1 动态库与 Python 依赖报错

最常见的一类问题,是启动时直接报ImportError,比如找不到Xlib模块。不要急着去 pip 重装,先在系统里搜一下:

apt-cache search python3-xlib

如果有,直接 apt 安装。UOS 20 的 ARM64 源里这个包通常是有的,而且系统版本跟桌面环境匹配度更好,不会出现 pip 版和系统库冲突的情况。

另一个高频错误是:

ImportError: libGL.so.1: cannot open shared object file

这说明某个图形相关的依赖库没有装全。解决办法是:

sudo apt install libgl1-mesa-glx

如果装了 PyQt5 后报qt.qpa.plugin: Could not find the Qt platform plugin "xcb",也是类似逻辑,需要补:

sudo apt install libxcb-xinerama0

这类问题的排查思路就是:看到 which 库缺失,就用apt-file或者apt-cache search找到对应 ARM64 包,装上之后一般就正常了。

5.2 DISPLAY 与 Xauthority 问题

如果你是通过 SSH 登录到这台 UOS 设备,然后尝试直接运行 KeymouseGo,很可能会遇到:

No protocol specified _x11.GetImage: Could not connect to display None

原因是没有把当前会话的显示环境变量传过来。需要在运行前手动指定:

export DISPLAY=:0

如果还是不行,还要把 Xauthority 文件指出来:

export XAUTHORITY=~/.Xauthority

注意这里的~对应的是正在运行图形桌面的那个用户,不是 SSH 登录用户。如果两个用户不一致,直接写绝对路径更稳妥。

5.3 XTEST 扩展不可用或者注入无效

运行 xdotool 模拟点击,但目标窗口毫无反应,大概率是 XTEST 扩展在当前会话里没启用。验证命令前面已经写过了:

xdpyinfo -display :0 | grep XTEST

如果是远程桌面或者某些经过安全加固的 Xorg 配置,XTEST 可能会被显式禁用。

另外,UOS 20 上如果启用了某些录屏或者安全管控组件,也可能拦截 XTEST 注入事件。这种情况我遇到过一次,最后是在系统设置的安全中心里,把对应程序的输入监控权限关掉才解决。不同版本的 UOS 设置项名称可能不一样,你找跟“输入监控”“进程保护”相关的开关,关掉试试。

5.4 高 DPI 与多显示器导致的坐标偏移

这类问题在项目里出现的频率最高。录制时鼠标明明停在按钮上,回放时却点到旁边去了,基本就是缩放比例变了,或者显示器布局变了。

排查方法很简单:看回放的实际落点是否偏移量固定。如果每次都是同样的偏移,说明坐标坐标系不一致;如果只在某个显示器上偏移,说明主屏设置变了。

我的经验是:录制前先确认显示设置为固定档位,别用自动缩放;多个显示器时尽量在同一个屏幕内录制和回放。偶尔需要跨屏操作,就老老实实重新录一遍,别迷信手改坐标。

5.5 回放停不下来怎么办

循环次数设得太多,或者脚本里有异常的长 delay,回放线程会把主界面卡住,此时鼠标点击“停止”按钮可能没反应。

遇到这种情况,我通常直接在工作线程所在的终端窗口按Ctrl+C,如果无效就开一个新终端,用进程名把整个程序杀掉再重启。所以每次跑长时间回放前,我会提前开一个终端窗口,随时准备用命令终止进程,避免被迫直接重启设备。

最后再分享一点经验

整个环境折腾下来,我的体会是:KeymouseGo 本身没什么高深技术,但能不能在你的 ARM64 UOS 设备上跑起来,很大程度上取决于系统依赖装没装对、X11 会话对不对、缩放配置统不统一。这三件事只要有一件没做好,你就会在莫名其妙的地方浪费半天时间。

最后分享一个我实际用下来的小技巧:回放任务正式开始前,先用xdotool获取目标窗口的位置信息,例如用xwininfo确认窗口所在区域,这样能在录脚本之前就知道目标坐标会不会落在窗口之外。特别是调整过分辨率或者屏幕布局后,这个检查能帮你省去一次重录的麻烦。

如果你手头的 UOS 20 ARM64 设备也要跑 KeymouseGo,照着这篇文章的顺序走一遍,基本半小时内就能把环境整好。真正跑通之后,你会发现那些每天重复到烦躁的操作,终于可以放心交给机器去执行了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询