Note
このレポートはClaude Codeに調査をさせて書かせたものです。 僕の環境はこれで直ったので参考までに公開しますが、不正確な可能性もあります。
niriで外部ディスプレイを接続するとクラッシュする
設定ファイルの比較により、決定的な証拠を発見しました:
現在の設定 (config/niri/config.kdl:228):
prefer-no-csd→ 有効化されている (コメント無し)
バックアップ設定 (config.kdl.backup:226):
// prefer-no-csd→ 無効化されている (コメントアウト)
現在の設定 (config/niri/config.kdl:296-300):
window-rule {
geometry-corner-radius 12
clip-to-geometry true
}→ 有効化されている
バックアップ設定 (config.kdl.backup:297-300):
/-window-rule {
geometry-corner-radius 12
clip-to-geometry true
}→ 無効化されている (/-でコメントアウト)
niriの公式ドキュメント (config.kdl:223-227) によると:
// Uncomment this line to ask the clients to omit their client-side decorations if possible.
// Additionally, clients will be informed that they are tiled, removing some client-side rounded corners.
// This option will also fix border/focus ring drawing behind some semitransparent windows.
prefer-no-csdを有効化すると:
- クライアントにCSS(Client-Side Decorations)を省略するよう要求
- ウィンドウがタイル状態であることを通知
- フォーカスリングとボーダーの描画方法が背後ではなく周囲に変更される
geometry-corner-radius 12 と clip-to-geometry true により:
- すべてのウィンドウジオメトリに12px半径の角丸を適用
- ジオメトリにクリッピング(切り取り)を強制
- GPUレンダリングパイプラインで追加の計算が必要
内蔵ディスプレイ (eDP-1) の設定 (config.kdl:69-98):
/-output "eDP-1" {
mode "1920x1080@120.030"
scale 2 ← 200%スケーリング
position x=1280 y=0
}※ただし、この設定は/-でコメントアウトされているため無効
外部ディスプレイ接続時に発生する問題:
- 異なるスケーリング係数: 内蔵ディスプレイ scale=2、外部ディスプレイ scale=1(通常)
- 角丸の論理ピクセル計算: 12pxの角丸が、scale=2では物理24px、scale=1では物理12pxになる
- CSD削除とフォーカスリング描画:
prefer-no-csdにより、フォーカスリングが「周囲」に描画されるが、角丸ジオメトリとの組み合わせで座標計算が破綻 - クリッピング領域の不一致: 異なるスケーリングを持つディスプレイ間でクリッピング領域の同期が失敗
Niriのレンダリングパイプラインで以下の処理が連続して実行されます:
1. ウィンドウジオメトリ計算
↓
2. 角丸クリッピングパス生成 (geometry-corner-radius)
↓
3. フォーカスリング描画位置計算 (prefer-no-csdの影響を受ける)
↓
4. マルチディスプレイ座標変換 (スケーリング係数適用)
↓
5. GPUバッファ描画
クラッシュポイント:
- ステップ3→4: 角丸クリッピングパスが適用されたウィンドウに対して、
prefer-no-csdモードでフォーカスリングを「周囲」に描画しようとすると、座標計算で負の値やオーバーフローが発生 - ステップ4: 異なるスケーリング係数を持つディスプレイ間でクリッピングパスを変換する際、浮動小数点誤差が蓄積
- ステップ5: 無効な座標やクリッピング領域がGPUバッファに送られ、レンダラーがアサーションエラーやセグメンテーション違反でクラッシュ
バックアップ設定では発生しない理由:
prefer-no-csdが無効 → フォーカスリングは「背後」に描画され、角丸との相互作用が発生しない- 角丸ルールが無効 → クリッピングパスが生成されず、座標計算がシンプル
-
Output設定がコメントアウト (config/niri/config.kdl:69-98)
/-output "eDP-1" { mode "1920x1080@120.030" scale 2 position x=1280 y=0 }
- 内蔵ディスプレイの設定が無効化されている
- 外部ディスプレイの明示的な設定が存在しない
-
DMS統合の問題
config/niri/dms/outputs.kdlが空ファイル (0バイト)- 自動ディスプレイプロファイルが利用できない
- 外部ディスプレイがデフォルトのフォールバック動作に依存
| 解決策 | クラッシュ防止効果 | 機能性への影響 | 推奨度 |
|---|---|---|---|
| prefer-no-csdを無効化 | ✓✓✓ 高 | 角丸は維持される | ⭐⭐⭐ 最推奨 |
| 角丸を無効化 | ✓✓✓ 高 | prefer-no-csdは維持される | ⭐⭐ 推奨 |
| 両方無効化 | ✓✓✓ 確実 | 両方の機能を失う | ⭐ 最終手段 |
| ディスプレイ設定のみ | ✓ 低 | 根本原因は未解決 | ✗ 非推奨 |
根拠: prefer-no-csdがフォーカスリング描画を「周囲」モードに変更し、角丸ジオメトリとの座標計算で競合を引き起こす主犯。これを無効化すれば、角丸は維持しながらクラッシュを防止できる。
config/niri/config.kdl:228
// prefer-no-csd // コメントアウトして無効化トレードオフ:
- ✓ 角丸ウィンドウは維持される
- ✗ フォーカスリングが半透明ウィンドウの背後に描画される(元の動作に戻る)
根拠: 角丸クリッピングがレンダリングを複雑化させ、マルチディスプレイ環境でのスケーリング変換時に問題を引き起こす。無効化すれば、prefer-no-csdは維持しながらクラッシュを防止できる。
config/niri/config.kdl:296-300
/-window-rule {
geometry-corner-radius 12
clip-to-geometry true
}トレードオフ:
- ✓ prefer-no-csd(CSD削除)は維持される
- ✗ すべてのウィンドウの角丸が失われる
根拠: 両方を無効化すれば、競合する要素がすべて取り除かれ、確実にクラッシュを防止できる。ただし、両方の機能を失う。
config/niri/config.kdl:228, 296-300
// prefer-no-csd
/-window-rule {
geometry-corner-radius 12
clip-to-geometry true
}目的: 自動検出に頼らず、明示的なディスプレイ設定で安定性を向上
config/niri/config.kdl:69-98 - 内蔵ディスプレイを有効化
output "eDP-1" {
mode "1920x1080@120.030"
scale 2
}config/niri/config.kdl:99 - 外部ディスプレイ用の設定を追加
output "HDMI-A-1" {
# 接続時に自動検出される
# 必要に応じてmodeとscaleを指定
}注意: この対応だけではクラッシュは解決しません。prefer-no-csdまたは角丸の無効化が必須です。
目標: 外部ディスプレイ接続時のクラッシュを即座に解決
-
prefer-no-csdを無効化 (Option 1を採用)
- ファイル:
config/niri/config.kdl - 行: 228
- 変更:
prefer-no-csd→// prefer-no-csd
- ファイル:
-
niriを再起動
niri msg action quit # niriが自動的に再起動される(セッション管理による) # または手動で: systemctl --user restart niri
-
外部ディスプレイ接続テスト
- 外部ディスプレイを接続
- クラッシュが発生しないことを確認
-
クラッシュが継続する場合の代替策
- 角丸設定も無効化 (Option 3に変更)
- ファイル:
config/niri/config.kdl - 行: 296-300
- 変更:
window-rule {→/-window-rule {
目標: ディスプレイ設定を明示的に構成して安定性を向上
-
内蔵ディスプレイ設定を有効化
- ファイル:
config/niri/config.kdl - 行: 69
- 変更:
/-output "eDP-1" {→output "eDP-1" { - position設定は削除または調整が必要かもしれない
- ファイル:
-
外部ディスプレイ設定を追加 (接続タイプに応じて)
- ファイル:
config/niri/config.kdl - 行: 99付近(outputブロックの後)
- 追加:
output "HDMI-A-1" { # 自動検出に任せる、または明示的にmodeを指定 }
- ファイル:
-
niriを再起動して設定を適用
# niriを再起動
niri msg action quit
# 外部ディスプレイを接続
# → クラッシュせずに両方のディスプレイが認識されることを確認# ディスプレイの認識状況を確認
niri msg outputs
# 期待される出力:
# - eDP-1 (内蔵ディスプレイ)
# - HDMI-A-1 または DP-1 など (外部ディスプレイ)- 両方のディスプレイが正しく認識されている
- ウィンドウが両方のディスプレイで正常に表示される
- ウィンドウを両ディスプレイ間で移動できる
- スケーリングが適切に適用されている(文字が読める)
- フォーカスリングが正常に表示される
- (Option 1の場合) 角丸ウィンドウが表示される
# niriのログを確認
journalctl --user -u niri -n 100 -f
# エラーやクラッシュの痕跡がないことを確認
# 特に以下のようなメッセージがないか確認:
# - "assertion failed"
# - "segmentation fault"
# - "panicked at"- 単一ディスプレイ(外部ディスプレイ切断)でも正常に動作
- 外部ディスプレイの接続・切断を繰り返してもクラッシュしない
- 異なる解像度の外部ディスプレイでも動作する
config/niri/config.kdl- メイン設定ファイル (228行目、296-300行目、69-98行目)config/niri/dms/outputs.kdl- DMS出力設定 (現在空)config/niri/config.kdl.backup- バックアップ (参照用)
- 問題を導入したコミット:
6872f05 - feat: Major configuration updates - 以前のバックアップが存在:
config/niri/config.kdl.backup - prefer-no-csdと角丸の組み合わせがマルチディスプレイレンダリングと競合