使用 xdotool 模拟用户交互
命令行下,对于一些常用而重复的命令,可以使用脚本来自动化;而对于图形界面程序,则可以使用 xdotool 来模拟用户的鼠标键盘输入。xdotool 是一个命令行工具,用户可以通过命令或者脚本模拟鼠标和键盘的动作,使用命令行控制图形界面。
安装
通常,发行版的软件源应该包含 xdotool,例如 Debian/Ubuntu 下可以通过 sudo apt-get install xdotool
来安装。如果系统软件源中没有,可以到 xdotool 官网下载源代码编译安装。xdotool 的依赖项只有 Xlib,因此编译过程应该很容易。
起步
下面通过一个简单的例子来测试 xdotool 的功能。首先打开图形界面下的终端模拟器,将鼠标移到某个菜单之上,但是不要点击。这时输入焦点应该还在命令行窗口,鼠标位置不动,输入下面的命令:
xdotool click 1
执行这条命灵之后,会发现鼠标悬停处的菜单神奇地打开了,就好像在那里点了左键一样。对 X11 来说,点击鼠标只是一个事件,它并不管这个事件来自鼠标、触摸板、触摸屏还是其他设备,或者是类似 xdotool 这样的软件。
上面的命令中,click
表示动作,1
表示鼠标左键,合法的取值有:
编号 | 含义 |
---|---|
1 | 鼠标左键 |
2 | 鼠标中键 |
3 | 鼠标右键 |
4 | 滚轮向前 |
5 | 滚轮向后 |
进阶
下面考虑复杂一些的情况,如果用 xdotool 来完成自动化,那么需要移动指针到指定的地方。X 桌面坐标系原点位于左上角,x 轴正方向向右,y 轴正方向向下,以像素为单位。例如,本人屏幕分辨率为 1920x1080,那么左上角的坐标为 (0, 0),右上角的坐标为 (1920, 0)。
假设现在需要平铺所有的窗口(我用的是 GNOME 桌面),那么需要将鼠标移到屏幕左上角点击 “Activities” 按钮。使用 xdotool 可以这样实现:
xdotool mousemove 0 0 click 1
xdotool 支持多个命令连在一起,上面的例子中,首先将鼠标移到屏幕左上角,然后点击鼠标左键。
mousemove
指令将鼠标位置移动到指定处,mousemove_relative
以鼠标当前位置为初始,移动相应的距离。这两条指令经常带上 --sync
参数,表示一定要等到 X11 确认鼠标已经移动到了目标位置,才会继续执行。
需要注意的是,如果坐标包含负值,必须在坐标前加上两个减号。例如命令
xdotool mousemove_relative -10 -10
是不能正确执行的,应该使用这种方式:
xdotool mousemove_relative -- -10 -10
窗口
xdotool 最强大的一个功能,就是能够自动搜索窗口,确定该窗口的位置,并使用窗口的局部坐标。例如,寻找 Chrome 浏览器并激活其窗口,可以通过下面的命令实现:
xdotool search "Chrome" windowactivate
这个功能需要窗口管理器的支持,xdotool 会遍历所有窗口,一旦发现标题栏内容包含指定的关键词,就返回该窗口。如果没有符合规则的窗口,那么什么也不会发生。
这里需要指出的是,窗口的标题栏内容和程序名称没有必然的关系。xdotool 根据标题栏内容查找窗口,而非应用程序的名字。
找到了目标窗口,还不能立刻对窗口中的按钮进行操作,因为窗口可能为于屏幕的任何位置。不过,我们可以将鼠标移动到窗口的左上角:
xdotool search "Chrome" windowactivate --sync mousemove --window %1 0 0
--window X
表示后面的坐标是相对窗口 X 而言的,%1
表示 search 操作返回的第一个窗口。
除了将鼠标移动到窗口的左上角,另一个方案是将窗口移动到指定的位置。例如,将 Chrome 移动到 (50, 50) 处:
xdotool search "Chrome" windowactivate --sync windowmove 50 50
再进一步,还可以指定窗口的大小,例如将 Chrome 缩放到宽 640,高 480 的大小:
xdotool search "Chrome" windowsize 640 480
杂项
拖拽
拖拽动作可以分解为“按下鼠标-移动鼠标-释放鼠标”的步骤,下面的代码是一个简单的例子:
xdotool mousedown 1
sleep 0.5
xdotool mousemove_relative --sync 200 200
sleep 0.5
xdotool mouseup 1
按键与输入
与鼠标模拟相比,xdotool 的虚拟键盘要简单的多。例如,按下 F1 键只需要:
xdotool key F1
如果需要组合键,可以使用加号连接:
xdotool key ctrl+a
对于文本流的输入,xdotool 提供了一个 type
命令:
xdotool search "gedit" windowactivate --sync type "hello world"