developing-gtk-apps について
Vala、Python、Rust で GTK 4/libadwaita アプリを開発する人向けのスキルです。アプリの構成、ライフサイクル、スレッド、リソース管理を扱い、言語別の資料も用意しています。
主な機能
- 01Vala、Python、Rust の言語別ガイド
- 02アプリのライフサイクルとスレッドの指針
- 03GSettings とアクションのパターン
- 04パッケージング、テスト、デバッグ資料
- 05Wayland と GNOME の連携指針
活用シーン
- 01GTK 4 アプリ開発の開始
- 02起動時のクラッシュや UI の停止の調査
- 03GSettings による設定の保存
- 04GTK アプリの Flatpak パッケージ準備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mhagrelius/ dotfiles --skill developing-gtk-appsインストール後、Claude Code で/developing-gtk-appsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
gnome-shell-companion-reference.mdgtk-dbus-reference.mdgtk-debugging-reference.mdgtk-gobject-reference.mdgtk-i18n-reference.mdgtk-packaging-reference.mdgtk-patterns-reference.mdgtk-testing-reference.mdpython-reference.mdrust-reference.mdvala-reference.md詳細
GTK アプリの開発
適切なアーキテクチャ、ライフサイクル、パターンを備えた堅牢な GTK 4/libadwaita アプリケーションを構築します。
基本原則: UI より先に基盤を整えます。ほとんどの GTK アプリで問題が発生するのは、アプリケーションのライフサイクル、スレッドモデル、リソース管理です。
UI スキルとの関係: このスキルではアーキテクチャと基盤部分を扱います。ウィジェットの選択、レイアウト、HIG への準拠については、designing-gnome-ui を使用してください。
まず言語のブランチを選ぶ
実行ごとに、Vala、Python、Rust のいずれかを使用します。プロジェクトから言語を判定します。.vala ソースまたは project() 内の 'vala' は Vala、gi をインポートする .py ソースは Python、gtk4 依存関係を含む Cargo.toml または .rs ソースは Rust を示します。新しいプロジェクトでは、ユーザーが指定した言語を使用します。その後、コードを書く前に該当するブランチファイルを開いてください。コードレベルの質問(構文、ボイラープレート、呼び出す関数など)はすべて、ここではなくそのファイルで回答します。
| 言語 | 開くファイル | 対象範囲 |
|---|---|---|
| Vala | vala-reference.md | ボイラープレート、所有権(owned/unowned/weak)、シグナル、プロパティ、リストモデル/ListView、非同期処理/スレッド、テンプレート、Meson、VAPI の検証 |
| Python | python-reference.md | ボイラープレート、GLib.idle_add、アクション、GSettings、さらに詳しい Python リファレンスへの案内 |
| Rust | rust-reference.md | ボイラープレート、サブクラス化(mod imp/wrapper)、clone!、プロパティ、シグナル、リストモデル/ListView、非同期処理/スレッド、テンプレート、ビルド、クレートソースの検証、エラーテキスト別にまとめたコンパイル時の落とし穴 |
プロジェクトでウィジェットツリーをすべてコードのみで構築している場合(リポジトリに .ui ファイルや .blp ファイルがない場合。よくある開発ルールです)は、その方法を続けてください。テンプレート/Blueprint/GResource の内容は省略し、ウィジェットを手動で構築します。
サブエージェント: サブエージェントには、このスキルが引き継がれません。GTK の作業をサブエージェントに委任する場合、コードを書く前に developing-gtk-apps を(UI の判断については designing-gnome-ui も)呼び出すよう、プロンプトで指示してください。
このファイルの残りの部分は言語に依存しません。どちらの言語にも当てはまるルールを説明します。
判断の流れ
| タスク | 使用するもの |
|---|---|
| 設定にはどのウィジェットを使うか? | designing-gnome-ui |
| 設定ウィンドウをどう構成するか? | designing-gnome-ui |
| 既存の GTK アプリの機能追加や動作修正 | THIS SKILL(まず言語のブランチを選ぶ) |
| gtk-rs の呼び出しがコンパイルに失敗する | THIS SKILL(rust-reference.md の Compile Traps) |
| アプリが起動時にクラッシュする | THIS SKILL |
| 操作中に UI がフリーズする | THIS SKILL |
| ユーザー設定を保存する方法 | THIS SKILL(GSettings) |
| シグナルが発火しない/メモリリークがある | THIS SKILL |
| 新しいアプリのボイラープレートをセットアップする | THIS SKILL |
| Flatpak 用にパッケージ化する | THIS SKILL |
| アプリが自分のウィンドウの位置を指定したり、前面に表示したりできない | gnome-shell-companion-reference.md |
| グローバルショートカットが必要、またはドックに表示したくない | gnome-shell-companion-reference.md |
現行の仕様(libadwaita 1.7+、GTK 4.18+)
置き換え — 現行の API を使用してください:
AdwShortcutsDialogはGtkShortcutsWindowを置き換えます(libadwaita 1.8+).dimmedCSS クラスは.dim-labelを置き換えます- libadwaita アプリでは
AdwSpinnerがGtkSpinnerを置き換えます Widget::compute_bounds()はallocation()を置き換えます(GTK 4.12 で非推奨。-D warningsを指定した clippy ではエラーになります)- Wayland を対象にしてください。GTK 4 では X11/Broadway バックエンドは非推奨であり(GTK 5 で削除予定)、GNOME 49+ には代替となる X11 セッションがありません
Wayland で明確に禁止されている操作 — これを前提に設計する前に確認してください。クライアントは、自分のウィンドウの位置を指定したり、その位置を読み取ったり、他のウィンドウより前面に表示したり、グローバルショートカットを取得したり、ドックに表示されないようにしたりできません。それぞれに GNOME Shell 拡張機能が必要です。詳しくは gnome-shell-companion-reference.md を参照してください。
新しいウィジェット(libadwaita 1.6–1.8、いずれも 1.9 API に含まれます):
AdwToggleGroup- 排他的なトグルのセットをまとめる単一のウィジェットAdwBottomSheet- 常時表示するボトムシートAdwWrapBox- 子要素を折り返して新しい行に配置するボックスAdwInlineViewSwitcher- カード、サイドバー、ボックス型リスト内でビューを切り替えるウィジェット
アプリケーション ID のルール
| ルール | 例 |
|---|---|
| 逆ドメイン表記 | com.example.MyApp |
| 英数字とドットのみ | org.gnome.TextEditor |
| 2 セグメント以上 | com.myapp(myapp は不可) |
| デスクトップファイルと一致 | com.example.MyApp.desktop |
ライフサイクル
| シグナル | タイミング | 用途 |
|---|---|---|
startup | アプリの起動時に一度 | アクション、CSS、GSettings |
activate | 起動または前面表示のたび | ウィンドウの作成/表示 |
shutdown | アプリの終了時 | 状態の保存、クリーンアップ |
open | ファイルがアプリに渡されたとき | ファイル引数の処理 |
startup をオーバーライドする場合は、独自のセットアップより先に親の実装を呼び出してください。ツールキットは親のハンドラー内で初期化されるため、これを行わずに作成したウィンドウは正常に動作しません。activate は、ウィンドウがすでに開いていればそれを再利用し、そうでなければ新しく作成します。そのため、2 回目の起動では実行中のインスタンスが前面に表示されます。
スレッド処理
GTK はシングルスレッドです。すべてのウィジェット呼び出しは、メインループのスレッドで行う必要があります。ワーカースレッドから結果を返す場合は、メインループにアイドルコールバックをスケジュールします(正確な呼び出しはブランチのファイルを参照してください)。スレッドよりも Gio の非同期 I/O を優先してください。これはメインループ上で実行され、受け渡し処理も不要です。スレッドは CPU 負荷の高い処理に限って使用します。
アクション
アクションは UI と動作を結び付けます。メニューやキーボードショートカットから、詳細名を使って呼び出します。アプリレベルのアクション(app.name)は startup で、ウィンドウレベルのアクション(win.name)はウィンドウの構築時に登録します。アクセラレーターは詳細名に割り当てます(app.quit → <Control>q)。コードはブランチのファイルに記述し、状態を持つアクションやパラメーター付きアクション、メニューの配線については gtk-patterns-reference.md を参照してください。
GSettings
ユーザー設定は、コンパイル済みスキーマをバックエンドとする GSettings を通じて永続化されます。キーをオブジェクトのプロパティに直接バインドすると、ハンドラーコードなしで両者が同期します。バインドされたプロパティを超える対応が必要な場合に限り、changed::key を購読してください。コードはブランチのファイルに記述し、スキーマ XML とインストールについては gtk-patterns-reference.md を参照してください。
デバッグ(クイックリファレンス)
GTK_DEBUG=interactive myapp # Open GTK Inspector (Ctrl+Shift+D)
G_MESSAGES_DEBUG=all myapp # Show all debug messages
G_DEBUG=fatal-criticals myapp # Abort on critical warnings
GSETTINGS_BACKEND=memory myapp # Test without persisting settings
デバッグの詳細なパターン、プロファイリング、GDB については gtk-debugging-reference.md を参照してください。
完了の定義
以下の各項目が、作成したコードで満たされていれば、基盤は完成です。
- ワーカースレッドがウィジェットに触れるのは、メインループ上のアイドルコールバックを介する場合のみです。
startupのオーバーライドは、最初に親の実装を呼び出します。- より長く存続するオブジェクト(アプリ、設定、モデル)に接続したすべてのハンドラーは、ウィジェットが閉じるときに切断されます。
- シグナルハンドラーは速やかに戻り、時間のかかる処理は非同期またはワーカースレッドで実行されます。
- ユーザーファイルは XDG ディレクトリ(GLib のユーザーデータ/設定/キャッシュ用ヘルパー)に保存されます。
- アプリケーション ID は逆ドメイン形式で、デスクトップファイルと一致します。
- 新しいコードでは「現行の機能」に記載された最新のウィジェットを使用します。
- Wayland で禁止されている操作のコントロールは、何も起きないまま操作を受け付け続けるのではなく、説明を添えて無効にします。
- (Rust)オブジェクトに再入可能なコールバックをまたいで
RefCellの借用を保持しません。 journalctl --user _COMM=<app>でアプリ自身の警告が表示されます。-- No entries --ではありません。- (Vala)すべてのスニペットで、
vala-reference.mdに記載された検証後のコンパイルチェックに合格しています。 - (Rust)すべてのスニペットで、
rust-reference.mdに記載された検証後のcargo checkに合格しています。
リファレンスファイル
| 必要な内容 | ファイル |
|---|---|
| Vala コード全般:ボイラープレート、所有権、シグナル、リストモデル、非同期処理、テンプレート、Meson、VAPI | vala-reference.md |
| Python コード全般:ボイラープレート、スレッド処理、アクション、GSettings | python-reference.md |
Rust コード全般:ボイラープレート、サブクラス化、clone!、プロパティ、シグナル、リストモデル、非同期処理、テンプレート、ビルド、コンパイルエラーの診断 | rust-reference.md |
| GObject の詳細、Python のみ:クラス、プロパティ、シグナル、リストモデル、ファクトリー | gtk-gobject-reference.md |
| 状態を持つアクション、GSettings スキーマ、GResource、Blueprint、非同期ファイル操作 | gtk-patterns-reference.md |
| デスクトップファイル、AppStream メタデータ、Meson のインストール、Flatpak、アイコン | gtk-packaging-reference.md |
| GNOME Shell コンパニオン拡張機能:ウィンドウの配置、グローバルショートカット、Wayland で禁止されていること | gnome-shell-companion-reference.md |
| テスト — pytest(Python)と GLib.Test/meson test(Vala)、ヘッドレス/CI | gtk-testing-reference.md |
| 国際化:gettext、複数形、.po ファイル、Blueprint の i18n、RTL | gtk-i18n-reference.md |
| DBus のアクティベーション、インターフェースのエクスポート、バックグラウンドサービス、Flatpak ポータル | gtk-dbus-reference.md |
| GTK Inspector、環境変数、プロファイリング、メモリのデバッグ、ログを参照可能にする方法 | gtk-debugging-reference.md |
| UI パターン、ウィジェット、HIG | designing-gnome-ui スキルを使用 |
外部リファレンス
- GTK 4 API
- Libadwaita API
- Valadoc(GTK/GLib/Adw の Vala バインディング)
- gtk4-rs docs(Rust バインディング。
Cargo.tomlのクレートバージョンに合わせて docs.rs のドキュメントを固定してください) - Blueprint docs