Как остановить повтор, щелкнув вдали от активного окна или нажав клавишу с помощью AppleScript?


0

Я пытаюсь написать AppleScript, который повторяет действие до тех пор, пока вы не нажмете клавишу или не уйдете из активного окна. Как бы я поступил так?

repeat repeatTimes times
tell application "System Events"

    keystroke firstText
    keystroke return
    delay firstDelay

    keystroke secondText
    keystroke return
    delay secondDelay

end tell
end repeat

я предпочел бы изменить , repeat repeatTimes timesчтобы until keypress(любое нажатие клавиши) или until app not activeили что - то. есть идеи?

Ответы:


2

После небольшого исследования я нашел 75% решение вашего вопроса. Сценарий ниже будет повторять действия внутри цикла, пока не будет выполнено одно из двух утверждений:

① Окно, которое теперь имеет фокус, отличается от окна, которое было раньше;

② A модификатор ключ из либо fn, , и нажимается.

Я попытался найти решение, которое позволяет тестировать любое событие нажатия клавиш, но смогло найти только решение с использованием клавиш-модификаторов. Один только AppleScript не может прослушивать ключевые события, однако AppleScript-ObjC может. Возможно, другой человек сможет предоставить полное решение, позволяющее контролировать нажатие любой клавиши.

Я добавил комментарии в сценарий, чтобы помочь вам понять, что делает каждая часть. Помните, что это всего лишь пример сценария, демонстрирующий один из возможных способов реализации этих методов для достижения вашей цели:

    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

Обратите внимание, что repeatцикл проверяет статус keydown модификатора несколько раз за одну итерацию. Я экспериментировал с проверкой один раз, что требовало удерживать клавишу модификатора в течение такого времени, пока цикл не смог достичь контрольной точки; и три раза, что сокращает время ожидания, но за счет времени, которое в противном случае могло бы быть потрачено на обработку других действий в цикле (т.е. это добавит к временам задержки, уже имеющимся между командами).

Там нет ничего правильного или неправильного - вам придется поиграть с этим и посмотреть, что вам больше нравится.

Аналогичным образом, проверка, выполняемая для фокуса окна, выполняется только один раз за итерацию, что на самом деле вполне достаточно. Тем не менее, вы заметите, что щелчок вдали от окна очень сильно затруднен вниманием, уделяемым выполнению действий внутри цикла. Это совсем не проблема, это просто делает изменение окон более совершенным, чем обычно.

Ничего удивительного, однако, с учетом того, что делает этот скрипт и как он это делает.

Дайте мне знать, как вы поживаете, и если у вас есть какие-либо вопросы или проблемы, оставьте комментарий, и я сделаю все возможное, чтобы помочь.


0

Вы можете сделать что-то вроде:

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

Таким образом, вы можете проверить текущее активное приложение и решить, хотите ли вы остановить цикл.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.