如何通过AppleScript在Safari、Chrome等应用多窗口中正确执行模拟按键
解决方案
问题根因
set index of app_window to 1 执行后,Safari、Chrome、Xcode 这类基于 AppKit 多文档架构的应用,窗口层级更新和 UI 焦点更新是异步执行的,你没有等焦点真正切换完成就执行了按键操作,所有按键都会落到还未被切走的旧窗口上。Finder 能正常运行是因为它的窗口焦点切换是同步完成的,不存在延迟问题。
修正后的可运行代码
tell application "Safari" activate set wList to every window whose visible is true repeat with app_window in wList log app_window set index of app_window to 1 -- 等待窗口真正被切换到最前 repeat while front window is not app_window delay 0.1 end repeat -- 给系统事件留足够的焦点同步时间 delay 0.2 tell application "System Events" keystroke "t" using {command down} end tell delay 1 end repeat end tell
该代码替换应用名后可直接用于 Chrome、Xcode 模拟器等同样存在窗口异步切换问题的应用。
关键改动说明
- 新增窗口切换等待逻辑:设置 index 后循环判断当前最前窗口是否为目标窗口,确认切换完成再执行后续操作
- 增加 0.2s 的焦点同步缓冲:确保系统事件层的焦点状态和应用内部的窗口层级保持一致
- 调整 activate 的位置:仅在操作前激活一次应用,避免重复激活打断窗口切换逻辑
更稳定的替代方案(无需模拟按键)
如果你的操作是应用原生 AppleScript 接口支持的行为(比如新建标签页),优先调用原生接口,完全不受焦点切换影响,执行效率更高:
tell application "Safari" set wList to every window whose visible is true repeat with app_window in wList make new tab at end of tabs of app_window end repeat end tell
内容的提问来源于stack exchange,提问作者Rostislav Shtanko
相关产品推荐
相关产品推荐

