Web開発
Show HN: Zen Mode – macOS用のグローバルフォーカスモード
Show HN: Zen Mode – a global focus mode for macOS (github.com)
要約
Zen Modeは、macOSのアプリ全体に適用できるグローバルなフォーカスモードを提供するツールです。ワンホットキーで、作業中のウィンドウ以外(メニューバー、Dock、他のウィンドウ、壁紙など)をすべて非表示または暗転させ、注意散漫を防ぎます。Hammerspoonスクリプトとして実装されており、あらゆるmacOSアプリで動作します。
全文翻訳
Ryan's Zen Mode
注意を取り戻すための小さなツールです。macOSアプリ全体にグローバルなフォーカスモードを提供します。
私の画面は常に注意を引くもので溢れています。他のウィンドウ、通知バッジ、メニューバーの時計、Dock、景色の良い壁紙などです。
Zen Modeは、それらすべてを静かにさせるワンホットキーです。
作業中のウィンドウは画面の中央に移動し、全高まで拡張され、それ以外のすべて(メニューバーとDockを含む)は黒くフェードアウトします。
もう一度ホットキーを押す(またはEscキーを押す)と、すべてが元の状態に戻ります。
これはフルスクリーンモードに似ていますが、ウィンドウはその自然な幅を保ちます。テイクオーバーというよりはスポットライトのような感じです。
これはアプリではなくHammerspoonスクリプトであり、すべてのMacアプリで動作します。個々のエディタに組み込まれているZenモードとは異なり、同じキーストロークがターミナル、ブラウザ、PDFリーダー、またはウィンドウを持つ他のどのアプリでも機能します。
ブログで、これがどのように実現されたかについて詳しく読んでください。
デモ
他のアプリウィンドウ、壁紙、メニューバー、Dockが注意を競い合っている賑やかなデスクトップが、ワンキーストロークでフォーカスされたウィンドウが中央に配置され、それ以外のすべてが黒くフェードアウトします。
ターミナル、ブラウザ、または他のどのアプリでも同じように動作します。
機能
どのアプリでも、アプリごとの設定は不要 — これはグローバルモードであり、アプリの機能ではありません。
フォーカスされているウィンドウで動作するため、同じホットキーでターミナル、ブラウザ、メモアプリ、または他のどのアプリでもZenモードに入れます。
ワンキートグル — Option + Cmd + Z でZen Modeを即座にオン/オフできます。
中央揃え、全高レイアウト — ウィンドウはその幅を保ち、画面の全高まで拡張され、水平方向に中央揃えされます。
積極的なUI非表示 — 暗転キャンバスはmacOSカーソルウィンドウレベルでレンダリングされ、メニューバーとDockを完全に覆い隠します。
密閉された視覚的シール — 少しインセットされた丸みを帯びた切り抜きがmacOSウィンドウフレームの内側にぴったりと収まるため、背景ピクセルが角から漏れることはありません。
スムーズなトランジション — 入力時には2段階のイーズインアウト振り付けが再生されます。ウィンドウは背景が黒くフェードアウトするにつれて中央に移動し、その後暗闇の下で全高まで拡張されます。終了時には逆の動作をします。
両方のフェーズは、moveDurationとresizeDurationを介して調整可能(または完全にオフ)です。
ライブウィンドウ追跡 — Zen Modeがアクティブな間にウィンドウをドラッグまたはリサイズすると、切り抜きがそれに追従します。ウィンドウが閉じると、オーバーレイは自動的に解除されます。
セーフエスケープフック — EscキーでZen Modeが即座に終了しますが、キーはZen Modeがアクティブな間のみインターセプトされます。終了した瞬間、macOSに引き渡されるため、Vim、ターミナル、通常のOS動作が通常通り機能します。
状態復元 — ウィンドウの正確な位置とサイズは記憶され、終了時に復元されます。
要件
macOS
Hammerspoon — brew install --cask hammerspoon
インストール
Hammerspoonをインストールして起動します。
brew install --cask hammerspoon
Hammerspoonにアクセシビリティ権限を付与します(システム設定 > プライバシーとセキュリティ > アクセシビリティ)。
このリポジトリのinit.luaの内容を ~/.hammerspoon/init.lua に追加します。
mkdir -p ~/.hammerspoon
curl -fsSL https://raw.githubusercontent.com/cabeen/zen-mode/main/init.lua >> ~/.hammerspoon/init.lua
メニューバーのHammerspoonアイコンをクリックし、Configをリロード(Reload Config)を選択します。
使用方法
アクション
キー
フォーカスされたウィンドウでZen Modeを切り替える
Option + Cmd + Z
Zen Modeを終了する
Option + Cmd + Z または Esc
仕組み
他のアプリをリサイズまたは非表示にするのではなく、スクリプトは単一のフルスクリーンCoreGraphicsキャンバスをすべての上に描画します。
これはカーソルウィンドウレベルにエスカレートされるため、メニューバーとDockを覆い隠し、フォーカスされたウィンドウがある場所に正確に透明で丸みを帯びた角の穴を開けます。
あなたのウィンドウは完全に通常のインタラクティブなウィンドウのままです。その周りのすべてが単に黒く塗りつぶされているだけです。
先行事例
いくつかの既存のツールがこのアイデアの一部をカバーしています。
ディストラクションディマー — HazeOver(有料)やFocusDimのような無料の代替手段は、フォーカスが変わるとバックグラウンドウィンドウを自動的に暗くします。これらは受動的で常にオンの効果です。デスクトップの壁紙、メニューバー、Dockには影響を与えず、ウィンドウを移動またはリサイズすることもありません。
Hammerspoonの組み込みhs.window.highlight — その「分離」モードは、不透明なオーバーレイで他のウィンドウとデスクトップを覆い隠します。ここで使用されているテクニックに最も近い関係です。ウィンドウを再配置したり、メニューバーとDockを非表示にしたりしません。
アプリ固有のZenモード — VS Code、Obsidian、iA Writerなどは、中央揃えでクロームフリーのライティングモードを提供しますが、それはそのアプリ内のみです。
ネイティブmacOSフルスクリーン — メニューバーとDockを非表示にしますが、ウィンドウをエッジツーエッジに引き伸ばし、フレーム化するのではなく、画面全体に表示します。
このスクリプトが異なるのは、これらの要素を1つの意図的で元に戻せるジェスチャーに組み合わせ、どのウィンドウでも機能することです。
単一のホットキーでウィンドウを全高で中央揃えにし、画面上の他のすべて(壁紙、メニューバー、Dockを含む)を1つの同期されたアニメーション遷移で黒く塗りつぶし、離れるときにはウィンドウを元の場所に戻します。
また、アプリではありません。
約250行の依存関係のないLuaコードで、数分で読んで好みに合わせて調整できます。
デザインノート
このスクリプトの労力のほとんどは、間違いやすい小さなUXの詳細に費やされました。
スムーズなアニメーション。
Hammerspoonの組み込みウィンドウアニメーション(hs.window.animationDuration)は、同期されたアクセシビリティ呼び出しのシーケンスをステップ実行するため、ぎこちなく見えます。
Zen Modeはそれを無効にし、独自の60 Hzアニメーションクロックを実行し、ウィンドウフレームとバックドロップのアルファを単一のタイムラインから一緒にイーズさせます。
アニメーションはステップベースではなく時間ベースです。アプリがフレームの適用に遅延した場合、中間フレームのレンダリングが少なくなるだけです。遷移は常にスケジュール通りに完了します。
移動してからリサイズ。
ウィンドウの移動はターゲットアプリにとって低コストです。リサイズは各ステップで再レイアウトを強制します(ターミナルは文字グリッド全体を再配置します)。
そのため、遷移は2つのフェーズで振り付けられます。ウィンドウは元のサイズで中央に移動し、画面が黒くフェードアウトする間、バックドロップが完全に暗くなってから全高まで拡張されます。これは、あまりスムーズでないリサイズにとって最も許容できる瞬間です。
終了時にはこれがミラーリングされます。暗闇の中で縮小し、暗闇が晴れるにつれてホームに滑り込みます。
ウィンドウエッジの処理。
切り抜きは、要求された場所ではなく、ウィンドウが実際に存在する場所に合わせられます。
アプリはフレーム変更を遅れて適用し、独自のグリッドに丸めます(ターミナルは文字セルにスナップします)。そのため、要求されたフレームに従う切り抜きはウィンドウより先行し、アニメーション中に明るい背景を漏らします。
各フレーム変更後、スクリプトは実際のフレームを読み戻し、切り抜きをそれに合わせます。残りの遅延は明るいのではなく暗い方(ウィンドウがオーバーレイの下に一時的に隠れる)に誤ります。
切り抜きはわずかにインセット(padding = -2)されているため、暗転がウィンドウエッジに重なり、明るい継ぎ目が残るのを防ぎます。
ウィンドウコーナーの処理。
切り抜きのコーナー半径は、ウィンドウ自体のコーナー半径以上である必要があります。そうでないと、コーナーの対角線上に暗くなっていない背景のスリットが覗いてしまいます。
macOS 26 "Tahoe" はウィンドウのコーナーを劇的に丸くしました。そして、その半径はウィンドウごとに異なり、それを照会する公開APIはありません。
デフォルト(cornerRadius = 24)は意図的に寛大です。なぜなら、失敗の方向は対称的ではないからです。大きすぎるとウィンドウのコーナーのスリットがわずかに暗くなるだけですが、小さすぎると明るい背景が漏れます。
メニューバーとDockの非表示。
通常のオーバーレイウィンドウはシステムUIの下に配置されます。
キャンバスはカーソルウィンドウレベルにエスカレートされます。メニューバーとDockレベルの上に配置されるため、ブラックアウトはウィンドウ以外の画面上のすべてを真に覆い隠します。
バックドロップがぼやけているのではなく、暗い理由。
曇りガラスのようなぼかしはきれいでしょうが、macOSはスクリプトが任意のウィンドウの後ろにあるものをぼかすための公開された方法を提供していません(実際のバックドロップぼかし機構はプライベートAPI領域です)。
回避策 — デスクトップのスクリーンショットを撮り、ぼかし、表示する — には画面録画の権限が必要で、後ろにあるものが変更されたりウィンドウが移動したりするとすぐに古くなる静止画像が生成されます。
半透明の暗い塗りつぶしは、同じフォーカス効果を達成し、ライブのままで、コストはかかりません。
バックドロップは、システムのライト/ダーク表示に関係なく、暗いままです。darkne