How do I stop repeat by clicking away from active window or pressing a key using AppleScript? I'm attempting to write an AppleScript that keeps repeating an action until you press a key or click away from the active window. How would I go about doing that?

repeat repeatTimes times
tell application "System Events"

    keystroke firstText
    keystroke return
    delay firstDelay

    keystroke secondText
    keystroke return
    delay secondDelay

end tell
end repeat


i would prefer to modify repeat repeatTimes times to until keypress (any keypress) or until app not active or something. any ideas?
After a bit of researching, I came up with a 75% solution to your question.  The script below will repeat the actions inside the loop until one of two assertions are met:

① The window that has focus now is different to the window that had focus before;

② A modifier key out of either fn, ⌃, ⌥ and ⌘ is pressed.

I tried to find a solution that permits testing for any keydown event, but was only able to find a solution involving the modifier keys.  AppleScript alone cannot listen for key events, however AppleScript-ObjC can.  Perhaps another person will be able to provide the full solution that allows for monitoring of any key pressing.

I've added comments within the script to help guide you through what each part does.  Bear in mind, this is just an example script demonstrating one possible way of implementing these methods to achieve your objective:

    use sys : application "System Events"
    use framework "Cocoa"


    set [firstText, secondText] to ["A", "B"]
    set [firstDelay, secondDelay] to [0.2, 0.3]


    # Open up a new TextEdit document into which
    # the keystrokes can produce output
    tell application "TextEdit"
        activate

        set D to make new document
    end tell


    # Get frontmost window of the frontmost application
    set P to a reference to (the first process whose frontmost is true)
    set W to the front window of P


    # Repeat loop will break if the focussed window changes
    repeat until the front window of P is not equal to W

        tell sys to keystroke [firstText, return] as text
        if modifierKeydown() then exit repeat # Exit on keypress

        delay firstDelay

        tell sys to keystroke [secondText, return] as text
        if modifierKeydown() then exit repeat # Exit on keypress

        delay secondDelay

        if modifierKeydown() then exit repeat # Exit on keypress

    end repeat


    close D without saving # Close the TextEdit document


    # Returns true if any of
    # { function, control, option, command }
    # are depressed; false otherwise
    on modifierKeydown()

        set __m to current application's ¬
            NSEvent's modifierFlags() as any

        return (__m &gt; 262143)

    end modifierKeydown


Note that the repeat loop checks for modifier keydown status a number of times within a single iteration.  I experimented with checking once, which necessitated holding down the modifier key for such a time until the loop was able to arrive at the checkpoint; and three times, which shortens the waiting time but at the expense of time that might be otherwise spent processing other actions within the loop (i.e. it will add to the delay times already in place between commands).

There's no right or wrong there—you'll have to play around with it and see what feels best for you.

Likewise, the check performed on window focus is only done once per iteration, which is actually very sufficient.  However, you will notice that clicking away from the window is ever so slightly obstructed by the attention given to performing the actions inside the loop.  It's not a problem at all, it just makes changing windows something done with more intent that normal.

None of that is surprising, however, given what this script is doing and how it's doing it.

Let me know how you get on, and if you have any questions or problems, leave a comment and I'll do my best to assist.