mcpField
D
developing-gtk-apps

developing-gtk-apps

github.com/mhagrelius开发120 次安装
代码仓库

关于 developing-gtk-apps

面向使用 Vala、Python 或 Rust 开发 GTK 4/libadwaita 应用的技能,侧重应用架构、生命周期、线程与资源管理,并提供语言专属参考资料。

主要功能

  1. 01Vala、Python 和 Rust 专属指南
  2. 02应用生命周期与线程指导
  3. 03GSettings 和操作模式
  4. 04打包、测试与调试参考
  5. 05Wayland 和 GNOME 集成指导

适用场景

  1. 01启动 GTK 4 应用开发
  2. 02排查启动崩溃或界面卡顿
  3. 03使用 GSettings 保存偏好设置
  4. 04为 Flatpak 打包准备 GTK 应用

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mhagrelius/dotfiles --skill developing-gtk-apps

安装后在 Claude Code 中输入/developing-gtk-apps确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

gnome-shell-companion-reference.md
gtk-dbus-reference.md
gtk-debugging-reference.md
gtk-gobject-reference.md
gtk-i18n-reference.md
gtk-packaging-reference.md
gtk-patterns-reference.md
gtk-testing-reference.md
python-reference.md
rust-reference.md
vala-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;对于新项目,使用用户指定的语言——然后在编写任何代码前打开对应的分支文件。所有代码级问题(语法、样板代码、应调用哪个函数)都应在对应文件中解答,而不是在此处:

语言打开涵盖内容
Valavala-reference.md样板代码、所有权(owned/unowned/weak)、信号、属性、列表模型/ListView、异步/线程、模板、Meson、VAPI 验证
Pythonpython-reference.md样板代码、GLib.idle_add、操作、GSettings,以及更深入的 Python 参考资料指引
Rustrust-reference.md样板代码、子类化(mod imp/wrapper)、clone!、属性、信号、列表模型/ListView、异步/线程、模板、构建、crate 源码验证、按错误文本索引的编译陷阱

如果项目完全通过代码构建控件树(仓库中没有 .ui 文件或 .blp 文件——这是常见的项目规范),请沿用这种方式:跳过模板/Blueprint/GResource 内容,手动构建控件。

子代理: 子代理不会继承此技能。将 GTK 工作委派给子代理时,提示词必须告知它在编写代码前调用 developing-gtk-apps(涉及 UI 决策时还要调用 designing-gnome-ui)。

本文件其余部分与语言无关:其中的规则适用于所有语言。

决策流程

任务使用
设置界面该用哪个控件?designing-gnome-ui
如何组织偏好设置窗口?designing-gnome-ui
修复现有 GTK 应用的功能或行为本技能(先选语言分支)
gtk-rs 调用编译失败本技能(rust-reference.md 的 Compile Traps)
应用启动时崩溃本技能
操作期间 UI 冻结本技能
如何保存用户偏好设置本技能(GSettings)
信号未触发/内存泄漏本技能
配置新应用的样板代码本技能
为 Flatpak 打包本技能
应用无法定位/抬升自己的窗口gnome-shell-companion-reference.md
需要全局快捷键,或要从程序坞隐藏gnome-shell-companion-reference.md

当前情况(libadwaita 1.7+、GTK 4.18+)

替代项——使用当前 API:

  • AdwShortcutsDialog 替代 GtkShortcutsWindow(libadwaita 1.8+)
  • .dimmed CSS 类替代 .dim-label
  • 在 libadwaita 应用中,AdwSpinner 替代 GtkSpinner
  • Widget::compute_bounds() 替代 allocation()(GTK 4.12 中已弃用;使用 -D warnings 的 clippy 会拒绝它)
  • 以 Wayland 为目标;X11/Broadway 后端在 GTK 4 中已弃用(计划在 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 会在已有窗口打开时复用该窗口,否则创建一个窗口,因此再次启动会唤起正在运行的实例。

线程

GTK 是单线程的:每次对控件的调用都必须在主循环所属的线程中执行。工作线程通过在主循环上调度空闲回调来传回结果(确切调用见你的分支文件)。优先使用 Gio 的异步 I/O,而非线程——它在主循环上运行,无需交接;仅将线程用于 CPU 密集型工作。

操作

操作将 UI 与行为连接起来;菜单和键盘快捷键通过详细名称调用操作。在 startup 中注册应用级操作(app.name),在构建窗口时注册窗口级操作(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、VAPIvala-reference.md
所有 Python 代码:样板代码、线程、操作、GSettingspython-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)、无头环境/CIgtk-testing-reference.md
国际化:gettext、复数形式、.po 文件、Blueprint i18n、RTLgtk-i18n-reference.md
DBus 激活、接口导出、后台服务、Flatpak 门户gtk-dbus-reference.md
GTK Inspector、环境变量、性能分析、内存调试、让日志易于访问gtk-debugging-reference.md
UI 模式、组件、HIG使用 designing-gnome-ui 技能

外部参考

评论

支持 Markdown