Skip to content

Instantly share code, notes, and snippets.

@Comamoca
Last active January 21, 2026 15:24
Show Gist options
  • Select an option

  • Save Comamoca/2baa860a7245448688b3e40b8c01d0c5 to your computer and use it in GitHub Desktop.

Select an option

Save Comamoca/2baa860a7245448688b3e40b8c01d0c5 to your computer and use it in GitHub Desktop.

Niri外部ディスプレイ接続時クラッシュの原因と解決策

Note

このレポートはClaude Codeに調査をさせて書かせたものです。 僕の環境はこれで直ったので参考までに公開しますが、不正確な可能性もあります。

問題の概要

niriで外部ディスプレイを接続するとクラッシュする

調査結果と根拠

根本原因: 設定変更の証拠

設定ファイルの比較により、決定的な証拠を発見しました:

証拠1: prefer-no-csdの有効化

現在の設定 (config/niri/config.kdl:228):

prefer-no-csd

有効化されている (コメント無し)

バックアップ設定 (config.kdl.backup:226):

// prefer-no-csd

無効化されている (コメントアウト)

証拠2: 角丸ウィンドウルールの有効化

現在の設定 (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
}

無効化されている (/-でコメントアウト)

技術的な根拠

1. prefer-no-csdがレンダリングを変更する仕組み

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)を省略するよう要求
  • ウィンドウがタイル状態であることを通知
  • フォーカスリングとボーダーの描画方法が背後ではなく周囲に変更される

2. 角丸設定がレンダリングを複雑化する仕組み

geometry-corner-radius 12clip-to-geometry true により:

  • すべてのウィンドウジオメトリに12px半径の角丸を適用
  • ジオメトリにクリッピング(切り取り)を強制
  • GPUレンダリングパイプラインで追加の計算が必要

3. マルチディスプレイ環境での競合メカニズム

内蔵ディスプレイ (eDP-1) の設定 (config.kdl:69-98):

/-output "eDP-1" {
    mode "1920x1080@120.030"
    scale 2              ← 200%スケーリング
    position x=1280 y=0
}

※ただし、この設定は/-でコメントアウトされているため無効

外部ディスプレイ接続時に発生する問題:

  1. 異なるスケーリング係数: 内蔵ディスプレイ scale=2、外部ディスプレイ scale=1(通常)
  2. 角丸の論理ピクセル計算: 12pxの角丸が、scale=2では物理24px、scale=1では物理12pxになる
  3. CSD削除とフォーカスリング描画: prefer-no-csdにより、フォーカスリングが「周囲」に描画されるが、角丸ジオメトリとの組み合わせで座標計算が破綻
  4. クリッピング領域の不一致: 異なるスケーリングを持つディスプレイ間でクリッピング領域の同期が失敗

クラッシュのメカニズム詳細

Niriのレンダリングパイプラインで以下の処理が連続して実行されます:

1. ウィンドウジオメトリ計算
   ↓
2. 角丸クリッピングパス生成 (geometry-corner-radius)
   ↓
3. フォーカスリング描画位置計算 (prefer-no-csdの影響を受ける)
   ↓
4. マルチディスプレイ座標変換 (スケーリング係数適用)
   ↓
5. GPUバッファ描画

クラッシュポイント:

  • ステップ3→4: 角丸クリッピングパスが適用されたウィンドウに対して、prefer-no-csdモードでフォーカスリングを「周囲」に描画しようとすると、座標計算で負の値やオーバーフローが発生
  • ステップ4: 異なるスケーリング係数を持つディスプレイ間でクリッピングパスを変換する際、浮動小数点誤差が蓄積
  • ステップ5: 無効な座標やクリッピング領域がGPUバッファに送られ、レンダラーがアサーションエラーやセグメンテーション違反でクラッシュ

バックアップ設定では発生しない理由:

  • prefer-no-csdが無効 → フォーカスリングは「背後」に描画され、角丸との相互作用が発生しない
  • 角丸ルールが無効 → クリッピングパスが生成されず、座標計算がシンプル

副次的な問題

  1. Output設定がコメントアウト (config/niri/config.kdl:69-98)

    /-output "eDP-1" {
        mode "1920x1080@120.030"
        scale 2
        position x=1280 y=0
    }
    • 内蔵ディスプレイの設定が無効化されている
    • 外部ディスプレイの明示的な設定が存在しない
  2. DMS統合の問題

    • config/niri/dms/outputs.kdl が空ファイル (0バイト)
    • 自動ディスプレイプロファイルが利用できない
    • 外部ディスプレイがデフォルトのフォールバック動作に依存

解決策と優先順位

根拠に基づく解決策の評価

解決策 クラッシュ防止効果 機能性への影響 推奨度
prefer-no-csdを無効化 ✓✓✓ 高 角丸は維持される ⭐⭐⭐ 最推奨
角丸を無効化 ✓✓✓ 高 prefer-no-csdは維持される ⭐⭐ 推奨
両方無効化 ✓✓✓ 確実 両方の機能を失う ⭐ 最終手段
ディスプレイ設定のみ ✓ 低 根本原因は未解決 ✗ 非推奨

最優先の対応

Option 1: prefer-no-csdを無効化 (最推奨)

根拠: prefer-no-csdがフォーカスリング描画を「周囲」モードに変更し、角丸ジオメトリとの座標計算で競合を引き起こす主犯。これを無効化すれば、角丸は維持しながらクラッシュを防止できる。

config/niri/config.kdl:228

// prefer-no-csd  // コメントアウトして無効化

トレードオフ:

  • ✓ 角丸ウィンドウは維持される
  • ✗ フォーカスリングが半透明ウィンドウの背後に描画される(元の動作に戻る)

Option 2: 角丸を無効化 (推奨)

根拠: 角丸クリッピングがレンダリングを複雑化させ、マルチディスプレイ環境でのスケーリング変換時に問題を引き起こす。無効化すれば、prefer-no-csdは維持しながらクラッシュを防止できる。

config/niri/config.kdl:296-300

/-window-rule {
    geometry-corner-radius 12
    clip-to-geometry true
}

トレードオフ:

  • ✓ prefer-no-csd(CSD削除)は維持される
  • ✗ すべてのウィンドウの角丸が失われる

Option 3: 両方を無効化 (確実だが最終手段)

根拠: 両方を無効化すれば、競合する要素がすべて取り除かれ、確実にクラッシュを防止できる。ただし、両方の機能を失う。

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" {
    # 接続時に自動検出される
    # 必要に応じてmodescaleを指定
}

注意: この対応だけではクラッシュは解決しません。prefer-no-csdまたは角丸の無効化が必須です。

実装計画

フェーズ1: 緊急修正(クラッシュ解決)

目標: 外部ディスプレイ接続時のクラッシュを即座に解決

  1. prefer-no-csdを無効化 (Option 1を採用)

    • ファイル: config/niri/config.kdl
    • 行: 228
    • 変更: prefer-no-csd// prefer-no-csd
  2. niriを再起動

    niri msg action quit
    # niriが自動的に再起動される(セッション管理による)
    # または手動で: systemctl --user restart niri
  3. 外部ディスプレイ接続テスト

    • 外部ディスプレイを接続
    • クラッシュが発生しないことを確認
  4. クラッシュが継続する場合の代替策

    • 角丸設定も無効化 (Option 3に変更)
    • ファイル: config/niri/config.kdl
    • 行: 296-300
    • 変更: window-rule {/-window-rule {

フェーズ2: 安定性向上(任意)

目標: ディスプレイ設定を明示的に構成して安定性を向上

  1. 内蔵ディスプレイ設定を有効化

    • ファイル: config/niri/config.kdl
    • 行: 69
    • 変更: /-output "eDP-1" {output "eDP-1" {
    • position設定は削除または調整が必要かもしれない
  2. 外部ディスプレイ設定を追加 (接続タイプに応じて)

    • ファイル: config/niri/config.kdl
    • 行: 99付近(outputブロックの後)
    • 追加:
      output "HDMI-A-1" {
          # 自動検出に任せる、または明示的にmodeを指定
      }
  3. niriを再起動して設定を適用

検証方法

1. 即座の確認(クラッシュ防止)

# niriを再起動
niri msg action quit

# 外部ディスプレイを接続
# → クラッシュせずに両方のディスプレイが認識されることを確認

2. 詳細な動作確認

# ディスプレイの認識状況を確認
niri msg outputs

# 期待される出力:
# - eDP-1 (内蔵ディスプレイ)
# - HDMI-A-1 または DP-1 など (外部ディスプレイ)

3. 視覚的な確認

  • 両方のディスプレイが正しく認識されている
  • ウィンドウが両方のディスプレイで正常に表示される
  • ウィンドウを両ディスプレイ間で移動できる
  • スケーリングが適切に適用されている(文字が読める)
  • フォーカスリングが正常に表示される
  • (Option 1の場合) 角丸ウィンドウが表示される

4. ログ確認(トラブルシューティング用)

# niriのログを確認
journalctl --user -u niri -n 100 -f

# エラーやクラッシュの痕跡がないことを確認
# 特に以下のようなメッセージがないか確認:
# - "assertion failed"
# - "segmentation fault"
# - "panicked at"

5. リグレッションテスト

  • 単一ディスプレイ(外部ディスプレイ切断)でも正常に動作
  • 外部ディスプレイの接続・切断を繰り返してもクラッシュしない
  • 異なる解像度の外部ディスプレイでも動作する

影響を受けるファイル

  • 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と角丸の組み合わせがマルチディスプレイレンダリングと競合
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment