システム環境設定にあるキーボードショートカットを設定するJXA

システム環境設定にあるキーボードショートカットを設定するJXA:

2年ぐらい前にポストした「システム環境設定にあるキーボードショートカットを設定するAppleScript」のJXA版です。

OS標準のショートカット設定では、設定をインポート/エクスポートができないため、それを補完する感じでJSONファイルで設定を書いて無理やり取り込むスクリプトです。インポートができれば設定ファイルが残るため、エクスポートは「ええやろ」という考えなのでエクスポートのスクリプトはありません。

High Sierra(10.13.6)で動作確認しています。


使い方

  1. 環境設定 → セキュリティとプライバシー → プライバシー の「アクセシビリティ」で、スクリプトエディタ.appにコンピュータの操作を許可する
  2. JSONファイルをこしらえる(:point_right_tone2:JSONの書き方

  3. :point_right_tone2:下記のスクリプトを「スクリプトエディタ」にコピペする(言語はJavaScriptを選択してください)
  4. スクリプトエディタのツールバーにある右向きの三角で実行(ショートカット:Cmd + R)すると、ダイアログが表示されるので、こしらえたJSONファイルを選択する
  5. あとは無事終わるまで眺める(スクリプトでGUIを操作しているので、文字通り眺めてください)
「アプリケーション」フォルダ直下にないアプリをJSONのappNameで指定している場合、4でダイアログが表示されるので、appNameと同じアプリを選択してください。

  • スクリプトエディタ.appは、「アプリケーション/ユーティリティ」の中にあります。
  • 「アプリケーション」フォルダは、FinderでCmd + Shift + Aで表示されるフォルダです。


JSONの書き方

次のように記述します。

[ 
    { 
        "appName": "Sketch.app", 
        "shortcut": [ 
            { 
                "menu": "Flatten Selection to Bitmap", 
                "key": "e", 
                "modifier": [ "command", "control", "shift" ] 
            } 
        ] 
    } 
] 
appName:
アプリケーション名です。アプリケーションフォルダ内の名前を正確に入力してください。
shortcut:
menu:
アプリのメニュー項目を正確に入力してください。同じ項目名が複数ある場合は、親のメニュー項目を「->」でつなぎます。
例:Use Defaultという項目がかぶる場合、Kern->Use DefaultLigature->Use Defaultと入力する。
key:
キーボードで文字が入力できるキーを1文字を小文字で指定してください。例外的に矢印キーは「up」「right」「down」「left」と指定できます。Fキーは要望があれば対応します。
modifier:
Command・Control・Shift・Optionキーを指定します。CommandまたはControlのどちらかは必ず含めてください。


サンプル


スクリプト

"use strict"; 
 
var app = Application.currentApplication(); 
app.includeStandardAdditions = true; 
 
// ローカライズ 
var langList = app.doShellScript("defaults read NSGlobalDomain AppleLanguages | awk '{gsub(/[^a-zA-Z-]/,\"\");print}' | grep -v '^$'"); 
var langs = langList.split('\r'); 
 
var chooseJSONLabel = 'Please select a JSON file:'; 
var shortcutLabel = 'App Shortcuts'; 
var menuItemLabel = 'Menu Title:'; 
var addButtonLabel = 'Add'; 
switch (langs[0].substr(0, 2)) { 
    case 'ja': 
        chooseJSONLabel = 'JSONファイルを選択してください。'; 
        shortcutLabel = 'アプリケーション'; 
        menuItemLabel = 'メニュータイトル:'; 
        addButtonLabel = '追加'; 
        break; 
} 
 
var appList = app.doShellScript('ls /Applications').split('\r'); 
 
// 設定ファイルを読み込んでJSONへパース 
var chooseFile = app.chooseFile({ 
        withPrompt: chooseJSONLabel 
    }) 
var json = JSON.parse(readFile(chooseFile)); 
 
// 環境設定を起動してキーボードを選択し、ショートカットタブを表示する 
var pref = Application('com.apple.systempreferences'); 
pref.panes['com.apple.preference.keyboard'].anchors['shortcutsTab'].reveal(); 
pref.activate(); 
delay(2); 
 
// 左のリストから「アプリケーション」を選択 
var sysEvent = Application('System Events'); 
var prefKeyboard = sysEvent.processes['System Preferences'].windows[0]; 
var rows = prefKeyboard.tabGroups[0].splitterGroups[0].scrollAreas[0].tables[0].rows(); 
var shortcutPosition = 0; 
for (let i = 0; i < rows.length; i++) { 
    console.log(rows[i].staticTexts[0].name()); 
    if (shortcutLabel === rows[i].staticTexts[0].name()) { 
        shortcutPosition = i; 
        break; 
    } 
} 
rows[shortcutPosition].select(); 
 
// ショートカットを設定 
for (let i = 0; i < json.length; i++) { 
    let appName = json[i].appName; 
    let appExist = false; 
    appList.some(function (obj) { 
        if (appName === obj) { 
            appExist = true; 
            return true; 
        } 
    }); 
 
    let appSelected = false; 
 
    for (let j = 0; j < json[i].shortcut.length; j++) { 
        // [+]ボタンをクリックしてダイアログシートを表示 
        prefKeyboard.tabGroups[0].groups[0].buttons[0].click(); 
        let settingSheet = prefKeyboard.sheets[0]; 
 
        // アプリケーションを設定 
        if (!appSelected) { 
            if (appExist) { 
                settingSheet.popUpButtons[0].click().menus[0].menuItems[appName].click(); 
            } else { 
                // ポップアップの中にアプリがない場合 
                let appListItems = settingSheet.popUpButtons[0].click().menus[0].menuItems.length; 
                settingSheet.popUpButtons[0].menus[0].menuItems[appListItems - 1].click(); 
 
                // アプリが選択されるまで待つ 
                while (!appExist) { 
                    if(appName == settingSheet.popUpButtons[0].value()) { 
                        appExist = true; 
                    } else { 
                        delay(2); 
                    } 
                } 
            } 
            appSelected = true; 
        } 
 
        // メニュー項目を設定 
        settingSheet.textFields[menuItemLabel].value = json[i].shortcut[j].menu; 
 
        // タブキーでフォーカスを移動 
        sysEvent.keyCode(48); 
 
        // ショートカットキーを設定 
        let pressKey; 
        switch (json[i].shortcut[j].key) { 
            case 'left': 
                pressKey = 123; 
                break; 
            case 'right': 
                pressKey = 124; 
                break; 
            case 'up': 
                pressKey = 125; 
                break; 
            case 'down': 
                pressKey = 125; 
                break; 
            default: 
                pressKey = json[i].shortcut[j].key 
                break; 
        } 
        setShortcut(pressKey, json[i].shortcut[j].modifier); 
 
        // 追加ボタンをクリック 
        settingSheet.buttons[addButtonLabel].click(); 
    } 
    appSelected = false; 
} 
 
 
// Helpers 
function readFile(file) { 
    var fileString = file.toString(); 
    return app.read(Path(fileString)); 
} 
 
function setShortcut(key, mod) { 
    for (var i = 0; i < mod.length; i++) { 
        mod[i] = mod[i] + ' down'; 
    } 
    if (isNaN(key)) { 
        sysEvent.keystroke(key, {using: mod}); 
    } else { 
        sysEvent.keyCode(key, {using: mod}); 
    } 
} 


トラブルシューティング

エラー処理はあまり考えてないので、そこは大目にみてください :bow_tone2:


1回実行した後にエラーが出て再実行できない

スクリプトエディタでハンマーのアイコンをクリックしてみてください。ショートカットはCmd + Kです。


アプリを選択したが進まない

JSONのappNameで指定した名前が間違っている可能性がありますので、確認してください。

コメント

このブログの人気の投稿

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2020-12-01 09:41:49 RSSフィード2020-12-01 09:00 分まとめ(69件)