Linux (GTK 4)
Tier 2 · Demi-supportedlinux-gtk is a Tier 2 desktop target using GTK 4 and libadwaita. It provides a GTK interface
for the app code you share with other systems. Install the development libraries required by
your distribution and check the backend’s accessibility limitations before choosing it.
Getting started
GTK 4.10+, libadwaita 1.5+, and librsvg 2.52+ development files are required (Ubuntu 24.04 and Fedora 40 satisfy these):
sudo apt install libgtk-4-dev libadwaita-1-dev librsvg2-dev pkg-config # Debian/Ubuntu
sudo dnf install gtk4-devel libadwaita-devel librsvg2-devel pkgconf # Fedora
cargo install --git https://github.com/daybrite/day day-cli
day new app my-app --toolkit linux-gtk
cd my-app
day launch -t linux-gtk
Add libwebkitgtk-6.0-dev if you use the web view piece. Sound effects play through libpulse,
which a desktop already has (system requirements). day doctor --toolkit gtk probes
GTK 4, libadwaita, librsvg, glib-compile-resources, and the packaging tools (flatpak-builder,
linuxdeploy, linuxdeploy-plugin-gtk); it does not check WebKitGTK.
day pack -t linux-gtk # single-file .flatpak AND a portable .appimage
day pack produces both formats by default. The flatpak runtime supplies GTK itself
(org.gnome.Platform), so that bundle carries only your app and its assets; A user installs it with
flatpak install ./my-app-1.0-linux-gtk-x86_64.flatpak. The AppImage carries its own GTK, so a user
marks it executable and runs it.
Caveats
- libadwaita is required. The window, navigation, tabs, dialogs and animations are all Adwaita types; a plain-GTK build is not a supported configuration.
GtkVideoneeds a GStreamer media backend in the GTK build. Distro packages ship one; Homebrew’s gtk4 does not, so the media piece shows GTK’s own “no media backend” error onmacos-gtk.- Lottie and map have no GTK arm; each renders its placeholder.
cover()presents as a topmost window-sized child (no transition, programmatic dismissal only). - The combo box uses
GtkComboBoxText, deprecated in GTK 4.10 but kept because GTK has no editable replacement yet. - A
progressnode picks its widget at realize time:progress(f)becomes aGtkProgressBarandspinner()aGtkSpinner. A node that starts indeterminate will not turn into a bar on a later value change; use separate nodes if you need both. - Canvas text uses cairo’s toy text API, not Pango, so complex-script shaping inside a
canvasis weaker than in alabel. - GTK on macOS and Windows (
macos-gtk,windows-gtk) exists for development convenience only (Tier 4);day packskips them, and the accessibility tree is absent (GTK’s a11y bridge is Linux-only).windows-gtkbuilds against MSYS2’s GTK 4 with a GNU Rust toolchain (setup); there is no WebKitGTK 6 for Windows, so the web view is a placeholder there, and bundled custom fonts don’t register with Pango.
What each piece becomes
The generated coverage matrix, checked in CI, covers every backend; this table adds links and notes.
| Day piece | GTK widget |
|---|---|
column / row / nav_stack / section | GtkFixed (Day owns layout) |
label | GtkLabel |
button | GtkButton |
toggle | GtkSwitch |
slider | GtkScale |
text_field | GtkEntry |
secure_field | GtkEntry with visibility off |
text_area | GtkTextView in a GtkScrolledWindow |
picker().menu() | GtkDropDown |
picker().segmented() | linked GtkToggleButtons |
picker().inline() | grouped GtkCheckButtons (GTK 4’s radio) |
progress(f) | GtkProgressBar |
spinner() | GtkSpinner |
divider | GtkSeparator |
scroll | GtkScrolledWindow |
list | GtkListView (recycling, signal factory) |
nav (split) | GtkPaned |
nav (stack) | AdwNavigationView |
nav_menu | GtkListBox (.navigation-sidebar) |
tabs | AdwViewStack + linked toggle buttons |
image | GtkPicture |
vector | GtkPicture showing the raster cache PNG (.tint recolors the pixels) |
cover() | emulated: a topmost window-sized child (no transition, programmatic dismissal only) |
canvas | GtkDrawingArea (cairo) |
| dialogs / alerts / prompts | AdwAlertDialog |
| file dialogs | GtkFileDialog |
| menu bar / context menus | GtkPopoverMenuBar / GtkPopoverMenu |
external activity() | GtkSpinner |
external combobox() | GtkComboBoxText (with entry) |
external search_field() | GtkSearchEntry |
external date_picker() | GtkCalendar, in a GtkMenuButton popover when compact |
external time_picker() | linked GtkSpinButtons |
external webview() | WebKitWebView (WebKitGTK 6.0) |
external media() | GtkVideo |
Text measurement builds a Pango layout on the label’s styled context rather than calling
gtk_widget_measure, because a GtkFixed child’s size request would otherwise ratchet upward and
never shrink.