Here's a little script that enters text into a document when activated.
tell application "TextEdit"
activate
end tell
delay 0.2
tell application "System Events"
keystroke "Hello World!"
keystroke return
end tell
I stuck the delay in there because otherwise the first few keystrokes tend to trigger before the window is done activating, so I end up with "lo World!" in the document and "Hel" in whatever other window had focus when the script was activated. Is that the proper use of delay, or is there a better way to circumvent that problem?
2 Answers 2
Rather than using System Events to generate keystrokes, consider using TextEdit itself to insert text.
tell application "TextEdit"
activate
tell first document to set its text to its text & "Hello World!\n"
end tell
There is a difference, though: this version always appends "Hello World!" to the end of the document, rather than wherever the cursor happens to be. (Unfortunately, TextEdit's AppleScript dictionary mentions nothing about cursors.)
A side benefit of this approach is that you don't have to grant permission to use Assistive Access to your script.
Assuming that you want to stick with the original plan to insert text wherever the cursor happens to be, you would need something more deterministic than an arbitrary delay.
This script covers all the scenarios that I can think of:
tell application "System Events"
-- In case TextEdit was already running and all windows were closed
repeat until first window of application "TextEdit" exists
tell application "TextEdit" to make new document at the front
delay 0.001
end repeat
-- Ensure TextEdit can have focus
repeat until process "TextEdit" is frontmost
set frontmost of process "TextEdit" to true
delay 0.001
end repeat
-- Give focus to the window
set focused of first window of process "TextEdit" to true
keystroke "Hello world\n"
end tell
In particular, the scenarios I tested include:
- TextEdit was not running at all
- TextEdit was running, but had no document windows at all
- TextEdit was already running with one or more windows
To convince yourself that the technique is sound, try each of these scenarios with the loop bodies commented out, and you should see that the script will wait until the conditions are appropriate before continuing.
There is no guarantee, however, that the user won't deliberately try to induce a race condition while the keystrokes are being sent.
"Hello World!"wherever the cursor happens to be? \$\endgroup\$