control center integration
Goal: make finupdate appear as a page inside gnome-control-center (GNOME
Settings) on existing installations, not as a separate window.
What we foundβ
On stock gnome-control-center 50.1 (the version Dakota ships):
- Panels are statically linked into the
gnome-control-centerbinary β there are nolib*-panel.sofiles anywhere on disk under/usr/lib*/gnome-control-center-1/panels/. The directory itself doesn't exist on this install. cc_panel_loader_load_by_nameis satisfied from a baked-in registry. The symbolcc_panel_loader_override_vtableexists but is internal β used by CC's own swappable-panel infrastructure, not exposed as a plugin point.gnome-control-center --listenumerates a closed set of ~23 panels:applications, background, bluetooth, color, display, keyboard, mouse, multitasking, network, wifi, notifications, online-accounts, power, printers, privacy, search, sharing, sound, system, universal-access, wacom, wellbeing, wwan. There's noupdatesslot.- The
.desktop-file route (X-GNOME-Settings-Panelcategory) gives you a launcher tile in the All Settings sidebar, but the click runsExec=in a separate process β it doesn't embed.
Conclusion: there is no upstream extension point for adding a panel to an existing gnome-control-center installation today. Every path below involves either patching the OS package or giving up on the "embedded inside Settings window" requirement.
Realistic paths, ordered by deployment difficultyβ
Path 1 β Distro-patched gnome-control-center (Bluefin/Dakota only)β
Bluefin/Dakota controls the image, so we can carry a downstream patch that
adds an updates panel to gnome-control-center and rebuilds it.
What we'd ship:
- A
cc-updates-panel.cpanel implementingCcPanel(the standard GObject/AdwBin interface every CC panel uses), registered in the panel loader. - The panel's UI widgets call into
libfinupdate.so, a Rust cdylib we'd produce from the existing crate viacrate-type = ["cdylib"]and a thin C header generated bycbindgen. - A patched
gnome-control-center.spec(or rpm-ostree layer) that links the new panel in.
Pros: true in-window embedding, the user's actual goal. Works the same way every other panel does. Cons: only works on Bluefin/Dakota images. Every gnome-control-center upstream release requires a rebase of the patch. Distributing the Rust backend as a cdylib needs a stable C ABI surface β we don't have one yet.
Effort: ~1β2 weeks. The C panel is small (~500 lines) but the cdylib boundary needs careful design.
Path 2 β Upstream a "Software Updates" panel into gnome-control-centerβ
The right long-term answer. Write the panel in C (matching the rest of gnome-control-center), submit it upstream, and once it lands every distribution that ships gnome-control-center gets it for free.
Reality check: GNOME has historically rejected an "updates" panel because the GNOME Software application owns that surface. There's been discussion (cc#1640, software#1234-ish) but no consensus. A bootc-centric panel might land more easily because it's about bootable container image management, not generic package updates β that's a niche gnome-software doesn't cover.
Effort: indefinite. Months of design discussion before any code is acceptable.
Path 3 β .desktop-file launcher tile in Settingsβ
Ship org.tunaos.finupdate.desktop with
Categories=GNOME;GTK;Settings;X-GNOME-Settings-Panel; and a
Keywords=update;upgrade;bootc;rebase;... line so it surfaces in the
"All Settings" sidebar and the Settings search bar. Clicking it launches
finupdate as a separate window.
Pros: zero patching, works on every GNOME install. Immediate deployability via Flatpak or RPM. Cons: not actually embedded. The user sees a Settings tile that opens a separate window β which is what most third-party "settings" apps do (GNOME Tweaks, GNOME Disks, etc.).
Effort: ~1 hour. Just metadata.
Path 4 β Custom-styled standalone that mimics gnome-control-centerβ
Make finupdate's main window look and behave like a CC panel: same sidebar/content split, same widget styling, same window chrome. Launch it from a Settings tile (Path 3). The user "feels" like they're in Settings even though it's a separate window.
Pros: under our control, no distro patching, no upstream politics. The UI is already close to this β adw::PreferencesPage gives us the CC look for free. Cons: doesn't satisfy the literal "page inside Settings" goal.
Effort: mostly already done; a few CSS tweaks plus the desktop file.
Recommended sequenceβ
If the goal is "Dakota users see this in their Settings as soon as possible":
- Path 3 now β ship the
.desktoptile so finupdate is at least discoverable from Settings. ~1 hour. - Path 1 in parallel β start the cdylib + C panel work so Dakota can roll out true embedding in a future image build. ~2 weeks.
- Path 2 eventually β once the Dakota patch is stable, propose it upstream. Time horizon: 6+ months.
Prep work that helps all pathsβ
Regardless of which path lands first, these changes make the panel embedding easier:
-
Factor the idle-page widget tree (
src/ui/status_view.rs'sidle_page: adw::PreferencesPage) into a reusableWidgetbuilder that's not coupled to the top-leveladw::ApplicationWindow. Path 1 needs to be able to drop this widget into aCcPanel's content area; Path 4 doesn't, but it's clean code anyway. -
Decouple the Settings/state model from the GTK loop: the
Settings::load()/BOOTC_STATUS_CACHEpatterns assume a single process. If the panel is loaded into gnome-control-center's process we share that loop with everyone else; no spawning runtime-in-runtime panics. -
Define a stable C-ABI surface for the backend. Today the service layer (
crate::service::global()) is async Rust. Path 1 needs a blocking, GMainLoop-friendly subset:finupdate_init() -> *Servicefinupdate_check_for_updates(svc, cb, user_data)finupdate_apply_update(svc, cb, user_data)finupdate_free(svc)
Each long-running call takes a callback and dispatches the result on the main loop via
g_idle_addso the CC main loop doesn't block.
Open questionsβ
- Which Dakota release should the patched gnome-control-center ship in? Coordinating with the image build pipeline is a separate workstream.
- What's the panel's identity inside CC? "Software Updates"? "System Image"? "Bootc"? The label drives discoverability via Settings search.
- Where does it slot in the sidebar? Probably between System and About, or as a sub-section of System itself.
- Does the panel show on non-bootc systems? If shipped upstream, it
needs a graceful no-op (or hidden state) when
/usr/bin/bootcis absent.