How would I automate several delayed commands in AppleScript?
Not sure if you realize it but key stokes sent by System Events goes to the active front most window of the front most application and as such the target must remain front most and you basically cannot use the computer for anything else while the process is happening.
The example AppleScript code, shown below, was tested under macOS Catalina as an AppleScript stay open application, with Language & Region settings in System Preferences set to English (US) — Primary and worked for me without issue1.
- 1 Assumes necessary and appropriate setting in System Preferences > Security & Privacy > Privacy have been set/addressed as needed.
In Script Editor, copy and paste the example AppleScript code into a new document and change "TextEdit"
and "Untitled"
to the appropriate values for the target application and window you want the key stokes to go to. The existing values were for testing purposes.
When saving, on the Save As: sheet, change File Format: to [Application], and under Options: check the [√] Stay open after run handler checkbox.
Example AppleScript code:
property appName : "TextEdit"
property winName : "Untitled"
global theCounter
on run
set theCounter to 0
delay 60
end run
on idle
my isItTimetoSendKeystroke()
return 60
end idle
on isItTimetoSendKeystroke()
set theCounter to theCounter + 1
if (theCounter mod 2) = 0 then
my sendKeystroke("a")
my sendKeystroke("a")
end if
if (theCounter mod 30) = 0 then
my sendKeystroke("b")
end if
if (theCounter mod 60) = 0 then
my sendKeystroke("C")
end if
end isItTimetoSendKeystroke
to sendKeystroke(thisKey)
tell application "System Events"
tell application process appName
set frontmost to true
perform action "AXRaise" of window winName
keystroke thisKey
end tell
end tell
end sendKeystroke
on quit
continue quit
end quit
Notes:
If you are just automating the typing of text into a text box or document, you can delete one of the my sendKeystroke("a")
and change the other to my sendKeystroke("aa")
, otherwise if simulating a key press for, say a game, then you would probably want it as it's currently coded.
UI Scripting can be kludgy and prone to failure.
Some applications will not respond to keystroke
and or key code
commands of System Events, as they are designed not to respond this type of event in this manner. Games are the typical type of application that may not respond.
Personally, I do not like this type of UI Scripting and have posted this more just as a proof of concept. It has been my experience that some AppleScript stay open applications can over time consume more memory and eventually crash. They can also cause the fans to spin up and maintain high RPMs. This probably has to do more so with some of the code being run, however, as a general rule I try to accomplish the task in a different way that does not become resource intensive, if possible.
Credit to Tetsujin for his comment to the OP, which was the basis for this answer.
Note: The example AppleScript code is just that and sans any included error handling does not contain any additional error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors. Additionally, the use of the delay command may be necessary between events where appropriate, e.g. delay 0.5
, with the value of the delay set appropriately.