Hyprland 設定 (Lua)
Hyprland の設定は Lua で記述しています (hyprland.lua)。従来の .conf ファイルから移行しました。Lua の真価は反復構造にあります。モニター、アニメーション、ループバインドを関数で表現することで、行ごとの monitor=... 記述よりも明確になります。ただし、この設定ファイルで私にとって最も有用なのはコメントです。各モニターのハードウェアの罠を横にメモしてあります。
27インチモニター3台を EDID 記述 (desc:) でマッチングさせており、接続ポートを変えても設定を変更する必要はありません。それぞれ物理的な回転が施されています:
hl.monitor({ output="desc:LG Electronics LG HDR 4K ...", -- 左上、物理的に180°反転
mode="3840x2160@60", position="0x0", scale=1.5, transform=2 })
hl.monitor({ output="desc:ASUSTek ... XG27UCS ...", -- 左下メインモニター、4K@160
mode="3840x2160@160", position="0x1440", scale=1.5, vrr=1 })
hl.monitor({ output="desc:CGC S27UHDIPSSR ...", -- 右、縦向き、時計回り90°
mode="3840x2160@60", position="2560x0", scale=1.5, transform=1 })
横にメモしてある罠は、実際に痛い目を見て得たものです。AMD 環境では VRR と direct_scanout を組み合わせると、フルスクリーンに切り替えた際に画面が黒くなるため、VRR はモニターごとに有効にしています。右側の縦向きモニターは HDMI を介すると最高でも 4K@30 に制限され、60Hz で動作させるには HDMI 2.1 ケーブルに変更するか、DP 経由にする必要があります(その場合、DP-2/DP-3 が CRTC と競合しないよう注意が必要です)。これらを書き残しておくことで、次回ケーブル交換や再インストール時に同じ轍を踏む必要がありません。設定ファイルはハードウェアのノートとしても機能します。
メインの修飾キーは SUPER で、大半は標準的なものです (T でターミナル、Q でウィンドウを閉じる、F でフルスクリーン、M でランチャー起動、SUPER+hjkl でフォーカス移動、SUPER+SHIFT+hjkl でワークスペースを指定方向のモニターへ移動)。その中で2箇所、意図的に変更しています:
hl.bind("ALT + Tab", hl.dsp.focus({ workspace = "m+1" })) -- 「現在のモニター」のワークスペースに切り替え、モニター間を跨がない
hl.bind(mainMod.." + V", hl.dsp.exec_cmd(
"cliphist list | fuzzel --dmenu | cliphist decode | wl-copy")) -- クリップボード履歴
マルチモニター環境では、デスクトップ全体でウィンドウを探すよりも、現在のモニターのワークスペースを切り替えた方が好ましいため、ALT+Tab の動作を変更しました。従来のウィンドウ切り替えは ALT+\`` に割り当てています。SUPER+V` では cliphist に保存されたクリップボード履歴を呼び出し、fuzzel で1つ選択して貼り付けます。
ウィンドウルールとアニメーション も Lua のテーブルを使用して記述しており、行ごとの windowrulev2 = ... 記述よりも明確です。ルールは class/title でマッチングさせ、特定のアプリケーションを固定された動作に割り当てます。電卓やファイル選択ダイアログなどは浮動ウィンドウとして設定し、中央に配置します。特定のアプリケーションは指定されたワークスペースに強制配置し、チャットソフトウェアの透明度を一段階調整します。アニメーションは、やや速めのカーブ(bezier でカスタムイージング + 短い時間)を採用しています。タイル型切り替えは「滑らか」であるべきですが「遅い」べきではなく、残像が長すぎると逆に邪魔になります。VRR が有効になっているモニターと組み合わせることで、追従性を優先した視覚効果を実現しています。角丸、ボーダー、ぼかしなどの decoration もこのレイヤーに集約されているため、Ghostty のようなアプリケーションは装飾を最小限に保ち、装飾全体をコンポジットタームinalによって統一して追加することができます。
もう一つ小さな罠も記録しておきます。Chrome の起動バインドは ~/.local/bin/google-chrome-stable の絶対パスを使用しています。Hyprland の PATH には ~/.local/bin が含まれていないため、コマンド名だけでは呼び出せないからです。ラッパースクリプト内では、インテリグラテッドグラフィックスの renderD ノードも同時に設定しています。配色は matugen によって注入されます。