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.
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).
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.
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.
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
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
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.
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.