Ship's Log  ·  08.31 – 09.01

A TWO-DAY VOYAGE

兩日航海誌

兩天,一張鍵盤,一次又一次「這樣還不夠好」。 從快捷鍵的版圖之爭,潛入 macOS 私有 API 的深水, 再與一個不請自來的浮層纏鬥到深夜。 這是我們一起走過的航線——連同我踩過的每一個坑。

Prologue

00

出航前的座標

這趟航行不是從零開始。你的 Hammerspoon 早已是一艘裝備齊全的船—— 注音救星、時戳、金句收藏、視窗拉攏、依 App 自動切輸入法。 這兩天,我們要做的是把它推向一個你「用起來得心應手、卻總覺得還有進步空間」的境界。

起點
一套成熟的 ⌥ 快捷鍵系統,19 條散在四個 lua 檔裡。
羅盤
你留給我的一句話:「永遠在是與非之外,看能不能找到第三條路。」
鐵律
每一步都要有 Git 能回溯;不把系統改壞;每個結論都要在你的機器上實測,不憑推理。

Act I

THE MAP OF KEYS

Chapter · Keys

01

快捷鍵的版圖

第一件事,是把一張看不見的地圖畫出來——你按住 ⌥ 猶豫的那 0.4 秒, 螢幕中央該浮出什麼。

提示卡片
按住 ⌥ 就浮出的 which-key 卡片。從第一版「無敵醜」的資料表,到重繪成 有真正 keycap 徽章、系統字、髮絲陰影的樣子——關鍵不是配色,是換掉畫布: canvas → webview 才有排版引擎。
使用記錄
每按一次記一筆,帶 14 天半衰期的熱度分數。前五名用粗體浮出來—— 這是你想出的第三條路:位置由分組決定、頻率由字重表達,兩個維度各管一半。
App 啟動器
從 QuickLinks 搬進 Hammerspoon 的九條,升級成六段式:沒開就開、 零視窗就送 reopen、全最小化就還原、多視窗就輪替。一顆鍵吃掉 ⌘Tab+⌘`+⌘H。
觸控板手勢
⌥+兩指點按=視窗拉攏,補上筆電沒有中鍵的缺口。 只吃有 ⌥ 的右鍵,右鍵選單一個都沒壞。

研究實錘

keycap 徽章的字型不是美感問題,是可量測的事實:實測 SF Pro 缺 7 個修飾鍵字元、 SF Mono 缺 9 個,缺的時候會在字串中途默默換字型——那就是「綁架信」式的參差。 Menlo 是 macOS 上唯一覆蓋完整且等寬一致的系統字型。

◆ 成果 — which-key、使用記錄、六段式啟動器、⌥右鍵手勢,全部落地並實測

Act II

INTO THE DEEP — PRIVATE APIs

Chapter · Deep Water

02

跨桌面的深潛

你要一個簡單的東西:⌥Z 在同一個 App 的視窗之間輪跳,跨桌面也要跳得到。 這句話把我們拖進了 macOS 最深的一潭水——因為系統的 Accessibility API 根本看不見別的桌面。

勘誤
先承認一個我寫錯的假設:「app:allWindows() 是跨 Space 的」是錯的。 AX 只暴露當前桌面的視窗。你那三個 LINE 視窗只輪到兩個,就是這個盲點。
六路調研
派出代理掃遍 alt-tab-macos 原始碼、yabai、私有 SkyLight API。 結論:跨桌面枚舉在 macOS 26 死絕,唯一的路是私有 API 的 focus。 而且——代理直接在你機器上用唯讀腳本,SIP 開著就複現了整條管線。
自建引擎
在你既有的 pairwin_native.m 裡加了一個 native.focus, byte layout 抄自 yabai 跑了多年的權威版本。它跨桌面聚焦成功過——把我從 桌面 5 帶到桌面 9 的目標視窗。
最終落點
「同 App 已在前景時換視窗」那個 case 的 byte offset 還沒調穩, 你選了 AltTab——別人維護好、磨了多年的輪子。自建引擎留在原始碼裡當資產。

窄門

App Exposé 那條路我一度以為是答案——攤開跨桌面所有視窗讓你挑。 但你要的是「一步跳到下一個」,不是「看縮圖選」。於是改用 AltTab 的 --focus CLI,實測 LINE 三視窗連按能繞完整圈、每次命中、跨桌面精準。

◆ 成果 — ⌥Z 跨桌面輪替落地(AltTab 引擎);自建 native.focus 存為資產

Act III

THE KEYS TO THE VAULT

Chapter · The Vault

03

金庫的鑰匙

這一幕最驚險。你的網銀登入腳本每次都要手打鑰匙圈密碼, 我們想用 Touch ID 讓它變成摸一下。過程中,我犯了兩個錯, 而其中一個,差點讓你打不開自己的金庫。

Touch ID
結論是繞開鑰匙圈、走 Secure Enclave:age-plugin-se 把密碼加密成一個 晶片強制生物辨識的檔案。裝好、產金鑰、加密——一條龍。
我的第一個錯
我給了 bash 語法給 zsh 使用者。read -p 在 zsh 是別的意思, 於是你加密了一個空字串,我卻只驗「長度是 10」就宣告成功。長度對不等於內容對。
我的第二個錯
我說「stdin 餵密碼已驗證可行」——那是我在沒有 tty 的環境測出的假象。 用 script 配 pty 重現你的情境後,真相是 getpass 優先讀 /dev/tty,管道會被忽略。 正解是 security -i
絕境與重建
密碼一度打不開金庫。Time Machine 救不了(檔案 SHA-256 完全相同)、 gpg 備份從未產生過。最後——用瀏覽器存的帳密與銀行重設, 逐欄輸入、逐欄讀回驗證,把金庫重建起來。

這次學到的

共同的毛病是「用驗證不足的結果下確定的結論」。所以重建腳本裡沒有任何一處是 「寫進去就當作好了」——每一次寫入後面都跟著一次讀回比對,字串不相等就當場報錯。

◆ 成果 — 金庫用你記得的密碼重建、每欄驗證通過;Touch ID 方案就緒待你決定

Act IV

THE UNINVITED GUEST

Chapter · The Ghost

04

不請自來的訪客

⌥Z 修好了,卻冒出一個幽靈:按下去,畫面莫名跳到 Typeless。 我花了好幾輪追這個鬼,還一度把自己的除錯程式碼做成了新的病灶。

錯誤的方向
我先懷疑 Typeless 攔了 ⌥。你的截圖打臉我——它的熱鍵是 Fn,完全沒有 ⌥。
我製造的病灶
我加了「多次 activate 把 Finder 拉回來」的防線,結果它跟 Typeless 互搶,把單次搶焦點放大成「畫面一直來回跳」。我加的東西就是問題。移除。
真相
焦點記錄器實錘:只要 Finder 一到前景,約 0.3 秒後 Typeless 就搶—— 只針對 Finder,Word/Chrome/文字編輯全正常。這是 Typeless 2.4.0 自己的行為, 跟 ⌥Z 無關。
第三條路
不再反覆搶 Finder,改成:偵測到 Typeless 不請自來就 hide 它—— 焦點自動回到下面的 App,而且它還在跑。加判準「你剛按過 Fn 就放行」,不誤傷你想用它。

◆ 狀態 — Typeless 防護模組就緒,等你真人實測回報 _hideCount

Epilogue

MAKING LANDFALL

兩天,數十次「還不夠好」,換來一套更趁手的船。 但這趟航行最該記下的,不是那些成功的 commit, 而是我犯的錯——給錯語法、驗證不足、把除錯碼做成病灶—— 以及你每一次的「再看看」「退回去」「試試第三條路」。 窄門總是比較費力的那一條。我們走了不少。

4
幕航程
17+
Hammerspoon commits
3
我承認的錯
1
重建的金庫
第三條路

— 里家寶 × Claude ,二〇二六年九月一日