Как создать Applescript для установки сочетания клавиш? - PullRequest
0 голосов
/ 26 мая 2020

Если кто-то может мне помочь, я пытаюсь автоматизировать создание ярлыков на клавиатуре для некоторых Сервисов .
То, что я получил, это

tell application "System Preferences"
    activate
    set current pane to pane id "com.apple.preference.keyboard"
    delay 1
    tell application "System Events"
        click radio button "Shortcuts" of tab group 1 of window "Keyboard" of application process "System Preferences"
        delay 1
        select row 6 of table 1 of scroll area 1 of splitter group 1 of tab group 1 of window 1 of application process "System Preferences"
        set value of text field 1 of UI element "My Service Name" of row 59 of outline 1 of scroll area 2 of splitter group of tab group 1 of window 1 of application process "System Preferences" to "⌥⌘1"
    end tell
end tell

Но теперь я застрял, то, что я не могу сделать, это:

  • Этот ...of row 59... не подходит, я хотел бы использовать имя ярлыка вместо этого индекса. Я знаю, что имя ярлыка находится в UI element "My Service Name", но я не знаю, как сделать вложенный выбор, например, вместо ...of row 59... сделайте что-то вроде of row (where UI element "My Service Name")
  • Этот скрипт работает, только если Служба имеет предыдущий ярлык, если ярлык отсутствует, вообще не работает

Есть ли у кого-нибудь подсказка, как я могу решить эту проблему?

Если есть какие-то другой способ создания ярлыка без applescript будет приветствоваться

Заранее всем спасибо.

Ответы [ 2 ]

1 голос
/ 27 мая 2020

Единственный способ, который я точно знаю, будет работать с использованием UI Scripting и System Preferences > Keyboard > Shortcuts > Services (или любая другая категория под Shortcuts ) по сути имитирует все шаги, которые могут возникнуть при выполнении этого вручную. Вот почему я бы использовал UI Scripting , если нет другого способа выполнить sh поставленную задачу.

Поскольку в вашем коде вы используете select row 6 ... и хотите настроить таргетинг row 59, я предполагаю, что вы используете macOS Mojave или macOS Catalina и нацеливаетесь на Services категория , поскольку это единственная категория , в которой реально может быть столько строк или больше, чтобы назначить сочетание клавиш для.

Пример AppleScript код , показанный ниже, был протестирован в Редакторе сценариев под macOS Mojave и macOS Catalina , а также macOS High Sierra с одним второстепенным редактированием и работает как в моей системе с использованием US Engli sh для Язык и регион настройки в Системные настройки .

Это также написано специально для служб категория , как и другие категории требуют другого кодирования .

Вам нужно будет установить значение из три переменные , serviceName, regularKey, modifierKeys, последняя из которых основана на списке в начале комментариях из script .

Он изначально установлен для Import Image с использованием сочетания клавиш ⇧⌘9 , и вы должны протестировать сценарий как есть, прежде чем изменять его.

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

Пример AppleScript код :

--  # Call the SetChangeServicesKeyboardShortcut(serviceName, regularKey, modifierKeys)
--  # handler using the parameters as defined below:

--  # serviceName defines the name of the target service under:
--  # System Preferences > Keyboard > Shortcuts > Services

--  # regularKey defines the regular key to press.

--  # modifierKeys define the modifier keys to be pressed. 
--  # Use the value based on the list below:
--  # 
--  #   1 = {command down}
--  #   2 = {shift down, command down}
--  #   3 = {control down, command down}
--  #   4 = {option down, command down}
--  #   5 = {control down, option down, command down}
--  #   6 = {shift down, control down, command down}
--  #   7 = {shift down, option down, command down}
--  #   8 = {shift down, control down, option down, command down}
--  #   
--  # |  shift = ⇧ | control = ⌃ | option = ⌥ | command = ⌘ |
--  #   


my SetChangeServicesKeyboardShortcut("Import Image", "9", "2")



--  ##################################
--  ## Do not modify code below unless necessary, as ##
--  ## it's tokenized for the variables defined above.   ##
--  ##################################


--  ## Handlers ##

on SetChangeServicesKeyboardShortcut(serviceName, regularKey, modifierKeys)
    --  # Need to start with System Preferences closed.
    if running of application "System Preferences" then
        try
            tell application "System Preferences" to quit
        on error
            do shell script "killall 'System Preferences'"
        end try
    end if
    repeat while running of application "System Preferences" is true
        delay 0.1
    end repeat
    --  # Open System Preferences to the target pane.
    tell application "System Preferences"
        activate
        reveal pane id "com.apple.preference.keyboard"
    end tell
    --  # Navigate to Shortcuts > Services and select the
    --  # target service, then change/set its keyboard shortcut.
    tell application "System Events"
        tell application process "System Preferences"
            tell its window 1
                --  # Wait until the Shortcuts tab can be clicked.          
                repeat until exists (radio buttons of tab group 1)
                    delay 0.1
                end repeat
                --  # Click the Shortcuts tab.          
                click radio button "Shortcuts" of tab group 1
                --  # Wait until Services can be selected.                      
                repeat until exists ¬
                    (rows of table 1 of scroll areas of splitter group 1 of tab group 1 ¬
                        whose name of static text 1 is equal to "Services")
                    delay 0.1
                end repeat
                --  # Select Services.          
                try
                    select (rows of table 1 of scroll area 1 of splitter group 1 of tab group 1 ¬
                        whose name of static text 1 is equal to "Services")
                end try
                tell outline 1 of scroll area 2 of splitter group 1 of tab group 1
                    --  # Wait until the services under Services are available.                 
                    repeat until exists (row 1)
                        delay 0.01
                    end repeat
                    --  # Set focus to the first item of Services.              
                    repeat 2 times
                        key code 48 -- # tab key
                        delay 0.25
                    end repeat
                    --  # Get the name of every service under Services.             
                    set serviceNames to (get name of UI element 2 of rows)
                    --  # Get the row number of the target service under Services.              
                    set countRows to (count serviceNames)
                    repeat with i from 1 to countRows
                        if contents of item i of serviceNames is equal to serviceName then
                            set rowNumber to i
                            exit repeat
                        end if
                    end repeat
                    --  # Select the row of the target target service under Services.               
                    select (row rowNumber)
                    --  # Change/Set the keyboard shortcut of the target service under Services.                
                    if exists (button "Add Shortcut" of UI element 2 of row rowNumber) then
                        click button "Add Shortcut" of UI element 2 of row rowNumber
                        my shortcutKeystrokes(regularKey, modifierKeys)
                    else
                        key code 36 -- # return key
                        my shortcutKeystrokes(regularKey, modifierKeys)
                    end if
                    select (row 1)
                end tell
            end tell
        end tell
    end tell
    quit application "System Preferences"
end SetChangeServicesKeyboardShortcut

on shortcutKeystrokes(regularKey, modifierKeys)
    tell application "System Events"
        if modifierKeys is equal to "1" then
            keystroke regularKey using {command down}
        else if modifierKeys is equal to "2" then
            keystroke regularKey using {shift down, command down}
        else if modifierKeys is equal to "3" then
            keystroke regularKey using {control down, command down}
        else if modifierKeys is equal to "4" then
            keystroke regularKey using {option down, command down}
        else if modifierKeys is equal to "5" then
            keystroke regularKey using {control down, option down, command down}
        else if modifierKeys is equal to "6" then
            keystroke regularKey using {shift down, control down, command down}
        else if modifierKeys is equal to "7" then
            keystroke regularKey using {shift down, option down, command down}
        else if modifierKeys is equal to "8" then
            keystroke regularKey using {shift down, control down, option down, command down}
        end if
    end tell
end shortcutKeystrokes

Примечание: для macOS High Sierra и, возможно, ранее, установите repeat 2 times под комментарием -- # Set focus to the first item of Services. на: repeat 3 times


Примечание: пример AppleScript код это просто и, без существующей обработки ошибок , не содержит какой-либо дополнительной обработки ошибок , которая может потребоваться. Обязанность пользователя - добавить любую обработку ошибок , которая может быть уместной, необходимой или желаемой. Взгляните на try оператор и error оператор в Руководство по языку AppleScript . См. Также: Работа с ошибками . Кроме того, может потребоваться использование команды delay между событиями, где это необходимо, например, delay 0.5, с значением задержка установить соответствующим образом.

1 голос
/ 26 мая 2020

Я немного реструктурировал ваш сценарий, потому что я предпочитаю иерархическую структуру «блока сообщения» (которую мне легче читать и следовать), и я поместил все это в обработчик, чтобы обобщить его. Но помимо этого, хитрость заключается в использовании where поисков для просмотра структуры пользовательского интерфейса и поиска идентифицируемых функций (NB, where является синонимом более обычного whose). См. Комментарии в сценарии. Обратите внимание, что я изменяю строку «Показать окно поиска Finder» в разделе «В центре внимания» настроек сочетаний клавиш, но, изменив значения вызова обработчика, вы можете изменить любые предпочтения.

Чтобы это работало , вам необходимо знать, к какому разделу относится ваша служба, и название службы, как оно отображается в списке. Если вы введете текстовую строку для new_val, она будет обрабатываться так, как если бы вы ввели первую букву; если вы введете целое число, оно будет рассматриваться как код клавиши, позволяя использовать непечатаемые символы и функциональные клавиши для сочетаний клавиш. См .: список кодов клавиш .

Этот скрипт был исправлен, чтобы исправить пару ошибок и приспособить как иерархическую структуру раздела «Услуги», так и возможность добавления новый ярлык, нажав кнопку «Добавить ярлык». Обратите внимание, что если вы добавляете ярлык в первый раз, пользовательский интерфейс по-прежнему будет показывать кнопку «Добавить ярлык», пока вы не выберете другую строку. Это верно даже при добавлении ярлыков вручную, поэтому это ограничение GUI, а не скрипта.

-- sets the 'Send Message' shortcut to cmd-opt-A
my change_shortcut("Services", "Text", "Send Message", "a", {"command", "option"})
-- sets the 'Call' service shortcut to cmd-F6
my change_shortcut("Services", "Text", "Call", 97, {"command"})

on change_shortcut(shortcut_region, section_name, shortcut_title, new_val, special_key_list)
    tell application "System Preferences"
        activate
        set current pane to pane id "com.apple.preference.keyboard"
        delay 1
        tell application "System Events"
            tell process "System Preferences"'s window "Keyboard"'s first tab group
                click radio button "Shortcuts"
                tell first splitter group
                    set sidebar_obj to first table of first scroll area
                    tell sidebar_obj

                        (* 
                            this looks to find the first row in the sidebar that contains a static text 
                            element with the value of `shortcut_region`
                        *)

                        set sidebar_entry to first row where (its first static text's value is shortcut_region)
                        select sidebar_entry
                    end tell
                    set outline_obj to first outline of second scroll area
                    tell outline_obj

                        (* 
                            if the shortcut outline view is arranged in groups, this section 
                            finds the correct group and make sure its disclosure triangle is 
                            opened, exposing the settings within
                        *)

                        if section_name is not "" and section_name is not missing value then
                            set wanted_section_row to first row where (its last UI element's name is section_name)
                            tell wanted_section_row's second UI element
                                set disclosure_tri to first UI element whose role description is "disclosure triangle"
                                if disclosure_tri's value is 0 then click disclosure_tri
                            end tell
                            delay 0.5
                        end if

                        (* 
                            this looks to find the first row in the outline that contains two 
                            UI elements (the row's cells) the second of which contains a static text 
                            element with the value of shortcut_title
                        *)

                        set wanted_entry to first row where (its last UI element's name is shortcut_title)
                        tell wanted_entry
                            select
                            set new_shortcut_flag to false
                            tell second UI element
                                if exists button "Add Shortcut" then
                                    click button "Add Shortcut"
                                    set new_shortcut_flag to true
                                end if
                                UI elements

                                -- set up a list of special keys
                                set special_keys to {}
                                if special_key_list contains "command" then set end of special_keys to command down
                                if special_key_list contains "control" then set end of special_keys to control down
                                if special_key_list contains "option" then set end of special_keys to option down
                                if special_key_list contains "shift" then set end of special_keys to shift down

                                -- opens the text field for editing, then write or keycode in the text
                                tell first text field
                                    if not new_shortcut_flag then perform action "AXConfirm"
                                    if class of new_val is text then
                                        keystroke new_val using special_keys
                                    else
                                        key code new_val using special_keys
                                    end if
                                end tell
                                -- select the cell to submit the result
                                select
                            end tell
                        end tell
                    end tell
                end tell
            end tell
        end tell
    end tell
end change_shortcut
...