A Field Guide to GTK Widgets

A Field Guide to GTK Widgets

This is the opening post of a series that works through GTK4 and Libadwaita together, one practical interface decision at a time. The posts are grouped around the things you actually build — a window, a list, a settings page — rather than the library a widget happens to ship in. Each post stands alone; together they’re meant to be the field guide the reference documentation isn’t. The problem with the reference The GTK4 documentation is genuinely good. Every widget has a page. Every property, signal, and method is listed. The class hierarchies are accurate and the prose is precise. If you already know which widget you need, the reference will tell you everything about it. ...

June 5, 2026 · 9 min · Justin
The Application Shell: GtkApplicationWindow vs AdwApplicationWindow

The Application Shell: GtkApplicationWindow vs AdwApplicationWindow

This is the first proper entry in A Field Guide to GTK Widgets — a series about which widget to reach for, when, and what bites you when you do. We start where every app starts: the window. Each post stands on its own, and the complete, runnable code for this one lives in the companion repo. Two windows, and the one you should reach for You sit down to write a GNOME app. The very first widget you need is the window, and the toolkit immediately hands you a choice it doesn’t explain: GtkApplicationWindow, from GTK itself, or AdwApplicationWindow, from Libadwaita. The reference describes both accurately and tells you nothing about which one you want. ...

June 12, 2026 · 9 min · Justin
Stop Thinking in Rows: GListModel and the Modern List Mindset

Stop Thinking in Rows: GListModel and the Modern List Mindset

This is the third entry in A Field Guide to GTK Widgets — a series about which widget to reach for, when, and what bites you when you do. We’re jumping straight to lists, ahead of layout and navigation, because it’s the material the reference documents worst. Each post stands on its own, and the complete, runnable code for this one lives in the companion repo. The list you’d build without thinking Say you’re showing a handful of tasks. The obvious way to do it doesn’t require reading any documentation at all: ...

August 11, 2026 · 10 min · Justin
Your First Factory: GtkListView and the Bind/Unbind Rhythm

Your First Factory: GtkListView and the Bind/Unbind Rhythm

This is the fourth entry in A Field Guide to GTK Widgets — a series about which widget to reach for, when, and what bites you when you do. The previous post got a list on screen with a factory it deliberately didn’t explain. This one explains it. The complete, runnable code lives in the companion repo. Where we left off The list-mindset post got a GtkListView on screen with just enough factory code to prove the model-driven approach worked, and it said so directly: setup builds a row’s widgets once, bind fills them in, and GTK recycles rows as you scroll — the same widgets get re-bound to different items instead of new rows being built for each one. That recycling is the entire reason GtkListView scrolls well through ten thousand rows without breaking a sweat, and it’s also the thing that breaks people’s mental model the first time they hit it, because nothing in the API shouts about it. You write bind once, it looks like a constructor, and it isn’t one. ...

August 18, 2026 · 8 min · Justin
Selection, Modelled: Why GTK4 Puts Selection in the Model, Not the View

Selection, Modelled: Why GTK4 Puts Selection in the Model, Not the View

This is the fifth entry in A Field Guide to GTK Widgets — a series about which widget to reach for, when, and what bites you when you do. The previous post got rows behaving correctly under recycling. This one is about which of them is selected. The complete, runnable code lives in the companion repo. Where we left off Two posts ago I wrapped the list store in a NoSelection and moved on, with a note that GtkListView won’t accept a bare GListModel and that NoSelection is how you say “no selection, and I mean it.” True enough as far as it went, but it was a placeholder. Time to take the wrapper seriously. ...

August 25, 2026 · 10 min · Justin