0

我正在尝试编写一个 AppleScript,由 MacOS 上的 Keyboard Maestro 中的热键触发

我想做什么,请不要提出任何其他建议,例如 hide all或 hide features。我正在寻找最小化所有打开的窗口功能,包括动画

我已经可以全部隐藏了。

所以我想要做的是迭代 所有打开的窗口,并触发菜单选项Window -> Minimize或者如果可能的话,以不同的方式触发最小化。

这是我到目前为止所拥有的,但它并没有完全工作,只是部分工作:

tell application "System Events"
    set currentProcesses to name of every application process whose visible = true
end tell

repeat with tmpProcess in currentProcesses

    tell application "System Events" to tell process tmpProcess

        set frontmost to true
        ---activate

        tell menu bar item "Window" of menu bar 1
            click menu item "Minimize" of menu 1
        end tell

    end tell

    delay 1

end repeat

请注意,某些应用程序将具有Minimize without az for Minimize。. 如果解决方案触发了一些全局最小化操作不是通过菜单 系统,那就太好了。

4

4 回答 4

2

这是我对您提出的问题的原始答案,据说应该在最近(ish)版本的 MacOS 中工作:

    use application "System Events"


    set _P to a reference to (every process whose class of windows contains window)
    set _W to a reference to (windows of _P whose value of attribute "AXMinimized" is false)

    set value of attribute "AXMinimized" of _W to true

我可以补充的是,如果我们将每个变量的值插入到引用它的下一行,并且(为简单起见)选择忽略针对进程和窗口使用的过滤,那么很明显,这四行将评估在编译到这一行代码时:

    tell application "System Events" to set value of attribute "AXMinimized" of windows of processes to false

但是,您(OP)报告说它很慢并且并不总是可靠的,并且可能没有使用迭代方法而是递归方法。

我正在等待发现上述脚本不可靠的情况的详细信息。

您问我是否可以为您提出的方法之一生成具有类似迭代性质/结构的代码。

这是将我的原始脚本的功能与您的代码结构相结合的脚本:

    use application "System Events"


    get the name of every application process whose class of windows contains window

    repeat with P in the result

        get (every window of process (contents of P) whose value of attribute "AXMinimized" is false)

        repeat with W in the result

            set the value of attribute "AXMinimized" of (contents of W) to true

        end repeat  

    end repeat

就像您的脚本一样,这里的脚本显式地遍历针对过滤器检索到的所有应用程序进程(您的过滤器是visibleeach的属性process,而我的过滤器是windoweach 的对象的集合process)。如果您觉得有必要,您可以自由更改。

但是,一旦进入repeat遍历 的循环processes,您的脚本忽略做的是遍历属于每个进程的每个窗口。这就是为什么您需要将visible属性设置为 的回退语句的原因false,这只是隐藏应用程序进程(您在 OP 中明确声明您不想做的事情)。

如果没有visible设置该属性,则执行的唯一其他操作是为每个进程单击一次Minimize菜单项。这将触发该应用程序进程的窗口(即当前具有焦点的窗口)最小化,但属于它的所有其他窗口不受影响,这意味着每个应用程序进程只有一个窗口将被最小化。其余的都被可见性切换隐藏了。

对此的补救措施是在第一个循环内设置第二个repeat循环,该循环遍历针对过滤器检索到的特定进程的所有窗口(和以前一样,我选择作为AXMinimized属性)。

然后只需将AXMinimized每个窗口的属性设置为true.

正如您所指出的,您的脚本的一个优点是它似乎比我的更快地最小化窗口。据我所知,出于某种原因,使用菜单触发实际最小化动画似乎比通过设置属性值触发时更快。因此,我继续创建了一个脚本,该脚本不尝试设置窗口的属性,而是使用您单击Minimize菜单项的机制:

    use application "System Events"


    set _P to a reference to (every application process whose visible is true)

    repeat with P in (_P as list)
        set frontmost of P to true

        set _M to (a reference to menu 1 of menu bar item "Window" of menu bar 1 of P)
        set _minimise to (a reference to menu item "Minimise" of _M)
        set _minimize to (a reference to menu item "Minimize" of _M)


        set _W to windows of P
        set n to count _W

        if n > 0 then perform action "AXRaise" of _W's front item

        repeat n times
            if (_minimize exists) and (_minimize is enabled) then
                click _minimize
            else if (_minimise exists) and (_minimise is enabled) then
                click _minimise
            end if
        end repeat
    end repeat

该脚本本质上是您的修改版本,对其进程使用相同的过滤标准 ( whose visible is false) 并单击菜单项Minimize(或Minimise) 以最小化窗口。它包含 的外部repeat循环processes和 的内部repeat循环windows

老实说,很难说哪个似乎比另一个更快地最小化窗口,所以我会让你来判断。

然而,回顾你在最初的简报中所说的话,你特别问:

  • 对于“全局最小化操作而不是 [to] 通过菜单系统”
  • 不提供其他建议“例如‘隐藏所有’或‘隐藏’功能。我正在寻找[a]‘最小化所有打开的窗口’功能”
  • [包括]动画。”

坦率地说,仍然只有一个解决方案可以满足所有这些标准,这就是我发布的原始答案。您发现的其他解决方案要么不起作用,要么依赖于隐藏应用程序窗口;我在上面提供的最后一个贡献是有效的,但是使用了菜单项,这不是您理想的方法;以及之前的脚本,它首先演示了两个repeat循环的嵌套以遍历进程窗口,可以通过归纳推理证明是与我的原始解决方案相同的脚本,尽管没有明确的迭代语句,你是习惯于在编程语言中看到,仍然会在幕后遍历process和对象。window

当然,您可以选择您想要的任何方法,因为您的项目和最终的满意度对于创建您将成为日常使用的工具很重要。但是,为了就实现您打算做的事情的最佳方法给出我诚实和最终的意见,我强烈建议您选择我的第一个答案的压缩形式,这是非常优雅和简单的代码行:

tell application "System Events" to set value of attribute "AXMinimized" of windows of processes to false
于 2018-03-15T10:10:05.137 回答
0

我相信我至少能够从上面的版本中获得一个工作版本。

我想当菜单最小化不存在时我遇到了一些错误,所以我为此添加了 try catch,并添加了一个后备隐藏。

该脚本应该可以工作:

tell application "System Events"
    set currentProcesses to name of every application process whose visible = true
end tell

repeat with tmpProcess in currentProcesses

    tell application "System Events" to tell process tmpProcess
        set frontmost to true

        try
            tell menu bar item "Window" of menu bar 1

                try
                    click menu item "Minimize" of menu 1
                on error
                    try
                        click menu item "Minimise" of menu 1
                    on error 
                        --- Optional, fallback
                        set visible to false
                    end try
                end try

            end tell

        on error
            --- Optional, fallback  
            set visible to false

        end try

    end tell

    delay 0.005

end repeat
于 2018-03-14T22:56:16.380 回答
0

网上找到的另一个较慢的解决方案:

tell application "System Events"

    repeat with appProc in (every application process whose visible is true)

        click (first button of every window of appProc whose role description is "minimize button")

    end repeat

end tell 
于 2018-03-14T23:05:30.460 回答
-1

另一个工作示例,迄今为止最好的。

tell application "System Events"
    set currentProcesses to name of every application process whose visible = true
end tell

repeat with tmpProcess in currentProcesses

    tell application "System Events" to tell process tmpProcess
        set frontmost to true

        try
            tell menu bar item "Window" of menu bar 1

                try
                    click menu item "Minimize" of menu 1
                on error
                    try
                        click menu item "Minimise" of menu 1
                    end try
                end try

            end tell

        end try

        delay 0.1

        set visible to false

    end tell


end repeat
于 2018-03-17T16:03:27.330 回答