AppleScript:在应用程序窗口上循环;让每个人都领先并在其他应用中触发动作?

时间:2019-07-04 14:17:58

标签: macos applescript

短版

我想编写一些AppleScript,该AppleScript在应用程序的窗口(非最小化)上进行迭代,并针对每个窗口将其置于最前面,并在另一个应用程序BTT中触发某些操作(BTT(将移动窗口))。目的是将应用程序的所有窗口移至同一位置。活动部分(由BTT处理),我只需要帮助使该问题发生在应用程序的所有窗口中即可。

长版

(这个问题涉及BetterTouchTool,但并不是真的-我想-我怀疑您不需要了解有关BTT的任何信息即可回答...)

我正在尝试编写一个AppleScript脚本(当我将其简化为尽可能简单的版本时),它将激活一些应用程序,并在其所有窗口中循环,为每个窗口触发一个BetterTouchTool“命名触发器”。命名触发器的工作是将当前窗口移至某个位置,但是其详细内容无关紧要。

在我看来,这应该很简单,但是我似乎找不到正确的方法。我已经尝试过将其进行培训,但是我什么也没做(除了怀疑,我需要参与“系统事件”)...我是一位经验丰富的程序员,但是我从未深入研究AppleScript和发现它的做事方式很奇怪/令人困惑。

到目前为止,我正在工作的是一个不会在窗口上循环播放的版本,因此它只命中了“第一个”(在某种意义上是“第一个”,它似乎“对于此应用”)。

例如,以下工作。 (我在这里已经将其硬编码为VSCode,尽管在我尝试编写的全部内容中,它会遍历应用名称列表以及为其运行的触发器。)

on run
    if application "Visual Studio Code" is running then
        tell application "Visual Studio Code" to activate
        tell application "BetterTouchTool"
            trigger_named "Move window: monitor 4k: core"
        end tell
    end if
end run

因此将激活VSCode,然后告诉BTT运行一个命名触发器,以将当前窗口移动到屏幕上的某个位置。结果是最近使用的VSCode窗口被移动了。

好的,这不是一个不好的开始,但是我想对所有 VSCode窗口(或者理想情况下,在当前可见的桌面上所有未最小化的窗口)执行此操作。

BTT的AppleScript界面​​似乎不支持针对特定的窗口-它只能在任何活动的应用程序/窗口上工作,因此我需要以某种方式激活/将窗口带到(<)> 呼叫BTT触发器。

我想我需要这样的东西(暂时忽略掉最小化窗户的问题):

on run
    if application "Visual Studio Code" is running then
        tell application "Visual Studio Code" to activate
        repeat with app_window in windows
            bring_window_to_front()
            tell application "BetterTouchTool"
                trigger_named "Move window: monitor 4k: core"
            end tell
        end repeat
    end if
end run

...我不知道该怎么做bring_window_to_front()部分!

(这里也不考虑:其他台式机;但是我可以不用我想而生活。)

有人能指出我正确的方向吗?感谢所有帮助!

摘要

我要:

  • 给出以给定名称标识的应用程序...
  • 获取所有窗口并在它们上循环,并针对每个窗口
  • 激活/将窗口移至最前面(前提是未将窗口最小化)并...
  • 告诉BetterTouchTool以给定名称运行触发器。

上下文

  • MacOS Mojave 10.14.5
  • BetterTouchTouch 3.072(不是我认为这有所区别)

2 个答案:

答案 0 :(得分:0)

是的,您需要系统事件。它可以为您提供所有正在运行且可见的进程(即=应用程序),并为您提供每个窗口列表。

甚至更多,您可以直接更新每个窗口的位置。这是示例脚本,该脚本获取所有应用程序的所有打开的窗口并移动“脚本编辑器”(我为测试而打开)的“库”窗口的位置:

tell application "System Events"
set theProcesses to application processes whose visible is true
repeat with aProcess in theProcesses -- loop thru all visible processes

    set allWindows to every window of aProcess
    repeat with myWindow in allWindows -- for each process, look for all windows

        set Pname to name of aProcess
        set Wname to name of myWindow
        if Pname = "Script Editor" and Wname = "Library" then
            set position of myWindow to {400, 900}
        end if

    end repeat -- window loop
end repeat -- process loop
end tell

答案 1 :(得分:0)

任何可编写脚本的应用程序-我假设“ Visual Studio代码”可以根据您编写的内容进行编写(具有脚本字典)-应该对此代码做出响应:

on run
    if application "Visual Studio Code" is running then
        tell application "Visual Studio Code" to activate
        set wList to every window whose visible is true
        repeat with app_window in wList
            set index of app_window to 1
            delay .5
            tell application "BetterTouchTool"
                trigger_named "Move window: monitor 4k: core"
            end tell
        end repeat
    end if
end run
  • 第4行的... whose visible is true部分不包括隐藏或最小化的窗口。
  • 第6行中的set index of ...命令将每个窗口循环到最前面。

indexvisible是所有AppleScript开发人员都应实现的标准Window属性的一部分,因此,除非应用程序设计人员是完全的业余爱好者,否则他们应该“正常工作”。请确保在“脚本编辑器”中查看脚本字典。有时AppleScript设计人员会添加有用的特殊命令,或者更改标准属性的名称(可能只是令人讨厌)。

我不确定是否需要第7行中的delay .5。我把它扔进去是为了确保在BTT通话之前窗口位于最前面。

除非应用程序不可编写脚本,否则请勿使用GUI脚本编写或系统事件。需要 时,GUI脚本非常有用,但是如果应用程序具有脚本字典,则使用该脚本将更加高效和可靠。 GUI脚本笨拙,缓慢并且容易受到无法预测的破坏。但是,如果您确实需要使用它,则代码是相似的。

tell application "System Events"
    tell process "Visual Studio Code"
        set frontmost to true
        set wlist to every window
        repeat with aWindow in wlist
            tell aWindow
                perform action "AXRaise"
                delay .5
                tell application "BetterTouchTool"
                    trigger_named "Move window: monitor 4k: core"
                end tell
            end tell
        end repeat
    end tell
end tell