Activate the frontmost window of main screen

I have a multiple monitor setup and have a lot of macros that switch windows to different screens.

I need a macro to activate the frontmost window of my main screen. Any app that is in the front most of the main screen.

I could use the click mouse at location but I’m sure there is a better way to do it.

I'm not sure there is...

Apps have a stacking order. Windows have a stacking order within their app. But you can easily have a situation where windows of different apps are interleaved -- for example:

...where Safari is the frontmost app, Preview has the frontmost window on the main screen, but because Safari also has a window on the main screen it is very difficult to disentangle the two.

Unless you have some constraints -- such as "It will always be the second app in the stacking order" or "An app will always have all its windows on a single screen". Even "Click at..." requires the constraint of "Some part of the window to activate will be at this coordinate".

This looks like one of those "So obvious to a human, but difficult for a computer" problems. And I really hope someone pops up with a cunning solution to prove me wrong!

I have come up with a macro that seems to do the trick, but note that it will only work if the size/resolution of each of each of your displays is unique. The macro cannot tell displays apart if they are of identical size (see the follow-up post below).

How it works: for each foreground application that is running, activate the application and if its front window is found to be on the main display, stop.

Activate front application of main display.kmmacros (6.0 KB)

Perhaps someone can think of a remedy for that. Maybe the macro could move the mouse (without clicking) and compare co-ordinates*... but I suspect there will be a less kludgy way to get the information.

* Edit: wut? :grinning_face_with_smiling_eyes:

Which, I think, is functionally equivalent to:

Activate Main Screen Front Window App.kmmacros (4.4 KB)

The problem for me was that could activate multiple apps on the other screen before getting to the target app, and I was assuming (and I should know better...) that OP didn't want that.

1 Like

Hello Kevin (@kevinb) :waving_hand:

I think I might have the solution of your problem. Your Macro doesn’t work with exactly the same Resolution Settings because you forgot to add the condition that tests if the Screen is actually the Main Screen. You only test against the Main Screen‘s Resolution, and that’s not enough.

If you add this to the Macro it will work with multiple Screens at the same Resolution.

To the topic in general - I also tend to work based on this subject and I’ve come up with the solution to write the information for frontmost Applcations and their windows based on the screen or Mission Control Desktop to global variables as soon as they change. This way I can switch to desired Windows of apps much faster without having my Mac’s Screens beeing searched by a macro.

Greetings from Germany :germany:

Tobias

If you can make a list of the apps you want this macro to be able to handle, then I can probably think of a way to do it, but you seem to want the method to work regardless of what apps are on the screen.

I hardly forgot; I highlighted that very issue! As I stated, I couldn’t think of another way to check. The SCREENINDEX functions that @Nige_S used in his version do the job. I shall have to refresh my memory about the functions section of the Wiki again, shan’t I!

An imperfect solution is generally better than none, I think—if only to nudge attempts and discussion forward.

My plan was an unholy alliance of KM's %Application%All% token to get the stacking-ordered list of apps, then iterate through those with AS "System Events" to check the position of the front window of each app without activating it, then pass the first hit back to KM for the "Bring Front Window to Front" action -- which also works without bringing the apps other windows forward.

And then work got in the way... Maybe later, unless someone else wants to jump in and flesh this out.

I have two plans. One plan is to use Find Image, but that depends on whether the apps have findable images in a few places in their window. If they do, it would probably work most of the time. (Although with Tahoe's new translucent windows, it may not work very well.) My second plan relies on OCR, and uses a devious trick: if a window is partially covered, then performing OCR on the visible part of the app's window would probably result in quite a few spelling errors, meaning that that window is partially hidden, therefore not frontmost. Again, this depends on the nature of the app's visible window. And to my surprise, the OCR action doesn't seem to work on windows that aren't frontmost, which makes my work a lot harder. But both of my plans won't work 100% of the time, so I will probably just drop them.

And here it is:

Activate Main Screen Front Window App (AS).kmmacros (4.4 KB)

Image

The meat is in the AppleScript:

Script
set inst to system attribute "KMINSTANCE"
tell application "Keyboard Maestro Engine"
	set appList to getvariable "Local_appList" instance inst
end tell

set appList to every paragraph of appList

tell application "Keyboard Maestro Engine" to set theScreen to process tokens "%Screen%0%"

set AppleScript's text item delimiters to ","
set absScreen to {text item 1 of theScreen as integer, text item 2 of theScreen as integer, ((text item 1 of theScreen) + (text item 3 of theScreen)), ((text item 2 of theScreen) + (text item 4 of theScreen))}

tell application "System Events"
	repeat with eachApp in appList
		tell process eachApp
			set thePos to position of window 1
			set theSize to size of window 1
			set midPoint to {(item 1 of thePos) + (item 1 of theSize) / 2, (item 2 of thePos) + (item 2 of theSize) / 2}
			if (item 1 of midPoint ≥ item 1 of absScreen) and (item 1 of midPoint < item 3 of absScreen) and (item 2 of midPoint ≥ item 2 of absScreen) and (item 2 of midPoint < item 4 of absScreen) then
				set bundleID to bundle identifier
				exit repeat
			end if
		end tell
	end repeat
end tell

set theXML to "<dict>
		<key>Action</key>
		<string>SelectWindow</string>
		<key>MacroActionType</key>
		<string>ManipulateWindow</string>
		<key>TargetApplication</key>
		<dict>
			<key>BundleIdentifier</key>
			<string>" & bundleID & "</string>
			<key>Match</key>
			<string>BundleID</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>"

tell application "Keyboard Maestro Engine" to do script theXML

...which, if nothing else, shows a couple of ways to get values from KM (by variable and process tokens) and an easy built-on-the-fly macro run directly by the KM Engine.

I've used what I think is KM's "is a window on a screen?" test -- is the mid-point of the window within the bounds of the screen?

It has not been tested in weird situations, such as when an intermediate app has all its windows minimised. IMO we're exchanging the "fast but flickering" KM macros above for a smoother, slower (in comparison) user experience -- let's see if it works for people before worrying about edge cases!

1 Like

Yes unfortunately I need it to work with any app.

Yes I am trying to look for the quickest way possible, though this is still a solution.

Thanks for this! I’ll test it out.

If Nige's script doesn't work, you can easily ask AI :brain: to provide you with a piece of Swift code that will activate the frontmost window on your primary display." I asked AI, and it came up with a single KM action that looks like it should work. Of course I couldn't test it because I don't have two displays. So you will have to test it.