# 機能設計書 119-ジャンプリスト

## 概要

Windowsタスクバーのジャンプリストにプロファイルを登録する機能の設計書である。

### 本機能の処理概要

本機能は、Windows Terminalに登録されたプロファイル（PowerShell、Command Prompt、WSLディストリビューション等）をWindowsタスクバーのジャンプリストに登録する。タスクバー上のWindows Terminalアイコンを右クリックした際に表示されるジャンプリストから、直接特定のプロファイルでターミナルを起動できる。

**業務上の目的・背景**：ユーザーがWindows Terminalを起動する際、最も頻繁に使用するプロファイルに素早くアクセスできる仕組みが必要である。タスクバーのジャンプリストを活用することで、アプリケーションを先に開いてからプロファイルを選択するのではなく、タスクバーから直接目的のシェル環境を起動できる。

**機能の利用シーン**：タスクバーにピン留めされたWindows Terminalアイコンを右クリックし、表示されるジャンプリストから特定のプロファイル（PowerShell、Ubuntu WSL等）を選択して直接起動する場面で使用される。設定変更時に自動的にジャンプリストが更新される。

**主要な処理内容**：
1. 設定の変更を検出する（設定ハッシュの比較）
2. ICustomDestinationList で既存のジャンプリストをクリアする
3. アクティブプロファイルごとに IShellLinkW を生成する
4. プロファイル名、アイコン、起動引数（-p {GUID}）を設定する
5. ジャンプリストのタスクセクションに追加してコミットする

**関連システム・外部連携**：Windows Shell API（ICustomDestinationList、IShellLinkW）を使用する。wt.exe のパスを GetWtExePath で取得する。

**権限による制御**：特に権限による制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | タスクバージャンプリスト | 主画面 | タスクバーの右クリックメニューにプロファイル一覧を表示 |

## 機能種別

外部連携処理（Windows Shell API）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| settings | CascadiaSettings | Yes | プロファイル情報の取得元となる設定オブジェクト | null でないこと |

### 入力データソース

- CascadiaSettings のアクティブプロファイル一覧（ActiveProfiles）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ジャンプリスト項目 | IShellLinkW[] | プロファイルごとのシェルリンク |

### 出力先

Windowsタスクバーのジャンプリスト（ICustomDestinationList 経由）。

## 処理フロー

### 処理シーケンス

```
1. AppLogic から UpdateJumplist が呼び出される
   └─ 設定のハッシュが変更された場合のみ実行
2. バックグラウンドスレッドで処理を開始
   └─ co_await winrt::resume_background() で切り替え
3. ICustomDestinationList を生成
   └─ CLSID_DestinationList でインスタンス化
4. BeginList でジャンプリストの編集を開始
   └─ 利用可能なスロット数を取得
5. _updateProfiles でプロファイルごとのシェルリンクを生成
   └─ 既存項目をクリアし、各プロファイルの ShellLink を追加
6. AddUserTasks でタスクセクションに追加
   └─ ジャンプリストの「タスク」カテゴリに追加
7. CommitList でジャンプリストをコミット
   └─ 変更を確定
```

### フローチャート

```mermaid
flowchart TD
    A[UpdateJumplist 呼び出し] --> B{settings が null?}
    B -->|Yes| Z[co_return]
    B -->|No| C[バックグラウンドスレッドに切り替え]
    C --> D[ICustomDestinationList 生成]
    D --> E[BeginList でジャンプリスト編集開始]
    E --> F[_updateProfiles でプロファイル追加]
    F --> G[AddUserTasks でタスクセクションに追加]
    G --> H[CommitList でコミット]
    H --> I[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-119-01 | 全クリア方式 | ジャンプリストを毎回全クリアしてから再登録する | 常時 |
| BR-119-02 | アクティブプロファイルのみ | ActiveProfiles に含まれるプロファイルのみが登録される | 常時 |
| BR-119-03 | 起動引数形式 | `-p {GUID}` の形式で wt.exe の引数を設定する | 常時 |
| BR-119-04 | バックグラウンド実行 | Explorer API がブロックする可能性があるため、バックグラウンドスレッドで実行 | 常時 |
| BR-119-05 | null設定チェック | settings が null の場合はトレースログを出力して早期リターン | settings が null の場合 |
| BR-119-06 | アイコン形式 | アイコンパスにカンマが含まれる場合はインダイレクトアイコン（パス,インデックス）として処理 | アイコン指定時 |

### 計算ロジック

- アイコン形式判定: パスにカンマがある場合 → SetIconLocation(path, index)、exe/dll の場合 → SetIconLocation(path, 0)、それ以外 → PKEY_AppUserModel_DestListLogoUri を使用

## データベース操作仕様

### 操作別データベース影響一覧

本機能はデータベース操作を行わない。WindowsのジャンプリストAPI（COM）を使用する。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | null設定 | settings が null の場合 | TraceLogging でログ出力し co_return |
| HRESULT | COM エラー | ICustomDestinationList やシェルリンク操作が失敗した場合 | CATCH_LOG() マクロでログ出力しつつ例外を吸収 |

### リトライ仕様

リトライは行わない。エラーは CATCH_LOG() で吸収される。

## トランザクション仕様

ICustomDestinationList の BeginList/CommitList がトランザクション的に動作する。CommitList が呼ばれるまでジャンプリストは更新されない。

## パフォーマンス要件

バックグラウンドスレッドで実行されるため、UIスレッドの応答性には影響しない。

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

- wt.exe のパスは GetWtExePath で取得するため、正規のパスが使用される
- プロファイルのGUIDが引数として渡される
- ShellLink の作成には標準的なCOM APIが使用される

## 備考

- PKEY_AppUserModel_DestListLogoUri は UWP ジャンプリストがアイコンに使用するプロパティキー
- propkey.h に定義されていないため、コード内で DEFINE_PROPERTYKEY で定義している
- Jumplist クラスはすべてのメンバーが static であり、インスタンス状態を持たない

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Jumplist.h | `src/cascadia/TerminalApp/Jumplist.h` | **18-26行目**: Jumplist クラス定義。すべてのメンバーが static。UpdateJumplist、_updateProfiles、_createShellLink の3メソッド |

**読解のコツ**: Jumplist クラスはインスタンスを持たない純粋なユーティリティクラスとして実装されている。ICustomDestinationList や IShellLinkW は Windows Shell の COM インターフェースで、タスクバーのジャンプリストを制御する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AppLogic.cpp | `src/cascadia/TerminalApp/AppLogic.cpp` | **292行目**: Jumplist::UpdateJumplist(_settings) の呼び出し。設定ハッシュの変更検出後に実行 |

#### Step 3: ジャンプリスト更新処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Jumplist.cpp | `src/cascadia/TerminalApp/Jumplist.cpp` | **28-74行目**: UpdateJumplist メソッド。非同期コルーチンとして実装。ICustomDestinationList を使用してジャンプリストを更新する |

**主要処理フロー**:
1. **30-41行目**: settings null チェックとトレースログ
2. **49行目**: co_await winrt::resume_background() でバックグラウンドスレッドに切り替え
3. **53行目**: ICustomDestinationList のインスタンス生成
4. **57-58行目**: BeginList で編集開始
5. **61行目**: _updateProfiles でプロファイル追加
6. **69行目**: AddUserTasks でタスクセクションに追加
7. **71行目**: CommitList でコミット

#### Step 4: プロファイル追加とシェルリンク生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Jumplist.cpp | `src/cascadia/TerminalApp/Jumplist.cpp` | **83-99行目**: _updateProfiles メソッド。全クリア後に各プロファイルの ShellLink を生成して追加 |
| 4-2 | Jumplist.cpp | `src/cascadia/TerminalApp/Jumplist.cpp` | **113-156行目**: _createShellLink メソッド。wt.exe のパス設定、引数設定、アイコン設定、タイトル設定を行う |

**主要処理フロー（_createShellLink）**:
- **117行目**: GetWtExePath() で wt.exe のパスを取得
- **118行目**: SetPath で実行ファイルパスを設定
- **119行目**: SetArguments で起動引数を設定
- **127-150行目**: アイコン形式の判定と設定（カンマ区切り、exe/dll、URI形式の3パターン）
- **152行目**: PKEY_Title でプロファイル名を設定

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

```
AppLogic::_OnSettingsChanged (AppLogic.cpp)
    |
    +-- Jumplist::UpdateJumplist (Jumplist.cpp:28)
            |
            +-- co_await resume_background() (スレッド切り替え)
            |
            +-- ICustomDestinationList::BeginList
            |
            +-- Jumplist::_updateProfiles (Jumplist.cpp:83)
            |       |
            |       +-- IObjectCollection::Clear
            |       |
            |       +-- for each profile:
            |               +-- Jumplist::_createShellLink (Jumplist.cpp:113)
            |               |       |
            |               |       +-- GetWtExePath
            |               |       +-- IShellLinkW::SetPath
            |               |       +-- IShellLinkW::SetArguments
            |               |       +-- IShellLinkW::SetIconLocation / PKEY_AppUserModel_DestListLogoUri
            |               |       +-- IPropertyStore::SetValue(PKEY_Title)
            |               |
            |               +-- IObjectCollection::AddObject
            |
            +-- ICustomDestinationList::AddUserTasks
            |
            +-- ICustomDestinationList::CommitList
```

### データフロー図

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

CascadiaSettings の      _updateProfiles で           ICustomDestinationList
ActiveProfiles ──────>   各プロファイルの  ──────>    に登録
                         ShellLink を生成
                              |
Profile.Name ──────>    _createShellLink で          タスクバー
Profile.Guid ──────>    wt.exe + 引数を設定 ──────>  ジャンプリスト
Profile.Icon ──────>    アイコンを設定
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Jumplist.h | `src/cascadia/TerminalApp/Jumplist.h` | ソース | Jumplist クラスの宣言 |
| Jumplist.cpp | `src/cascadia/TerminalApp/Jumplist.cpp` | ソース | ジャンプリスト更新処理の実装 |
| AppLogic.cpp | `src/cascadia/TerminalApp/AppLogic.cpp` | ソース | UpdateJumplist の呼び出し元 |
| AppLogic.h | `src/cascadia/TerminalApp/AppLogic.h` | ソース | AppLogic クラスの宣言 |
| WtExeUtils.h | `src/cascadia/WtExeUtils.h` | ソース | GetWtExePath ユーティリティ |
