¿Cómo detengo la repetición haciendo clic fuera de la ventana activa o presionando una tecla con AppleScript?

0

Estoy intentando escribir un AppleScript que repite una acción hasta que presionas una tecla o haces clic fuera de la ventana activa. ¿Cómo voy a hacer eso?

repeat repeatTimes times
tell application "System Events"

    keystroke firstText
    keystroke return
    delay firstDelay

    keystroke secondText
    keystroke return
    delay secondDelay

end tell
end repeat

preferiría modificar repeat repeatTimes times a until keypress (cualquier pulsación de tecla) o until app not active o algo así. alguna idea?

    
pregunta esaruoho 02.03.2018 - 15:03

2 respuestas

2

Después de un poco de investigación, encontré una solución al 75% para tu pregunta. El siguiente script repetirá las acciones dentro del bucle hasta que se cumpla una de las dos afirmaciones:

① La ventana que tiene el foco ahora es diferente de la ventana que tenía el foco antes;

② Una tecla modificador de fn , , y .

Traté de encontrar una solución que permitiera probar cualquier evento keydown, pero solo pude encontrar una solución con las teclas modificadoras. AppleScript solo cannot escucha eventos clave, sin embargo AppleScript-ObjC puede. Quizás otra persona podrá proporcionar la solución completa que permita el monitoreo de cualquier pulsación de tecla.

He agregado comentarios dentro del guión para guiarte en lo que hace cada parte. Tenga en cuenta que este es solo un ejemplo de secuencia de comandos que demuestra una manera posible de implementar estos métodos para lograr su objetivo:

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

    end modifierKeydown

Tenga en cuenta que el bucle repeat comprueba el estado del modificador de reducción de teclas varias veces en una única iteración. Experimenté con la verificación una vez, lo que requería mantener presionada la tecla modificadora durante tal tiempo hasta que el bucle pudiera llegar al punto de verificación; y tres veces, lo que acorta el tiempo de espera, pero a expensas del tiempo que podría dedicarse a procesar otras acciones dentro del bucle (es decir, se agregará a los tiempos de demora ya existentes entre los comandos).

No hay correcto o incorrecto allí, tendrás que jugar con él y ver qué se siente mejor para ti.

Del mismo modo, la comprobación realizada en el enfoque de la ventana solo se realiza una vez por iteración, lo que en realidad es muy suficiente. Sin embargo, notará que hacer clic para alejarse de la ventana se ve ligeramente obstruido por la atención prestada a realizar las acciones dentro del bucle. No es un problema en absoluto, simplemente hace que cambiar las ventanas sea algo hecho con más intención de lo normal.

Sin embargo, nada de eso es sorprendente, dado lo que hace este script y cómo lo hace.

Hazme saber cómo te va y, si tienes alguna pregunta o problema, deja un comentario y haré todo lo posible para ayudarte.

    
respondido por el CJK 02.03.2018 - 19:48
0

Puedes hacer algo como:

-- Get current active app
tell application "System Events"
    set activeApp to name of first application process whose frontmost is true
end tell

set repeatValue to false
repeat until repeatValue
    tell application "System Events"
        set newActiveApp to name of first application process whose frontmost is true
        if newActiveApp is not in activeApp then
            set repeatValue to true -- stop the loop
        end if

        log "Repeating"
    end tell
end repeat

Por lo tanto, puede verificar la aplicación activa actual y decidir si desea detener el ciclo.

    
respondido por el Mateusz Szlosek 02.03.2018 - 16:36

Lea otras preguntas en las etiquetas