Skip to content

fix: Ghostty で zoom/pan が追従しない問題を修正#23

Merged
flexphere merged 2 commits intomainfrom
worktree-cuddly-sparking-dawn
Mar 25, 2026
Merged

fix: Ghostty で zoom/pan が追従しない問題を修正#23
flexphere merged 2 commits intomainfrom
worktree-cuddly-sparking-dawn

Conversation

@flexphere
Copy link
Copy Markdown
Owner

概要

Kitty Graphics Protocol の placement コマンドに placement ID (p=1) を追加し、Ghostty 等の仕様準拠ターミナルで zoom/pan が正しく追従するようにする。

変更内容

  • Display() の placement コマンドに p=1 を追加(メイン画像)
  • DisplayMinimap() の placement コマンドに p=1 を追加(ミニマップ)
  • テストに placement ID の存在確認アサーションを追加

背景

placement ID を指定しない場合、a=p コマンドは毎回新しい placement を作成する。WezTerm はプレースメントをセルにマッピングする独自実装のため問題が表面化しないが、Ghostty は仕様通りに複数 placement を蓄積するため、古い画像が残り zoom/pan に追従しないように見えていた。

p=1 を指定することで、毎フレームの placement が前回のものを置換するようになり、全ターミナルで一貫した挙動になる。

テスト計画

  • 既存テスト全パス (make ci)
  • 新規テスト追加: kitty_renderer_test.gop=1 アサーション追加
  • 手動確認: Ghostty で zoom/pan が正常に追従すること
  • 手動確認: WezTerm でリグレッションがないこと

備考

  • Kitty Graphics Protocol 仕様: "each display command creates a new placement, unless the placement id key p is also specified, in which case the existing placement is replaced"
  • placement ID は image ID ごとにスコープされるため、メイン画像・ミニマップ両方で p=1 を使用可能

🤖 Generated with Claude Code

…ompatibility

Without a placement ID (p=), each Display() call creates a new placement
instead of replacing the previous one. WezTerm handles this gracefully by
mapping placements to cells, but spec-faithful terminals like Ghostty
accumulate stale placements, causing zoom/pan to appear unresponsive.

Adding p=1 ensures each frame's placement replaces the previous one,
producing consistent behavior across all Kitty Graphics Protocol terminals.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 25, 2026 08:52
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Kitty Graphics Protocol の placement コマンドに placement ID(p=1)を付与し、Ghostty 等の仕様準拠ターミナルでフレーム更新時に placement が蓄積して zoom/pan が追従しなくなる問題を防ぐ変更です。

Changes:

  • KittyRenderer.Display() の placement コマンドに p=1 を追加
  • KittyRenderer.DisplayMinimap() の placement コマンドに p=1 を追加
  • テストで p=1 の出力有無を検証するアサーションを追加

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
internal/adapter/renderer/kitty_renderer.go メイン画像・ミニマップの placement を p=1 で置換更新できるようにし、端末差分による表示不整合を抑制
internal/adapter/renderer/kitty_renderer_test.go placement ID(p=1)が出力に含まれることをテストで検証

Comment on lines +158 to +160
if !strings.Contains(output, "p=1") {
t.Error("output should contain placement ID for consistent cross-terminal behavior")
}
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

このアサーションが strings.Contains(output, "p=1") だと、DisplayMinimap() の output に含まれる base64 ペイロード内の偶然一致でテストが通ってしまう可能性があります(placement コマンドに p=1 が無くても false positive になり得ます)。"\x1b_Ga=p,i=2,p=1" のように placement コマンド部分に限定して検証するか、a=p 以降〜 \x1b\\ までを抽出してその範囲に p=1 があることを確認すると堅牢です。

Suggested change
if !strings.Contains(output, "p=1") {
t.Error("output should contain placement ID for consistent cross-terminal behavior")
}
// placement コマンド部分(a=p〜ESC 終端)に限定して p=1 を検証する
aPos := strings.Index(output, "a=p")
if aPos == -1 {
t.Fatal("output should contain action=place (a=p) command")
}
// Kitty graphics プロトコルの終端シーケンスは ESC '\' = "\x1b\\"
termPosRel := strings.Index(output[aPos:], "\x1b\\")
if termPosRel == -1 {
t.Fatalf("output should contain kitty graphics terminator after placement command: %q", output)
}
placementCmd := output[aPos : aPos+termPosRel]
if !strings.Contains(placementCmd, "p=1") {
t.Errorf("placement command should contain placement ID p=1 for consistent cross-terminal behavior, got: %q", placementCmd)
}

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

9b5d2ee で修正 — DisplayMinimap テストの p=1 検証を placement コマンド部分に限定し、base64 ペイロードとの偶然一致を防止しました。

…ap test

The previous strings.Contains(output, "p=1") check could false-positive
against base64-encoded RGBA payload data. Extract the placement command
(a=p...ESC\) and verify p=1 within that range only.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@flexphere flexphere marked this pull request as ready for review March 25, 2026 08:59
Copilot AI review requested due to automatic review settings March 25, 2026 08:59
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@flexphere flexphere merged commit 23687fb into main Mar 25, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants