article_image

本文选自拙作《Keyboard Maestro 进阶指引》,欢迎选购完整栏目。
Keyboard Maestro 进阶指引
Keyboard Maestro 进阶指引

无论自动化工具提供了多少现成模块,都不可能——即便是刚好——覆盖你的所有需求。传统的兜底方法是写脚本,毕竟早些年那会儿,常见的软件多是原生的,很可能支持 AppleScript——包括 Evernote 和 Microsoft 系列产品。1

然而,姑且不谈如今各种无法脚本化的网页套壳软件,绝大多数人恐怕也没有阅读 AppleScript 等上古魔法手稿的能力。2一款工具如果本身没有活跃的社区氛围,又撂下一句“反正我支持脚本啊”,那就是流氓。

Keyboard Maestro 开辟了疯狂造轮子向脚本逃离之外的第三条路径:交互自动化,模拟键盘和鼠标操作

笨办法,还是大智若愚?

模拟鼠标和键盘操作,给人的第一印象是“笨办法”,而且有人可能抛出 Windows 上的按键精灵,进一步批评 Keyboard Maestro 折腾了半天还不是回归土办法。3

事情并非那么简单。Keyboard Maestro 模拟键盘和鼠标操作,并非只是按部就班按下某颗按键或者点击屏幕的某个角落,而是通过多种方式追踪屏幕上的元素,这意味着屏幕布局在一定范围内变化时,相应的动作也不至于失效。如果说传统模拟交互是狙击,那么 Keyboard Maestro 就是带热感因的自动制导。

举一个极端例子。原生预览软件自带几款高亮工具,但需要点开按钮、展开二级工具栏才能切换颜色,很不方便。相关按钮躲在工具栏中,没有对应的菜单栏项目,很难用脚本或快捷键操作,对此,Keyboard Maestro 有特殊应对方法:鉴于目标按钮总是位于窗口右上角,可以先确定窗口边角的坐标,再向下、向左移动一定的像素,接着模拟鼠标点击和键盘操作,最终完成一键切换高亮颜色。

无论怎样改变预览窗口的大小,或者外接一台尺寸迥异的显示器,由于目标按钮和窗口之间的相对关系基本不变,相应的 Macro 也就不容易失效。

三种常见的交互自动化

为避免混淆,此处所指的交互限于 Action 部分,而不包括 Trigger。其实正因为 Keyboard Maestro 功能过于丰富,在 Trigger 和具体模块中都涉及菜单栏和快捷键,不幸也导致许多人误把 Trigger 当成了 Keyboard Maestro 最后要执行的操作。

模拟点击菜单栏

最常用最使用也最容易设置的交互,自动化就是模拟点击菜单栏项目。当然,目标软件本身这一类交互自动化生效的前提,在 macOS 中,多数软件都会把大部分功能列入菜单栏,包括一些设计比较简约的笔记或者任务管理工具,看上去没有几颗按钮,但是翻开顶部的菜单栏仍然可以看见大量功能。这些菜单栏项目提供了重要的自动化入口。

Move or Click 模块可以点击任意菜单栏的项目4,其主要用途有三:其一,为没有快捷键的项目绑定快捷键;其二,将不合适的键位改到顺手为止;其三,作为大型 Macro 中的组件。

即便仅仅将 Keyboard Maestro 当作改键工具,这笔投资也足够回本。而接下来几篇将介绍的案例,会展示模拟交互的中高难度用法。

模拟按键

模拟按键——Type a Keystroke——既是菜单栏操控的补充,也可以在更复杂的流程中填上空白环节、尽量避免写代码。

就其补充价值而言,模拟按键可以克服菜单栏内容易变动的缺点。前一节介绍的菜单栏模拟,需要事先准确写好菜单栏项目的路径,但只要换个界面语言,原 Macro 就打不准了。如果目标菜单栏项目已经设有快捷键,不妨通过模拟按键触发它,这样就不必担心界面变动。5

至于原本就没有菜单栏项目而只提供快捷键的操作——例如 Calibre 和 Obsidian 等跨平台软件——不必多言,当然要优先考虑快捷键方案。6

话说回来,模拟快捷键即能单用,也可以组装到更大 Macro 中。我有一个从 Calibre 阅读器中拷贝电子书深度链接的 Macro,运行后先模拟快捷键、获取 URL Scheme,再自动运行文本替换模块以简化 Calibre URL 中的冗长编码。

考虑到模拟快捷键常常与其他模块组合使用,而可调整的参数也不多,本作第一版暂不单列章节。

模拟点击屏幕位置

作为终极的交互自动化手段,模拟点击屏幕位置可以延伸至菜单栏和快捷键不能及的地带。

诸如跨平台软件、网页套壳软件和右键菜单等,通常是自动化的禁区,但只要目标元素显示在屏幕上,Keyboard Maestro 总有办法控制。例如著名的 PDF Expert,从不按 macOS 开发规范出牌,虽然性能良好但界面不科学,此时就可以借 Keyboard Maestro 重塑其稀烂的工具栏,借快捷键轻松选用高亮颜色。

Keyboard Maestro 提供两种互补的位置点击方式,分布是基于窗口或屏幕位置,以及特定的图案;前者可以将窗口和屏幕周围位置相对固定的控件纳入自动化范围,后者若运用得当,则相当于在整个屏幕上布置了空对地雷达。

分论:模拟操控菜单栏

菜单栏是 macOS 软件最原始的控件之一,同时也是极具潜力的自动化素材——抛开部分网页套壳的软件不说,多数软件都将大部分功能列入菜单栏,可通过模拟点击来调用;早在 AppleScript 当道的时代,模拟点击菜单栏就是重要的自动化手段。

而 Keyboard Maestro 的卓尔不群之处远不限于操作简单:虽然是“点击”,Keyboard Maestro 却不会真的一层一层展开菜单栏,一切都在后台悄无声息地进行。这一关键特性令大量复杂的自动化成为可能,并且整个过程非常光滑无痕;而配合 Keyboard Maestro 中的其他模块,单击菜单栏还有各种变体。

基础的模拟点击

菜单栏是典型的层级结构,平时操作时,一般也是层层点开,并不方便——何况,你还得记得住各个项目位于何处。正是在这个意义上,Hum 提出了快捷键之王的概念,强调菜单栏搜索功能。手动操作尚且如此麻烦,据此编写的脚本也很痛苦,不妨看一段我早期编写的输入法切换脚本,其原理是模拟点击菜单栏中的输入法图标:7

Alt text
模拟点击菜单栏的脚本非常冗长而麻烦

这种古老的咒语,毋说诸位读者,我自己都不愿意学——或说复习,毕竟我以前就是这么熬过来的。而 Keyboard Maestro 则让事情变得非常简单,你只需要逐步填好一个菜单栏项目的路径(path),就能跳过所有繁琐的脚本、殊途同归。下图展示了如何用 Keyboard Maestro 模拟点击绘图工具 Scapple 的菜单栏项目,只需找到目标,然后记住 Notes、Align 和 Bottom Edges 这条路径,再填入 DEVONthink 的 Select or Show a Menu Item 模块——实际操作比文字描述更简单,Keyboard Maestro 已经镜像复刻了软件的菜单栏,你可以点击图中的“Menu”按钮以穿过层层菜单栏、找到目标,一番操作下来,Keyboard Maestro 就会记录下最终目标项目的位置。

Alt text
为 Scapple 菜单栏项目设置快捷键

一旦掌握了模拟点击菜单栏的方法,就可以为常用功能设置——或重新指定——快捷键。通常来说,软件开发者往往有自己的一套快捷键或菜单栏布置逻辑,很少照顾用户的习惯,最夸张的就是 DEVONthink,其菜单栏堪比宇宙飞船的操控舱,根本不知道怎么下手。好在对于 Keyboard Maestro 而言,这种对人类不友好的界面反而成了难得的资源,可通过模拟点击触发 DEVONthink 中的大量功能——事实也是如此,我为 DEVONthink 设置的多数 Macro 只是点击菜单栏项目,而不需要复杂脚本。

Alt text
DEVONthink 的菜单栏令人窒息(图中只是我随手截的一小部分)

Keyboard Maestro 在菜单栏方面最简单而有效的应用,自然就是对付这些复杂如鲁布哥德堡机械的仪表盘。而除了穿透一团乱麻的菜单,多个同一 Trigger 的 Macro 还能抱团成组,成为软件的第二、第三菜单栏。

Alt text
为 DEVONthink 中常用的菜单栏项目设定自定义快捷键

而在模拟点击菜单栏的脉络被打通后,其还可以与复杂脚本配合,负责难以脚本化的部分,比如在《一种几乎永不失效的网页中英对照翻译方案》《一种长寿可靠的网页中英分屏翻译方案》中,我设计的 Macro 均分为两部分,先跑一段 Javascript 脚本将网页内容逐段复制8,再模拟点击菜单栏中的翻译功能,组合起来实现对照翻译或分屏翻译。

Alt text
用 Keyboard Maestro 分屏翻译网页
注意:如果菜单栏项目的名称、位置发生变动,或者软件界面语言发生变动,则原本设置的模拟操作也会失效,需要重新设置。如果你下载了别人提供的 Macro,也请检查一下菜单栏项目的路径是否符合实际。 9

根据菜单栏状态执行相应操作

前文已经提及,菜单栏内容可能会发生变化,一般情况下这是消极的,不利于 Macro 保持稳健;但偶尔也有变通办法,即令 Keyboard Maestro 检查当前菜单栏的状况,再判断点击哪个项目。在部分 Markdown 编辑器中,预览模式和编辑模式下的菜单会有些微差异,例如 iA Writer 中,如果用户正在打字,那么软件只需要提供预览按钮而不需要给出编辑按钮;反之亦然。但是 iA Writer 的设计又不到位,两个功能的快捷键不同,经常记混——而对用户来说,开启和关闭预览无非就像电灯开关的两个状态,完全可以只记一组快捷键,按一次开、再按一下关。

Alt text
在 iA Writer 中切换预览和编辑模式

具体到 Keyboard Maestro 中,需要先检查当前菜单栏中项目的状态。If 模块条件丰富,也包括菜单栏相关条件“A menu item with this name XXX exists”,对于 iA Writer 而言,如果“Hide Preview”存在,那么就点击它;反之,则点击“Show Preview”。这样分情况模拟点击,就不会扑空,也不会误操作。

Alt text
通过当前菜单栏项目状态判断后续操作

单纯根据菜单栏状态点击相应相应项目,相当于简单的两相开关;而在 DEVONthink 等工具中,还涉及“编辑-预览-双栏”这样三元组,仅凭菜单栏状态就不足以判断后续操作,此时可能要另行引入变量。进一步的话题,我已在《Keyboard Maestro 中的“开关”》中讨论过。

分论:点击屏幕位置

菜单栏操控是 Keyboard Maestro 交互自动化的重要一环,但总有一些按钮等控件不在菜单栏中,例如 Office 和部分原生软件就更喜欢往工具栏(Toolbar)中塞功能;至于一大批网页套壳软件,压根就没用多少原生控件,更难操控。面对这些非标准情形,别说是写 AppleScript,就算用 Automator 完整复制键鼠操作也不一定奏效。例如:

  • 使用预览工具或 PDF Expert 等阅读器时,切换高亮颜色的选项一般都藏在工具栏内部,往往要点半天才够得着;10
  • 在论坛上留言时,留言编辑器非常难用、按钮密密麻麻排在一起,不方便点击(并且这些网站往往是套模板的,开发者不太可能有工夫给你设计快捷键);
  • 在网站后台上传数据时,各种按钮一般也没有快捷键,让习惯了本地编辑器之电光火石的人非常难受;
  • ……

好在 Keyboard Maestro 还提供了一种兜底的交互自动化方法:大量难以或不能通过其他方式够及的控件,只要它显示在屏幕上,总有办法点下去!详言之,核心模块一 Move and Click Mouse 用于点击屏幕上的特定位置,而核心模块二 Click at Found Image 则可以点击屏幕上的特定图案。单独和组合使用两个模块,几乎每一颗屏幕上的像素都能奏出自动化旋律。

点击位置:以控制预览工具的工具栏为例

第一类兜底交互自动化的核心是位置,尤其是相对位置。尽管目标不能直接触及,但只要能够在目标位置附近找到一个参照物、而参照物的位置可以确定,就能转而点击目标位置——这好比我们不能直接看到黑洞,但通过周围天体光线的扭曲,可以间接得知其位置。当然,macOS 的自动化领域中几乎没有黑洞,自动化工具可以照亮一切。

本节以原生预览工具的高亮工具栏为例。就批注而言,最重要的是颜色,而不是笔迹粗细等细枝末节,但多数 PDF 阅读器的设计者显然是工程师思维,只想着按功能分类,而不知把常用功能提到更方便触及的位置。

Alt text
预览工具的工具栏

观察一下上图的工具栏,手动切换高亮颜色的步骤是:点击右上角的批注工具按钮,然后移到想选用的颜色上,再点击一次鼠标。把这套操作翻译成 Keyboard Maestro 的交互自动化步骤如下:

  1. 先把鼠标移到预览工具窗口右上方,具体位置是相对于右上角往下、往左各30个像素,以定位到展开高亮工具栏的按钮位置;
  2. 考虑到部分机器性能有限或显示器,先暂停 0.2 秒;
  3. 模拟就地点击鼠标;
  4. 模拟按下方向键,连按几次直到定位到所需颜色;
  5. 模拟按下 ↩Return 键,完成高亮颜色切换。
Alt text
用 Keyboard Maestro 点击屏幕上的特定位置

上述流程的突破口是当前窗口右上角这一位置,因为无论预览工具的窗口如何调整大小或移动位置,目标按钮相对于窗口右上角的位置总是不变的11,只要抓住边角位置,就能点到目标按钮。再制作几个类似的 Macro,覆盖其他常用颜色,就可以告别艰难的颜色切换,一键更改高亮颜色。

Alt text
通过 Keyboard Maestro 在预览工具中切换不同的高亮颜色

当然,上例只是一个难度适中的演示,而 Move and Click Mouse 模块参数多矣,参照物可以是当前光标位置、当前屏幕或窗口的任意一角,点击时既可以点左键也可以是右键或者其他按键——只要你的鼠标按键够多——点击时还可以模拟按下 ⌘Command⌃Control 等修饰键,并且有单击、双击甚至三击等选项。诚然,仅仅罗列这些参数是空洞的12,最好的办法还是再参考更多案例,我也在本作索引部分列出涉及 Move and Click Mouse 的其他章节,用各项案例勾勒出一个模块的不同侧面。

Alt text
Keyboard Maestro 模块示意图

点击图案:以控制 PDF Expert 的工具栏为例

前例中,尚有窗口边角供辅助定位,但是在另一款 PDF 阅读器 PDF Expert 中,切换颜色的主要入口隐于右键上下文菜单中,连辅助定位都不成。不少网页也很难对付,因为网页布局容易变动,相对位置定位方案同样走不通。不过,Keyboard Maestro 仍有另一种模拟点击的方式:Click at Found Image。你可以先提供一张目标区域的截图,然后 Keyboard Maestro 就会尝试在屏幕可见区域中寻找近似图案——换言之,只要屏幕上仅有一处与目标区域图案类似,那就能够精确点击!

Alt text
用 Keyboard Maestro 点击屏幕上有特定图案的区域

能否成功按图索骥——字面意义上的——关键在于截取的图案本身是否恰当。如果截取的范围太小(比如只截了一颗按钮),屏幕上很可能会出现多个近似区域,导致无法瞄准;而如果截取的范围太大,则如果软件布局稍有变动,那么 Keyboard Maestro 也无法点中相应位置——这就像检索文献,关键词太短则目标过多,关键词太长则容易查不到任何内容。在截取图案时,可以多观察不同场景下的软件界面,试着缩放窗口或把窗口移动到屏幕的各个角落,以确保所截图案总是保持稳定。如果实在拿不准,可以向右拨动途中的滑块,提升识别图案的模糊程度。

Alt text
截取目标区域图案并测量好要点击哪里

除去图像部分,Click at Found Image 模块与 Move and Click Mouse 大同小异,前者的参数也多见于后者。话说回来,两个模块其实就是一个,只不过在定位方式上有差别,但 Keyboard Maestro 特意区分,我也萧规曹随。和优化预览工具类似,我也为 PDF Expert 打造了一套高亮标注工具,详细方法可参见《用 Keyboard Maestro 为 PDF Expert 打造个性化批注工具箱》,而核心的交互自动化见诸本节。

Alt text
通过 Keyboard Maestro 在 PDF Expert 中切换不同的高亮颜色

Tips:恢复鼠标状态

设计 Macro 时,一旦完成主要的建设任务,就应当开始考虑环保问题:避免自动化对日常操作产生各种形式的干扰和影响。处理文本时可能出现剪贴板污染,覆盖剪贴板中原有的数据;交互自动化中,由于模拟了鼠标移动——相当于有第二只手把你的光标拖过去——也会导致光标位置污染。与之前处理剪贴板污染的思路类似,我在 Move and Click Mouse 和 Click at Found Image 模块前后也添加了保护机制,以在动作运行后恢复鼠标的原始位置

在准备移动鼠标前,先添加一个模块:Set Variable “变量名” to Text “%CurrentMouse%”,其中的 %CurrentMouse% Token 表示光标当前位置的座标。移动和点击鼠标结束后,再添加一个模块:Use Variable “变量名” to Set the Mouse Location,根据之前提取的光标座标,再把光标移回去。通常情况下,在按下并释放快捷键的几分之一秒到一秒多时间里,光标就会回到原始位置,干扰轻微。

惟需注意,既然是操控光标,那么 Trigger 就不适合设置为鼠标或触控板,以免用户操作和 Keyboard Maestro 产生冲突。


  1. 严格来说,还可以写 Object-C 脚本,但是要求过高,往往在软件开发的语境下才会触及这一工具,自动化玩家通常不会考虑那么底层的方案。
  2. 说是上古,因为多数有意思的 AppleScript 脚本都是多年以前编写的。AppleScript 本身于 1993 年推出。
  3. 当然也有很多人是为了让 Windows 迁移过来的用户感到亲切,所以才觉得这个例子。
  4. 严格来说是左边的菜单栏,而不包括右侧,故一些菜单栏小工具就比较难自动化。
  5. 从设计的角度看,最好添加注释,注明快捷键对应的操作,以免自己都想不起来某个步骤有何用途。毕竟,知道菜单栏项目后查询快捷键很方便,但只知道键位则很难查到对应操作。
  6. 不过这些软件本身很可能支持自定义快捷键,不一定非要用 Keyboard Maestro。具体视各人场景而定,像我这样只用一台 MacBook 的人,就倾向于用 Keyboard Maestro 统御尽可能多的软件;而如果您需要在多台电脑甚至多个系统之间同步软件设置,可能用软件自带键位设置更合适,例如 Obsidian 就可以同步配置文件。
  7. 好在 Keyboard Maestro 在后来的版本中已经新增了一键切换输入法的模块 Set Keyboard Layout。这个例子其实对 AppleScript 不公平,因为 Keyboard Maestro 只能模拟点击左侧的菜单栏,而右边的还是得交给 AppleScript,不过举例的目的是非常容易理解的:脚本过于复杂,而 Keyboard Maestro 很简单。
  8. 这里的复制是“Duplicate”之意,是难得的“就地复制”之例。
  9. DEVONthink 在赌气式的 3.9 版更新中支持了段落链接,但其竟然是将完整段落编入 URL Scheme,这种动辄几页纸的链接根本就是报复用户,为此还牺牲了拷贝 page link 的按钮、为所谓的新功能腾出空间。这次更新导致我有一批涉及 page link 的动作部分失效,包括 Anki 摘抄
  10. 我是如此痛恨二级菜单栏或工具栏,以至于将构思分享给 Legolas,建议制作一款没有二级菜单栏的手写笔记软件
  11. 严格来说也可能会变,比如外接显示器的分辨率非常低、颗粒度非常明显(而当前在售的 MacBook 分辨率均非常高),那么两个位置之间的向量就不是 (-30,30)。经测试,在 27 英寸的2K显示屏上可能出现定位偏移,而在4K或更高规格的屏幕上则不易出错。
  12. 再举一例:模拟点击右键,就可以展开右键菜单,此法可用于获取当前光标所在位置的链接,在 2-2-1 节中有具体用例。

author_avatar

Lawyer, macOS/iOS Automation Amateur