# 通知設計書 3-ring_bell（ベル文字）

## 概要

本ドキュメントは、Ghosttyターミナルエミュレータにおけるベル文字（BEL、0x07）検出時の通知機能の設計について記述する。

### 本通知の処理概要

ring_bell通知は、ターミナルがベル文字（BEL、ASCII 0x07）を検出した際に発生する通知である。設定に応じてシステム音再生、オーディオファイル再生、ウィンドウのアテンション要求、タイトルへのベル絵文字追加、ボーダー表示などの多様なフィードバックが可能。

**業務上の目的・背景**：CLIアプリケーションがユーザーの注意を引くためにベル文字を出力する際、視覚的または聴覚的なフィードバックを提供する。コマンド完了通知、エラー警告、タイマーアラートなど、様々な用途でベル文字は利用される。Ghosttyは柔軟な設定により、ユーザーの好みに応じたベル動作を実現する。

**通知の送信タイミング**：ターミナルがベル文字（0x07）を受信したタイミングで即座に通知が発生する。ただし、100ミリ秒以内の連続したベルはレート制限により抑制される。

**通知の受信者**：Ghosttyターミナルを使用しているローカルユーザー。通知はOS/デスクトップ環境の機能を通じてユーザーに提供される。

**通知内容の概要**：ベル通知は複数の形式で提供される：システム音/カスタムオーディオ再生、ウィンドウのアテンション要求（タスクバーでの強調表示等）、タイトルバーへのベル絵文字追加、ウィンドウボーダーの色変更。

**期待されるアクション**：ユーザーはベル通知を受けて、ターミナルウィンドウに注意を向け、該当するプロセスの状態を確認する。

## 通知種別

複合通知（オーディオ通知 / 視覚通知 / システム通知）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（ベル文字受信時に即時処理） |
| 優先度 | 中 |
| リトライ | 無し |
| レート制限 | 100ミリ秒間隔 |

### 送信先決定ロジック

通知は、ベル文字を受信したターミナルサーフェスに対して送信される。具体的な通知方法はOSおよびランタイム（GTK等）の実装に依存する。

## 通知テンプレート

### ベル通知の場合

| 項目 | 内容 |
|-----|------|
| オーディオ | システム音またはカスタム音声ファイル |
| 視覚効果 | ボーダー色変更、タイトル絵文字追加 |
| システム通知 | ウィンドウアテンション要求 |

### 添付ファイル

該当なし

## テンプレート変数

該当なし（ベル通知はパラメータを持たない）

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 制御文字 | ベル文字（BEL、0x07）の受信 | `shell-integration-features`にbellが含まれる かつ 前回のベルから100ms以上経過 | ターミナルがベル文字を検出した時点で発火 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| `shell-integration-features`からbellが除外 | 設定でベル機能が無効化されている場合 |
| 100ms以内の連続ベル | レート制限により、短時間での連続ベルは抑制される |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ベル文字受信] --> B[StreamHandler.bell呼び出し]
    B --> C[surfaceMessageWriter ring_bell送信]
    C --> D[Surface.handleMessage]
    D --> E{レート制限チェック}
    E -->|100ms未満| F[処理スキップ]
    E -->|100ms以上| G[last_bell_time更新]
    G --> H[rt_app.performAction ring_bell]
    H --> I[apprt実装による処理]
    I --> J{bell-features設定}
    J -->|bell| K[システム音再生]
    J -->|audio| L[カスタム音声再生]
    J -->|visual| M[ボーダー表示]
    J -->|urgent| N[アテンション要求]
    J -->|notify| O[デスクトップ通知]
    J -->|title-prefix| P[タイトル絵文字追加]
    K --> Q[終了]
    L --> Q
    M --> Q
    N --> Q
    O --> Q
    P --> Q
    F --> Q
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| オーディオ再生失敗 | 音声ファイルが存在しない、再生デバイスが利用不可 | 警告ログを出力し、処理を継続 |
| performAction失敗 | apprrtがベル処理をサポートしていない | 警告ログを出力し、処理を継続 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 最小間隔 | 100ミリ秒 |
| 1分あたり上限 | 最大600回（理論値） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（24時間いつでも送信可能）

## セキュリティ考慮事項

- 悪意のあるプログラムが大量のベル文字を送信してユーザーを妨害する可能性があるが、レート制限により緩和される
- カスタムオーディオファイルのパスは設定ファイルで指定するため、信頼できるソースからのファイルを使用すること

## 備考

- bell-featuresで個別の機能を有効/無効化可能
- bell-audio-pathでカスタム音声ファイルを指定可能
- bell-audio-volumeで音量を0.0〜1.0の範囲で指定可能
- デフォルトではbellのみが有効

---

## コードリーディングガイド

本通知を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

ベル通知に関連する設定構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Config.zig | `src/config/Config.zig` | BellFeatures構造体（行8869付近）を確認 |
| 1-2 | surface.zig | `src/apprt/surface.zig` | Message.ring_bellを確認（行89） |

**読解のコツ**: BellFeaturesは複数のブール値フィールドを持ち、各種ベル機能の有効/無効を制御する。

#### Step 2: エントリーポイントを理解する

ベル文字の検出処理を追跡する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | stream_handler.zig | `src/termio/stream_handler.zig` | bell関数（行555-557）を確認 |

**主要処理フロー**:
1. **行555-557**: bell関数がsurfaceMessageWriter経由でring_bellメッセージを送信

#### Step 3: サーフェス処理を理解する

サーフェスがベルメッセージを受け取った後の処理を追跡する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Surface.zig | `src/Surface.zig` | handleMessage関数のring_bell分岐（行1079-1092） |

**主要処理フロー**:
- **行1080-1082**: レート制限チェック（100ms以内の連続ベルを抑制）
- **行1084**: last_bell_timeを現在時刻に更新
- **行1085-1091**: rt_app.performAction(.ring_bell)を実行

#### Step 4: アプリランタイム処理を理解する

アプリランタイム（GTK等）でのベル処理を追跡する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | action.zig | `src/apprt/action.zig` | ring_bellアクション（行293） |

### プログラム呼び出し階層図

```
terminal.Parser (ベル文字検出)
    │
    └─ stream_handler.bell()
           │
           └─ surfaceMessageWriter(.ring_bell)
                  │
                  └─ Surface.handleMessage()
                         │
                         ├─ レート制限チェック
                         │
                         └─ rt_app.performAction(.ring_bell)
                                │
                                └─ apprt固有の処理
                                       │
                                       ├─ システム音再生
                                       ├─ カスタム音声再生
                                       ├─ ボーダー表示
                                       ├─ アテンション要求
                                       └─ タイトル絵文字追加
```

### データフロー図

```
[入力]                [処理]                         [出力]

BEL (0x07)  ───▶  stream_handler.bell()      ───▶  Message.ring_bell
                        │
                        ▼
                  Surface.handleMessage()
                        │
                        ▼
                  レート制限チェック
                        │
                        ▼
                  rt_app.performAction()
                        │
                        ▼
                  bell-features に応じた出力  ───▶  オーディオ/視覚/システム通知
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| stream_handler.zig | `src/termio/stream_handler.zig` | ソース | bell関数（ベル文字検出時の処理） |
| surface.zig | `src/apprt/surface.zig` | ソース | ring_bellメッセージの定義 |
| Surface.zig | `src/Surface.zig` | ソース | ベルメッセージの処理とレート制限 |
| action.zig | `src/apprt/action.zig` | ソース | ring_bellアクション定義 |
| Config.zig | `src/config/Config.zig` | ソース | bell-features、bell-audio-path、bell-audio-volume設定 |
| window.zig | `src/apprt/gtk/class/window.zig` | ソース | GTKでのベル処理実装 |
