Reference to application immediately below the frontmost application

Hello.

When a script is saved as an application it becomes the application in front and the application that is the target in the code is relegated to sit on a plane immediately below the executable, and it is no longer possible to reference “the application in front”.

One would need to refer to the application that is just below the frontmost application.

Any help to solve this situation?

Thanks in advance.

This may do what you want and, if not, could you give a concrete example?

tell application "System Events"
	set openApps to name of every process whose background only is false
	set activeApp to name of first process whose frontmost is true
end tell

repeat with i from (count openApps) to 1 by -1
	if item i of openApps = activeApp then exit repeat
end repeat

display alert "The frontmost app is " & (item i of openApps) & ". The app just below the frontmost app is " & (item (i - 1) of openApps) & "."

If you don’t mind using ASObjC, the following is about 8 times faster, once the necessary frameworks are in memory:

use framework "AppKit"
use framework "Foundation"
use scripting additions

set theWorkspace to current application's NSWorkspace's sharedWorkspace()
set openApps to theWorkspace's runningApplications()
set thePredicate to current application's NSPredicate's predicateWithFormat:"activationPolicy = 0"
set openApps to openApps's filteredArrayUsingPredicate:thePredicate
set activeApp to theWorkspace's frontmostApplication()
set formerApp to (openApps's objectAtIndex:((openApps's indexOfObject:activeApp) - 1))'s localizedName as text

display alert "The active app is " & (activeApp's localizedName as text) & ". The former app is " & formerApp & "."

tell application “System Events”
set theName to name of the first process whose frontmost is true
end tell

tell application “System Events”
tell process theName
set windowCount to count windows
display dialog “Application " & theName & " : " & windowCount & " windows”
end tell
end tell

If I run this script on my Mac and if Script Editor is in front and we save the script as windowCount.scpt the result is, for example,

Application Script Editor : 3 windows

But if I were to send a friend the same script in the form of windowCount.app and run it on his Mac, windowCount.app is in the foreground and the result is

WindowCount.app : 0 windows

(Note that in the code there is no target application name explicitly, but implicitly being the application that is in front; when you run windowCount.scpt the application in front is the application that is in front at the time of execution; however, when in the form of windowCount.app the .app itself will be the application in front and the result will be 0 windows.)

For that reason, my question is how to make the windowCount.app (application in front) focus on the application immediately below it (e.g. Script Editor) to get the desired result (number of windows of the Script Editor application).

Thank you very much for your time and knowledge.

Regards.

The following works in my testing on Catalina:

tell application "System Events"
	set activeApp to name of first process whose frontmost is true
	set openApps to name of every process whose background only is false
end tell

repeat with i from (count openApps) to 1 by -1
	if item i of openApps = activeApp then exit repeat
end repeat

set formerAppName to item (i - 1) of openApps
tell application "System Events"
	tell process formerAppName
		set windowCount to count windows
		display dialog "Application " & formerAppName & " : " & windowCount & " windows"
	end tell
end tell

A few comments:

  • I tested the above script by saving it to the desktop as an app and double clicking on it.

  • Script Editor has a bug and does not reliably report the number of open windows, so it’s best to test this script with another app, like Safari.

  • The name of an app and that app’s process name are not always the same. It’s rare that there’s a difference but this could be an issue.

Hello, peavine.

Unfortunately I have not been able to corroborate the performance of your proposal.

Even if there are several open windows of the same application the result of open windows is always 1 and when the proposal is saved as .app the response is zero.

In any case, I think there is no proper understanding of the issue (maybe I don’t know how to properly state the question).

The fundamental core of the question is how to get a code that focuses the focus on an application located in the immediate background and implicitly referenced (without naming it by name, for versatility). It would be something similar to making the foreground application the one that would have been used immediately before running the executable file.

Thank you very much, in any case, for your availability and help.

The answer is that, via AppleScript, you can’t – scripting has no access to application z-order. There was a thread here a long time ago that had a workaround, but I have no idea if it still works.

Shane Stanley and peavine

Thank you very much for your time and kindness in helping me.

Regards. :slight_smile:

I think, the OP asked for simple hiding like this:


tell application "System Events"
	set visible of (first process whose frontmost is true) to false -- hide front process
	set appName to name of (first process whose frontmost is true) -- this process is front now
end tell

tell application appName
	display dialog "Application " & appName & " : " & (count of its windows) & " windows"
end tell

DJUNQUERA. My suggestion contains a really dumb mistake. Sorry about that.

property theName : missing value

tell application "System Events"
	keystroke "h" using {command down} -- Hides this "windowCount.app" after launch
	
	(* since the chances are you will be launching this "windowCount.app" from
	Finder, It's gonna return the Finder's window count.  The delay 3 command gives you time to 
	bring a different app to the front.  However, if you save this "windowCount.app" to
	the Script Menu in the menu bar and run it from there, It's gonna return the
	window count of the current visible app.*)
	
	delay 3
	set theName to name of every process whose visible is true and name is not name of me
	repeat with i in theName
		if application process i is frontmost then
			set theName to i
			exit repeat
		end if
	end repeat
	tell process theName
		set windowCount to count windows
	end tell
end tell

activate
display dialog "Application " & theName & " : " & windowCount & " windows" giving up after 5

Hi, KniazidisR

Your script works perfectly when saved as .scpt (when hiding the foreground application, it foregrounds the application immediately below it, leaving it ready to receive subsequent instructions.
However, when saved as .app I have not been able to get result.

Receive my sincere gratitude for your help.:slight_smile:

Hello, wch1zpink

Your script works perfectly, both when saved as .scpt and .app.

Reading the code has been easily understood despite my low level of knowledge.

The screenshot has been clarifying. Providing a timeout for the user to choose the application to which the script instructions will be directed is an idea that I will take advantage of for future scripts.

I think your solution will make it easier to send utilities in the form of .app files to people without any knowledge of AppleScript by bypassing the inconvenience of the executable being the application in front of it.

Thank you very much for your time and expertise in solving this problem.:slight_smile: