0 votos

¿Cómo puedo detener la repetición haciendo clic fuera de la ventana activa o pulsando una tecla mediante AppleScript?

Estoy intentando escribir un AppleScript que siga repitiendo una acción hasta que se pulse una tecla o se haga clic fuera de la ventana activa. ¿Cómo puedo hacerlo?

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 tecla) o until app not active o algo así. ¿Alguna idea?

2voto

qarma Puntos 71

Después de investigar un poco, he dado con una solución del 75% a tu pregunta. El script de abajo repetirá las acciones dentro del bucle hasta que se cumpla una de las dos afirmaciones:

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

② A modificador de cualquiera de las dos teclas fn , , y está presionado.

Intenté encontrar una solución que permitiera probar cualquier evento de pulsación de teclas, pero sólo pude encontrar una solución que involucrara a las teclas modificadoras. AppleScript solo no puede escuchar los eventos clave, sin embargo AppleScript-ObjC puede. Tal vez otra persona sea capaz de proporcionar la solución completa que permite el seguimiento de cualquier pulsación de teclas.

He añadido comentarios dentro del script para ayudarte a guiarte en lo que hace cada parte. Ten en cuenta que esto es sólo un ejemplo de script que demuestra una posible forma de implementar estos métodos para lograr tu 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 repeat comprueba el estado de la tecla de modificación hacia abajo un número de veces dentro de una sola iteración. He experimentado con la comprobación una vez, lo que requería mantener pulsada la tecla modificadora durante ese tiempo hasta que el bucle pudiera llegar al punto de comprobació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 añadirá a los tiempos de retardo ya existentes entre los comandos).

No hay nada correcto o incorrecto: tendrás que jugar con ello y ver qué te parece mejor.

Asimismo, la comprobación que se realiza sobre el foco de la ventana sólo se hace una vez por iteración, lo que en realidad es muy suficiente. Sin embargo, notarás que al hacer clic fuera de la ventana se ve ligeramente obstaculizado por la atención prestada a la realización de las acciones dentro del bucle. No es un problema en absoluto, sólo hace que cambiar de ventana sea algo que se haga con más intención de lo normal.

Sin embargo, nada de esto es sorprendente, dado lo que este script está haciendo y cómo lo está haciendo.

Cuéntame cómo te va, y si tienes alguna duda o problema, deja un comentario y haré lo posible por ayudarte.

0voto

hjdm Puntos 18

Puedes hacer algo así:

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

Así puedes comprobar la aplicación activa actual y decidir si quieres detener el bucle.

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X