This machine runs a custom stack: elementary OS 9 Early Access on Ubuntu 26.04 "resolute", Asahi
kernels, a patched Gala, a private libmutter, and a growing Rust layer. Every piece below comes from
an upstream we must pull from to stay current. Keep this file updated whenever a pin moves.
Background: RUST-IN-THE-STACK.md (what is Rust today and why) and
PANTHEON-CRASH-2026-10-18.md (why we patch mutter).
- Stay on upstream Vala for Pantheon apps. Gala, Wingpanel, Dock and Granite stay upstream Vala code.
No Vala-to-Rust translator exists; writing one would mean maintaining a compiler, and generated Rust
would mirror GObject's shared mutable references inside
unsafe, losing Rust's benefit. - New code in Rust, talking to Vala libraries through GObject Introspection (GIR). Vala libraries can export GIR; gtk-rs generates safe Rust bindings from it.
- Rewrite in Rust only with evidence (a crash, a measured cost). The compositor qualifies (mutter is C
and crashed); see
codex/rust-mutter-pantheon.
| Component | Upstream | Pinned / installed | Our changes | Where |
|---|---|---|---|---|
| mutter (libmutter) | Ubuntu source mutter on Launchpad; GNOME mutter |
Ubuntu 50.1-0ubuntu2.4 |
Upstream commit c18af474 (null surface in cursor path), private libmutter-18.so.0 for the patched Gala only |
install-gala-mutter-fix.sh, patches/mutter-surface-actor-null-cursor.patch, test-gala-mutter-fix.sh |
| Gala | elementary/gala | f0791434ac40a50f2aec64700a47b3bb04145752 (gala 8.6.2+r3174) |
Screen/window corners, panel offset (protocol v2), dock work area, screenshot patches | install-gala-screen-corners.sh, patches/gala-*.patch |
| Wingpanel | elementary/wingpanel | Installed io.elementary.wingpanel 8.0.4+r814 (elementary daily); patch made against e737de88bc02 |
Export Wingpanel-9.gir + typelib (not installed yet) |
patches/wingpanel-export-gir.patch |
| Granite | elementary/granite | libgranite-7 7.8.1 (ships Granite-7.0.gir) |
None | system package |
| granite-rs | davidmhewitt/granite-rs (crates.io granite-rs, granite-rs-sys) |
granite-rs 3.3.0, granite-rs-sys 0.9.0 |
None; consumers must enable gtk4 v4_10+ (see below) |
rust/granite-smoke, rust/mseries-updates (Software Updates app) |
| gtk4-rs / glib | gtk-rs/gtk4-rs, gtk-rs/gtk-rs-core | gtk4 0.11.5 (feature v4_20), glib 0.22.10; system GTK 4.22.4 |
None | rust/Cargo.lock |
| pangocairo, rayon, libc crates | gtk-rs-core (pangocairo 0.22, same release train as glib/gtk4), rayon, libc |
rust/Cargo.lock |
None | rust/mseries-diskspace (Disk Space app); keep pangocairo on the same minor as glib/pango when bumping gtk-rs |
| Smithay | Smithay/smithay (smallvil example as base) |
023b78b1c5a05ca512767cacc07efca55fae8be4 |
Pantheon desktop-shell v2 in a nested compositor | rust/pantheon-compositor on codex/rust-mutter-pantheon (Codex) |
| Pantheon desktop-shell protocol | XML from elementary/gala f0791434 |
v2 with our set_offset |
set_offset extension |
gala-panel-offset.patch; copy in the compositor branch |
| Vala | GNOME/vala | system valac |
None | n/a |
Upstream Rust branches checked 2026-10-18: none in GNOME/vala, GNOME/mutter (only wip/nielsdg/uncrustify,
a C formatter), elementary/gala, granite, wingpanel or dock.
The mseries-gala launcher stops using the private libmutter as soon as the system libmutter-18-0
version changes (it logs patched libmutter is for …). Then:
- Check whether Ubuntu's new version already contains
c18af474: search the Launchpad changelog for "Handle destroyed surfaces when updating cursor" or checksrc/compositor/meta-surface-actor-wayland.cfor theif (surface)guard. If it does, runbash mseries/install-gala-mutter-fix.sh --uninstalland drop the patch. - Otherwise run
bash mseries/install-gala-mutter-fix.sh(downloads the matching Ubuntu source, verifies the.dscchecksums, applies the patch, builds withdebian/rulesflags), thenbash mseries/test-gala-mutter-fix.sh. - If Ubuntu adds build dependencies, the meson step fails with the missing program; add it to
need=().
install-gala-screen-corners.sh pins commit=. To move: pick the elementary/gala commit matching the
installed gala package, update commit=, re-apply each patches/gala-*.patch (git apply --check first),
rebuild, run window-snapping/test-nested.sh and test-gala-mutter-fix.sh. Pantheon must be logged out and
in to pick it up.
- Clone elementary/wingpanel at the commit matching the installed
io.elementary.wingpanel(elementary dailyrNNNnumbers do not equalgit rev-list --count; match by date or ask the packaging repo). git apply mseries/patches/wingpanel-export-gir.patch,meson setup build,ninja -C build lib/Wingpanel-9.typelib.- Check:
GI_TYPELIB_PATH=build/lib LD_LIBRARY_PATH=build/lib python3 -c "import gi; gi.require_version('Wingpanel','9'); from gi.repository import Wingpanel". Verified 2026-10-18: GIR hasIndicator,KeybindingHelper,PopoverMenuItem; typelib loads. - Not yet installed system-wide or proposed upstream. Proposing it upstream is an outward action: owner decides. With it upstream, Rust indicators need no fork.
granite-rs 3.3does not turn on any gtk4 version feature, butgtk4-rs 0.11putsgtk::Accessiblebehindv4_10. Every crate using granite-rs here must setgtk4 = { version = "0.11", features = ["v4_20"] }and granite-rs features["v7_8", "gtk_v4_20"], or granite-rs fails withcannot find type Accessible in crate gtk. Worth reporting upstream (owner decides).granite::prelude::*together withgtk::prelude::*makesBox::appendambiguous; import the specific Granite traits instead (for examplegranite::prelude::PlaceholderExt).- To update (the crate now lives in
techmore/mseries-sdk-apps,rust/granite-smoke): bump versions in itsCargo.toml,cargo update, thenCARGO_TARGET_DIR=<scratch> cargo build -p granite-smokeand run it underdbus-run-session -- env -u WAYLAND_DISPLAY GDK_BACKEND=x11 GSETTINGS_BACKEND=memory xvfb-run -a <scratch>/debug/granite-smoke. ExpectPASS: Granite widgets built from Rust …. Match granite-rsv7_Nto the installed Granite minor version.
Owned by Codex on codex/rust-mutter-pantheon; its README keeps the pin and says to review any Smithay upgrade
explicitly. Do not commit to that branch from another agent.
rust/target/(build output, about 377 files) is committed on main. Build withCARGO_TARGET_DIRoutside the repo so those files do not churn; removing them from git is a separate cleanup.- Packages installed on the owner's machine for the mutter build (2026-10-18):
libei-dev libsysprof-6-dev sysprof libcanberra-gtk3-dev libpam0g-dev libumockdev-dev python3-argcomplete python3-docutils patchelf.
Nested and headless runs only prove pieces. To test the whole thing, the Rust compositor needs its own
opt-in login session: a /usr/share/wayland-sessions/pantheon-rust.desktop entry next to Pantheon and
Ubuntu in the LightDM session menu. It would start the compositor on DRM/KMS, then the unmodified Vala
Wingpanel, Dock and settings daemon. Rules for that step:
- Never the default or autologin session; Pantheon (
pantheon-wayland) stays the default and rollback. - A failure must return to the greeter, not a black screen (same
OnFailureidea as Gala's unit). - Prerequisites from the compositor branch: DRM/KMS backend, libinput, output configuration, lock screen.
- Acceptance follows
pantheon-rust-compositor/EXPERIENCE-REQUIREMENTS.md(login, apps, panel/dock, monitor changes, snapping, lock/unlock, crash recovery) on the M1 Pro, with the owner present. - Consumers:
rust/granite-smoke(compile check) andrust/mseries-updates(updates-app: header labels, placeholder with an action button, toast). Both carry the samegtk4 v4_20/ granite-rsv7_8, gtk_v4_20feature lines; update them together. Ubuntu 26.04's ownlibgranite-7-devis 7.8.0, which is enough forv7_8, so CI needs no PPA for it. - granite-rs 3.3 surprises met while writing the app:
granite::HeaderLabelhas noset_label(set thelabelproperty);PlaceholderExt::append_buttontakes agio::Icon(not agtk::Image) and returns thegtk::Button(it has noaction-activatedsignal binding); agtk::Expander's collapsed child is not reachable by walkingfirst_child(), so tests expand it first. - Dark scheme in a test: Granite's stylesheet follows
gtk-application-prefer-dark-theme(deprecated since GTK 4.20 but still honoured);gtk-interface-color-schemedid not switch it on 4.22.4.