I want to program my mouse button to show/hide the Finder. I wrote the following AppleScript and bound it to my mouse button:
tell application "System Events"
--When this script is run,
-- the frontmost application will be this script itself
--Get the name of this script as it is running and hide it,
-- so that the previous frontmost application is in front again
set theName to name of the first process whose frontmost is true
set visible of process theName to false
set theName to name of the first process whose frontmost is true
end tell
if theName is "Finder" then
tell application "System Events"
set visible of process "Finder" to false
end tell
else
tell application "Finder"
activate
end tell
end if
This works, but is rather slow. It takes about 2 seconds to run.
I want it to be faster. The first tell block uses System Events to get the name of the script and hide it. Is there an easier/faster way to get the name of the frontmost application before the script starts? (i.e. the application that was active when the script was activated)
The reason for the slow run time is that I saved the applescript as an Application. This makes the application PPC-only so it must run under Rosetta. If you choose Application Bundle, it will make a universal application.
Related
I try to get the title of an app (and copy it as a var)
Here is my code so far but this is failing
tell application "app"
activate
end tell
tell application "System Events"
set frontApp to name of first application process whose frontmost is true
end tell
tell application frontApp
if the (count of windows) is not 0 then
set window_name to name of front window
end if
end tell
Result :
error "app got an error: every window doesn’t understand the “count” message." number -1708 from every window
The error message suggests that the frontmost application is not scriptable.
The only way to target a non-scriptable application's windows is via the properties of [application] process objects from the System Events context - not via its application object (only scriptable application objects have windows elements):
tell application "app"
activate
end tell
tell application "System Events"
# Get the frontmost app's *process* object.
set frontAppProcess to first application process whose frontmost is true
end tell
# Tell the *process* to count its windows and return its front window's name.
tell frontAppProcess
if count of windows > 0 then
set window_name to name of front window
end if
end tell
So I have a very basic Applescript here that basically hides all my social networking related apps, and then a similar one that unhides them. Problem is that if one of these apps isn't running then the entire thing halts at that line and won't set the ones below that line to hidden either.
Here's the script:
tell application "System Events" to set visible of process "Twitter" to false
tell application "System Events" to set visible of process "Wedge" to false
tell application "System Events" to set visible of process "Facebook" to false
tell application "System Events" to set visible of process "Adium" to false
tell application "System Events" to set visible of process "Messages" to false
Am I doing this the wrong way? Do I have to check to see if each one of these is running first, or is there some way to get it to continue with the script either way?
EDIT: Experiencing the same thing with this script, which I use with an Alfred hotkey to quit specific apps and start the screensaver when I leave work:
tell application "Adium" to quit
tell application "Messages" to quit
tell application "1Password" to quit
tell application "iTunes" to quit
tell application "ScreenSaverEngine" to activate
So basically if iTunes - for instance - isn't running then the screensaver will not start, but the 3 apps before that line will all quit.
You can wrap each statement in a try block so it will fail silently:
set myApps to {"iTunes", "1Password"}
repeat with anApp in myApps
try
tell application anApp to quit
end try
end repeat
You Could use the try command as specified above and use on error do nothing to do it.
Hint: with the [Enhanced Application Object Model][1] you can also do things like this:
if application "iTunes" is running then
tell application "iTunes" to quit
end if
or
tell application "iTunes"
if it is running then
pause
end if
end tell
[ How to check in AppleScript if an app is running, without launching it - via osascript utility ]
I created a code that toggles the keyboard viewer in Automator.
on run {input, parameters}
if application "KeyboardViewer" is running then
quit application "KeyboardViewer"
else
activate application "KeyboardViewer"
end if
return input
end run
However, the Keyboard Viewer becomes the current running window and I cannot instantaneously start typing (I have to switch back to the previous window). Is there a specific code that I can add so that the previous window is highlighted again ?
You could use launch instead of activate:
tell application "KeyboardViewer"
if running then
quit
else
launch
end if
end tell
If the application wasn't open, launch usually opens a new window above other applications but below the frontmost application. Otherwise it just keeps the application on the background. You can use AXRaise to raise windows in the second case, but it also makes them look like active windows.
launch application "Terminal"
tell application "System Events" to tell process "Terminal"
perform action "AXRaise" of windows
end tell
You could also save the previous application in a variable:
set a to path to frontmost application as text
activate application "Terminal"
activate application a
If you're moving focus to a background application, you can just activate the frontmost application later:
try
tell application "SystemUIServer"
display dialog "" default answer ""
end tell
end try
activate application (path to frontmost application as text)
Try this just after the activate application "KeyboardViewer" line...
tell application "System Events" to keystroke tab using command down
EDIT: Since the original post above didn't do it for you then try this. It uses a subroutine I use to get the frontmost running application in cases just like this. Just put this code into the applescript section of your automator action...
on run {input, parameters}
if application "KeyboardViewer" is running then
quit application "KeyboardViewer"
else
set frontAppPath to my getFrontAppPath()
activate application "KeyboardViewer"
delay 0.2
tell application frontAppPath to activate
end if
return input
end run
on getFrontAppPath()
set frontAppPath to (path to frontmost application) as text
set myPath to (path to me) as text
if frontAppPath is myPath then
try
tell application "Finder" to set bundleID to id of file myPath
tell application "System Events" to set visible of (first process whose bundle identifier is bundleID) to false
-- we need to delay because it takes time for the process to hide
-- I noticed this when running the code as an application from the applescript menu bar item
set inTime to current date
repeat
set frontAppPath to (path to frontmost application) as text
if frontAppPath is not myPath then exit repeat
if (current date) - inTime is greater than 1 then exit repeat
end repeat
end try
end if
return frontAppPath
end getFrontAppPath
I'm scripting iTunes with applescript using UI scripting. Depending on what I'm doing an iTunes notification will appear, at which point I need to handle it. The name of the window is AXWindow: "", and I can't seam to get applescript to handle it. I've tried using the literal "", I've tried defining a variable to "", I've tried both cases with escape characters, and I've tried getting the name of the frontmost process.
tell application "System Events"
set processName to name of front window
end tell
tell button "whatever" of window processName
click
end tell
But that comes up with "error "System Events got an error: Can't get window 1. Invalid Index."" Any help on this would be greatly appreciated.
You can do something like this:
tell application "iTunes" to activate
tell application "System Events"
tell process "iTunes"
set xxx to first UI element whose role description is "dialog"
end tell
end tell
Or to find them all:
tell application "iTunes" to activate
tell application "System Events"
tell process "iTunes"
set xxx to every UI element
end tell
end tell
Well, usually notifications or user dialogs will show up as the frontmost window and stay on top of the other windows of the same application until the user (or the script) clicks something.
Thus, the dialog window (if there is any) should be accessible via the specifier window 1. You can then further check if that really is the window you're interested in by reading its properties:
tell application "System Events" to tell application process "iTunes"
properties of window 1
end tell
I have the following applescript to skip songs in spotify. If I call the script when a fullscreen application is the frontmost, the application will not be visible after the script has finished. It will be in a different space. Is there a way that I can make the frontmost application visible again with applescript?
set front_app to (path to frontmost application as Unicode text)
tell application "Spotify"
next track
end tell
tell application front_app to activate
This probably won't get you anywhere, but you could use this script to loop through all your spaces until you see the application you're targeting...
set front_application to current application
tell application "Spotify" to next track
tell application "Finder" to set collapsed of front_application to false --makes sure the app isn't minimized
repeat
tell application "System Events" to keystroke (ASCII character 29) using {control down}
display dialog "Correct space?" buttons{"OK"} default button 1 giving up after 4 --don't click 'OK' if the current space isn't showing the target application
if gave up of the result is false then exit repeat
end repeat
set front_app to current application
tell application "Spotify"
next track
end tell
tell front_app to activate