developing-gtk-apps

Build robust GTK 4/libadwaita applications with correct architecture, lifecycle, and patterns.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "developing-gtk-apps" with this command: npx skills add mhagrelius/dotfiles/mhagrelius-dotfiles-developing-gtk-apps

Developing GTK Apps

Build robust GTK 4/libadwaita applications with correct architecture, lifecycle, and patterns.

Core principle: Get the foundation right before the UI. Application lifecycle, threading model, and resource management are where most GTK apps break.

Relationship to UI skill: This skill handles architecture and plumbing. For widget selection, layout, and HIG compliance, use designing-gnome-ui .

Decision Flow

Task Use

Which widget for settings? designing-gnome-ui

How to structure preferences window? designing-gnome-ui

App crashes on startup THIS SKILL

UI freezes during operation THIS SKILL

How to save user preferences THIS SKILL (GSettings)

Signal not firing/memory leak THIS SKILL

Setting up new app boilerplate THIS SKILL

Packaging for Flatpak THIS SKILL

What's Current (libadwaita 1.7+, GTK 4.18+)

API deprecations to avoid:

  • GtkShortcutsWindow → Use AdwShortcutsDialog (libadwaita 1.8+)

  • .dim-label CSS class → Use .dimmed class

  • X11/Broadway backends are deprecated in GTK 4 (removal planned for GTK 5)

New patterns (libadwaita 1.6-1.8):

  • AdwSpinner

  • Preferred over GtkSpinner

  • AdwToggleGroup

  • Replaces multiple exclusive GtkToggleButton instances

  • AdwBottomSheet

  • Persistent bottom sheets

  • AdwWrapBox

  • Box that wraps children to new lines

  • AdwInlineViewSwitcher

  • For cards, sidebars, boxed lists

Application Boilerplate

import gi gi.require_version('Gtk', '4.0') gi.require_version('Adw', '1') from gi.repository import Gtk, Adw, Gio

class MyApp(Adw.Application): def init(self): super().init( application_id="com.example.MyApp", flags=Gio.ApplicationFlags.DEFAULT_FLAGS )

def do_activate(self):
    win = self.props.active_window
    if not win:
        win = MyWindow(application=self)
    win.present()

class MyWindow(Adw.ApplicationWindow): def init(self, **kwargs): super().init(**kwargs) self.set_default_size(800, 600)

def main(): app = MyApp() return app.run(None)

Application ID Rules

Rule Example

Reverse domain notation com.example.AppName

Only alphanumeric + dots org.gnome.TextEditor

Min 2 segments com.myapp (not myapp )

Match desktop file com.example.MyApp.desktop

Lifecycle Signals

Signal When Use For

startup

Once, app launches Actions, CSS, GSettings

activate

Each launch/raise Create/present window

shutdown

App exits Save state, cleanup

open

Files passed to app Handle file arguments

def do_startup(self): Adw.Application.do_startup(self) # Chain up FIRST self.setup_actions()

Threading - The Critical Rule

GTK is single-threaded. All UI calls MUST happen on the main thread.

WRONG - will crash

def background_task(): result = slow_computation() self.label.set_text(result) # CRASH

RIGHT - use GLib.idle_add

def background_task(): result = slow_computation() GLib.idle_add(self.label.set_text, result) # Safe

threading.Thread(target=background_task).start()

For async patterns with Gio.Task and cancellation, see gtk-patterns-reference.md .

Actions (Quick Reference)

Actions connect UI to behavior. Define at app level (app.action ) or window level (win.action ).

In do_startup - app-level action

quit_action = Gio.SimpleAction.new("quit", None) quit_action.connect("activate", lambda a, p: self.quit()) self.add_action(quit_action) self.set_accels_for_action("app.quit", ["<Control>q"])

In window init - window-level action

save_action = Gio.SimpleAction.new("save", None) save_action.connect("activate", self.on_save) self.add_action(save_action) self.get_application().set_accels_for_action("win.save", ["<Control>s"])

For stateful actions (toggles), parameterized actions, and menu integration, see gtk-patterns-reference.md .

GSettings (Quick Reference)

Persist user preferences with GSettings. Requires a schema file.

In app init

self.settings = Gio.Settings.new("com.example.MyApp")

Read/write values

dark = self.settings.get_boolean("dark-mode") self.settings.set_boolean("dark-mode", True)

Bind to widget property (auto-syncs)

self.settings.bind("window-width", window, "default-width", Gio.SettingsBindFlags.DEFAULT)

React to changes

self.settings.connect("changed::dark-mode", self.on_dark_changed)

For schema XML format and installation, see gtk-patterns-reference.md .

Debugging (Quick Reference)

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

For full debugging patterns, profiling, and GDB integration, see gtk-debugging-reference.md .

Red Flags - STOP

  • Calling UI methods from threads (use GLib.idle_add )

  • Missing do_startup chain-up

  • Signal handlers without disconnect on destroy

  • Blocking operations in signal handlers

  • Hardcoded paths instead of XDG directories

  • Missing application ID or wrong format

  • Using time.sleep() in main thread

  • Using GtkShortcutsWindow (deprecated - use AdwShortcutsDialog )

  • Using GtkSpinner for libadwaita apps (use AdwSpinner )

Reference Files

Need File

GObject classes, properties, signals, list models, property bindings, factories gtk-gobject-reference.md

Actions, GSettings, Resources, Blueprint, async file ops gtk-patterns-reference.md

Desktop file, AppStream metadata, Meson, Flatpak, icons, Python deps gtk-packaging-reference.md

Testing with pytest, async testing, headless/CI testing gtk-testing-reference.md

Internationalization, gettext, ngettext plurals, .po files, Blueprint i18n, RTL testing gtk-i18n-reference.md

DBus activation, interface export, background services, Flatpak portals gtk-dbus-reference.md

GTK Inspector, env vars, profiling, memory debugging gtk-debugging-reference.md

UI patterns, widgets, HIG Use designing-gnome-ui skill

External References

  • Blueprint docs

  • Libadwaita API

  • GTK 4 API

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

using-typescript-lsp

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

building-cli-apps

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

using-python-lsp

No summary provided by upstream source.

Repository SourceNeeds Review
General

dotnet-10-csharp-14

No summary provided by upstream source.

Repository SourceNeeds Review