MacOS 快捷鍵切換 AirPods 降噪模式:從不想用到離不開

January 13, 2026

深入 AppleScript,我發現沒法透過關鍵詞匹配的方式標記對應的選項,只好選擇了按照 index 排序選擇。

這句正是我先前提出的妥協,正是這個痛點導致了舊版腳本的雞肋。

先前如果連接了 HDMI 揚聲器,它會被添加在 AirPods 前,腳本就會因為 AirPods 絕對位置的改變而發生意料之外的響應,同理,任何會改變 AirPods 絕對位置的設備都是一道隱患。

而這種後果會顯著的增加使用者的認知負荷,從而完全不可用——人們才不會使用不穩定的方法,比起不如長按耳機柄來的安穩。

時隔兩個月,以下是堪稱完美的改良版腳本。

首先改變了什麼?

首先是最重要的核心定位邏輯,從「絕對座標」到「相對錨點」。

先前的腳本透過查找 checkbox 4 達成目的。而現在改用了和人眼視覺一樣的邏輯,先掃描 AXDisclosureTriangle(展開箭頭),確認 AirPods 區塊的開頭,接著掃描 AXHeading 確認這真的是 AirPods,鎖定這個錨點後,才開始計算該區塊內的 checkbox

無論上方多了多少個揚聲器設備,腳本都會自動忽略,精準鎖定 AirPods 區域內的選項。

危險的殭屍視窗

儘管核心邏輯得到了修復,但提升 Robustness 是從能用變為好用的關鍵。

過去的腳本十分的天真,只要系統回報視窗存在,就嘗試操作,但完全忽略了「正在消失但還沒死透」的視窗。此時嘗試點擊裡面的按鈕時,視窗剛好銷毀,就導致 Invalid index 錯誤崩潰。現在即使視窗打開了,也要檢查 scroll area 1 是否存在,確保內容已載入,而不只是一個空殼。

自癒機制:引入重試迴圈

這是新版本穩定性最強的原因,解決了不確定性的 UI 延遲問題。

過去的邏輯是:嘗試點擊 -> 失敗 -> 彈出錯誤對話框 -> 結束。

後果就是只要那一次 macOS 卡頓了一下,腳本就失敗了,使用者必須手動重試。而現在的點擊包裹在 repeat with attempt from 1 to 2 中,對使用者來說,這是一個「永遠不會失敗」的腳本,因為錯誤在內部被消化並修復了。

現在透過兩個路徑判斷:

  • Attempt 1(快速路徑):嘗試直接複用當前視窗(如果有的話)。如果因為殭屍視窗報錯,不報錯,直接進入 Attempt 2。
  • Attempt 2(強制路徑):重置狀態,強制重新點擊 Menu Bar 開啟新視窗,再次執行。

本地化與兼容性

儘管同樣需要手動指定 "Sound" 為對應的系統語言,但在視窗處理上有極大的改進。

先前腳本透過 window "Control Center" 呼叫 UI,但如果使用者的 macOS 是日文(コントロールセンター)或中文(控制中心),腳本就原地罷工。而現在透過 window 1 動態判斷,對於 ControlCenter 這個 process 來說,當下的活動視窗永遠是 window 1。這完全繞過了視窗標題語言不同的問題。

最後參考

最新腳本的位址:

dotfiles/bin/applescript/macos-sound-mode.applescript

使用 Better Touch Tool,Keyboard Maestro,Raycast 等等軟體綁定 Applescript 到三個快捷鍵(對應三種 Noise Mode)即可使用。

最後推薦搭配 Hidden Bar,將 Sound 圖標拖入隱藏區域,即可在執行腳本時不顯示 UI 彈出。