Minimize each application in a list?

I want to minimize each app in a list so I can replace this with something more reasonable? I’ve tried various AppleScripts, but nothing seems to work reliably when iterating over multiple virtual desktops on multiple screens. This sequence works fine, but is cumbersome.

If you mean by reasonable you mean dynamic, Keyboard Maestro Engine's "do script" on action XML can approximate a "runtime action" into which you can plug a list of applications whose front windows you want to minimize.

Use the Minimize action's XML as a template in an Execute an AppleScript, with a placeholder variable for one of the application key values--name, bundle identifier, or path. Import a list of the chosen values. For each list item set the value of the placeholder variable to the item's the value, such as bundle identifier, and run "do script" on it.

Below is a macro that demos the technique with bundle identifiers.

  • Enable the macro group and the macro and run it.

  • A Prompt With List will show a list of running applications and output a text list of corresponding bundle identifiers.

  • An Execute an AppleScript will create a Minimize action for each bundle identifier from xml and run it with "do script".

use AppleScript version "2.4"
use scripting additions
property author : "@CRLF"
set kminstance to system attribute "KMINSTANCE"
tell application id "com.stairways.keyboardmaestro.engine"
	set processBIDs to getvariable "localProcessBundleIDs" instance kminstance
end tell

set processBIDs to paragraphs of processBIDs

tell application id "com.stairways.keyboardmaestro.engine"
	repeat with aBundleID in processBIDs
		if contents of aBundleID is not "" then
			set kmScript to my minimizeFrontWindowOfAppByBundleIDXML(aBundleID)
			do script kmScript
		end if
	end repeat
end tell

on minimizeFrontWindowOfAppByBundleIDXML(theBundleID)
	"<array>
        <dict>
            <key>Action</key>
            <string>ReallyMinimizeWindow</string>
            <key>HeightExpression</key>
            <string>300</string>
            <key>HorizontalExpression</key>
            <string>125</string>
            <key>MacroActionType</key>
            <string>ManipulateWindow</string>
            <key>TargetApplication</key>
            <dict>
                <key>BundleIdentifier</key>
                <string>" & theBundleID & "</string>
                <key>Match</key>
                <string>BundleID</string>
                <key>Name</key>
                <string></string>
                <key>NewFile</key>
                <string></string>
            </dict>
            <key>Targeting</key>
            <string>FrontWindow</string>
            <key>TargetingType</key>
            <string>Specific</string>
            <key>VerticalExpression</key>
            <string>125</string>
            <key>WidthExpression</key>
            <string>300</string>
            <key>WindowIndexExpression</key>
            <string>2</string>
            <key>WindowName</key>
            <string></string>
        </dict>
</array>"
end minimizeFrontWindowOfAppByBundleIDXML

If it runs as expected, you can hard-code a text list of the bundle identifiers you want to target and add to or delete from the list as needed. Enable the two green actions to display the bundle identifiers chosen from the Prompt With List in a window where you can copy and paste them into the Set Variable to localProcessBundleIDs action.

When you no longer need the Prompt From List action and the Display Text in Window. disable them.

Minimize front window of chosen running applications.kmmacros (8.8 KB)

Image

I can hide apps, usually. For those apps that become unhidden when I move between spaces, and it happens all the time unexpectedly, I found that I need to minimize the windows of each app that reappears unexpected. If I can minimize THOSE apps, all is good.
So, What I want is to have a list, e.g. “Messages”, “Safari”, “Mail”, and a KM Macro to minimize each app in that list.

If what you have works you just need to fill in the Set Variable to localProcessBundleIDs to something like this:

Then delete or disable everything except that Set Variable action and the Execute an AppleScript.

It should work exactly as the hard-coded actions, but with a list that you can edit as needed.

However if what you're after is an AppleScript to minimize all windows of an app, I'm not sure I'd know how the AppleScripts that you've been trying have failed or how to fix them. I'm afraid I don't know anything about virtual desktops on other screens, which I why stuck with what you said was working for you and just tried to move the Minimize action into an AppleScript where it could be modified on the fly.

FWIW, this is the AppleScript that I might use to do the same thing as you posted for a single desktop.

set kminstance to system attribute "KMINSTANCE"
tell application id "com.stairways.keyboardmaestro.engine"
	set processNames to getvariable "localProcessNames" instance kminstance
end tell


if name of current application is not "osascript" then
	set processNames to ¬
		"Finder
Keyboard Maestro
TextEdit"
end if
set processNames to paragraphs of processNames


repeat with procName in processNames
	tell application id "com.apple.systemevents" to tell application process procName
		tell (first window whose value of attribute "AXMinimized" is false)
			if it exists then
				set value of attribute "AXMinimized" to true
			end if
		end tell
	end tell
end repeat

Edit: The AppleScript above is fixed

I think I get your point. I’ll give it a try when I get a chance (soon).

Great! Will be offline for a while but will check in to see how it's going.

How about this:

It assumes all apps in the list are running and have at least one window.

set kmInst to system attribute "KMINSTANCE"
tell application "Keyboard Maestro Engine"
	set appName to getvariable "Local_Line" instance kmInst
end tell

tell application "System Events"
	tell process appName
		set value of attribute "AXMinimized" of window 1 to true
	end tell
end tell

I have two questions:

  1. Why can’t I put the list (local_AppList) inline to the AppleScript as a list of strings?
  2. I can easily check if the app is running. Is there an easy way to ask if there are more than zero windows?

Thanks for the help.

For whom?

Unless I'm missing something, there is no reason--other than the convenience of entering the list in KM--not to hard-code your application list into the AppleScript.

You could do this:

set processNames to "Finder
Keyboard Maestro
TextEdit"

set processNames to paragraphs of processNames

Or this:

set processNames to {"Finder", "Keyboard Maestro", "TextEdit"}

This certainly would make it easier, in the case of @evanfuchs AppleScript, to run the loop inside one AppleScript and avoid the cost of loading a new AppleScript each time you minimize the window of a process.

It sounds like you're now considering mimimizing more than one window?

Directly using AppleScript for UI scripting the window(s) and not the KM action for minimizing the front window?

If so, it would seem minimizing window(s) via AppleScript UI scripting for virtual desktops is now a viable method for you?

It would be helpful to know if it is is back on the table. I am curious what has changed.

Anyway, yes. You might check for the count of unminimized windows, for example, and either choose to minimize the front one:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

set processNames to "Finder
Keyboard Maestro
TextEdit"

set processNames to paragraphs of processNames

set processNames to {"Finder", "Keyboard Maestro", "TextEdit"}

tell application id "com.apple.systemevents"
	repeat with procName in processNames
		if application process procName exists then
		tell application process procName
			set winList to (windows whose value of attribute "AXMinimized" is false)
			if (count of winList) > 0 then
				tell item 1 of winList --minimize the first unminimized window
					set value of attribute "AXMinimized" to true
				end tell
				--minimize all unminimized windows
				--set value of attribute "AXMinimized" of (windows whose value of attribute "AXMinimized" is false) to true				
			end if
		end tell
		end if
	end repeat
end tell

EDIT: The script now checks if the running process exists.

Or all of them by uncommenting (remove the prefix, "--" ) this.

-- set value of attribute "AXMinimized" of (windows whose value of attribute "AXMinimized" is false) to true

and delete:

				tell item 1 of winList --minimize the first unminimized window
					set value of attribute "AXMinimized" to true
				end tell
1 Like

My example is super basic and straightforward to edit the list of apps, but @CRLF ‘s is the way to go.

OK, problem is now solved. It turned out to be surprisingly simple. Here’s the solution:

Hide Stubborn Apps.kmmacros (3.9 KB)

Great. I've fixed my script to check for existence of a running process per your solution.

I'm glad you got your AppleScript working!