A GTK4 GUI for univ, inspired by the
Bazaar. It talks to
univ the same way the built-in TUI does — by shelling out to the binary —
so the store stays the single source of truth.
The UI is written against libadapta (the theme-aware libadwaita soft fork) via
its adw-compat.h header, so the code uses the familiar Adw* names and would
also compile against plain libadwaita unchanged.
| View | What it does |
|---|---|
| Home | a large auto-scrolling banner of five random featured packages plus buttons for every configured repository |
| Installed | list installed packages, filter them, view details, reinstall or uninstall |
| Browse | search the deb/rpm repo indexes and install results |
| Log | live output of every univ operation |
The header bar has a refresh button, an upgrade-all button, and a spinner while anything is running. Package installs/uninstalls stream their output into the Log and pop a toast when done.
The only hard dependency is a C++17 compiler, meson/ninja, and a GTK4 + libadapta stack. On any Ublue machine those come from Homebrew:
brew install meson ninja gtk4 glib graphene fribidi appstream json-glib sassc gettext
export PATH="/home/linuxbrew/.linuxbrew/opt/gettext/bin:$PATH"
export PKG_CONFIG_PATH="/home/linuxbrew/.linuxbrew/lib/pkgconfig:/home/linuxbrew/.linuxbrew/share/pkgconfig:/home/linuxbrew/.linuxbrew/opt/xorgproto/share/pkgconfig"
meson setup _build \
-Dlibadapta:examples=false \
-Dlibadapta:tests=false \
-Dlibadapta:vapi=false \
-Dlibadapta:introspection=disabled \
-Dlibadapta:gtk_doc=false
ninja -C _buildNotes:
- Leave
LD_LIBRARY_PATHunset while building. Pointing it at/home/linuxbrew/.linuxbrew/libmakes/usr/bin/gitload brew's libcurl, which breaks GitHub TLS when meson clones subprojects (unable to get local issuer certificate (20)). - The
xorgprotodirectory inPKG_CONFIG_PATHis required — without it meson cannot find the X protocol headers (xproto,kbproto,xextproto, ...) that GTK4's pkg-config metadata expects, and it falls back to building gtk/pango/cairo from source. sasscis needed to build libadapta's stylesheet.
libadapta is pulled in automatically as a meson subproject
(subprojects/libadapta.wrap), pinned to the latest 1.5.x revision. If it is
ever installed system-wide instead, meson picks it up via pkg-config and skips
the subproject.
env LD_LIBRARY_PATH=/home/linuxbrew/.linuxbrew/lib ./_build/catalogLD_LIBRARY_PATH is required at runtime so the binary finds brew's GTK4.
univ is resolved from $UNIV_BIN if set, otherwise from PATH.
The app bundles the Adwaita symbolic icons it uses (from
adwaita-icon-theme,
LGPL-3.0-or-later) as GResources, so the header bar, view switcher and package
rows look right even on desktops whose icon theme lacks the GTK icon names
(KDE/Breeze misses e.g. software-update-available-symbolic and
view-list-symbolic, which is what made them render as fallback blobs).
The gear button in the header bar picks the icon style:
- GNOME (Adwaita) (default) — force the Adwaita icon theme
- KDE (Breeze) — use KDE's Breeze icons, with the bundled set filling the gaps
- Follow system — use whatever icon theme the desktop has set
The choice is persisted in ~/.config/catalog/config.ini
([ui] icon-style = gnome|kde|system).
Wayland-first: the app is a native Wayland client. GTK4 selects the Wayland
backend automatically and falls back to X11 only if no Wayland compositor is
available; this has been verified to open on GdkWaylandDisplay.
Dependencies: meson, ninja, GTK 4 (gtk4), json-glib. libadapta is
vendored as a meson subproject and builds with introspection disabled, so no
gobject-introspection is required.
Per-user install (installs to ~/.local):
meson setup _build --prefix "$HOME/.local"
ninja -C _build
meson install -C _buildSystem-wide install (requires root):
meson setup _build --prefix /usr --libdir lib
ninja -C _build
sudo meson install -C _buildInstalled files:
bin/catalog— the applicationshare/applications/io.univ.Catalog.desktop— launcher entry (app idio.univ.Catalog, iconcatalog)share/icons/hicolor/{16..512}x{16..512}/apps/catalog.png— app icon (the coupon logo fromimages/Coupon.png)- the libadapta fallback subproject installs its own lib/theme/locale files
The desktop entry and icon are picked up by both GNOME and KDE; after a
system-wide install run gtk-update-icon-cache -f /usr/share/icons/hicolor.
A per-user install needs ~/.local/bin on $PATH for the Exec=catalog line
to resolve.
| File | Responsibility |
|---|---|
src/main.cpp |
entry point, AdwApplication setup |
src/app.cpp |
window, three views, package list/details widgets, actions |
src/model.cpp |
Package struct + json-glib parsing of univ JSON output |
src/univ.cpp |
univ discovery, async queries, streaming install/uninstall tasks |
meson.build |
build glue, links libadapta subproject + json-glib |
- package icons (deb control / rpm header metadata or generic by-kind icons)
- per-repository view and repo management
- dependencies graph / reverse-dependencies in the detail pane
- profile management (
univ profile ...) from the GUI - transaction rollback status surfacing from the Log