Come posso interrompere la ripetizione facendo clic lontano dalla finestra attiva o premendo un tasto usando AppleScript?

0

Sto tentando di scrivere un AppleScript che continua a ripetere un'azione finché non premi un tasto o clic via dalla finestra attiva. Come potrei fare per farlo?

repeat repeatTimes times
tell application "System Events"

    keystroke firstText
    keystroke return
    delay firstDelay

    keystroke secondText
    keystroke return
    delay secondDelay

end tell
end repeat

preferirei modificare repeat repeatTimes times in until keypress (qualsiasi pressione di tasto) o until app not active o qualcosa. qualche idea?

    
posta esaruoho 02.03.2018 - 15:03
fonte

2 risposte

2

Dopo un po 'di ricerche, ho trovato una soluzione al 75% per la tua domanda. Lo script seguente ripeterà le azioni all'interno del ciclo fino a quando una delle due asserzioni non sarà soddisfatta:

① La finestra che ha ora il focus è diversa dalla finestra che aveva lo stato attivo prima;

② Un tasto modificatore di fn , ^ , e viene premuto.

Ho provato a trovare una soluzione che consenta di testare qualsiasi evento keydown, ma è stata solo in grado di trovare una soluzione che includa i tasti modificatori. Solo AppleScript non può ascoltare gli eventi chiave, tuttavia AppleScript-ObjC può. Forse un'altra persona sarà in grado di fornire la soluzione completa che consente il monitoraggio di qualsiasi pressione dei tasti.

Ho aggiunto commenti all'interno dello script per aiutarti a guidare ciò che fa ogni parte. Tieni presente che questo è solo uno script di esempio che dimostra un possibile modo di implementare questi metodi per raggiungere il tuo obiettivo:

    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

Si noti che il ciclo repeat controlla lo stato del keydown del modificatore un numero di volte all'interno di una singola iterazione. Ho sperimentato una volta il controllo, il che ha richiesto di tenere premuto il tasto modificatore per un tempo simile fino a quando il loop non è stato in grado di arrivare al checkpoint; e tre volte, che accorcia i tempi di attesa ma a spese del tempo che altrimenti potrebbe essere impiegato per elaborare altre azioni all'interno del ciclo (cioè aggiungerà ai tempi di ritardo già presenti tra i comandi).

Non c'è né giusto né torto, devi giocarci e vedere cosa ti fa sentire meglio.

Allo stesso modo, il controllo eseguito sul focus della finestra viene eseguito una volta sola per iterazione, che in realtà è molto sufficiente. Tuttavia, noterai che il click lontano dalla finestra è sempre leggermente ostacolato dall'attenzione prestata all'esecuzione delle azioni all'interno del loop. Non è affatto un problema, ma rende semplicemente il cambiamento di windows qualcosa fatto con più intento.

Nulla di tutto ciò è sorprendente, tuttavia, dato cosa sta facendo questo script e come lo sta facendo.

Fammi sapere come vai avanti e se hai domande o problemi, lascia un commento e farò del mio meglio per aiutarti.

    
risposta data 02.03.2018 - 19:48
fonte
0

Puoi fare qualcosa come:

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

Quindi puoi controllare l'attuale app attiva e decidere se vuoi interrompere il ciclo.

    
risposta data 02.03.2018 - 16:36
fonte

Leggi altre domande sui tag