atagen

monolith

public
Star0
Watch0

Commit 14c8fedad3a3

tarball

atagen <boss@atagen.co>2026-10-16 22:31 UTC

5 files changed+43-1
monolith: export the session for portals and display managers

xdg-desktop-portal only routes screenshots and screencasts to the wlr backend when XDG_CURRENT_DESKTOP names a desktop with a portals.conf, and its D-Bus activated services never see the compositor's environment otherwise. Only bare-metal sessions export, so a nested monolith leaves its host's activation environment alone.
Modified file: crates/monolith/src/commands.rs+4 additions
@@ -173,6 +173,10 @@ impl State {
173173 if let Some(sock) = &self.ipc.path {
174174 cmd.env("MONOLITH_SOCKET", sock);
175175 }
176+ if self.drm.is_some() {
177+ cmd.env("XDG_CURRENT_DESKTOP", "monolith")
178+ .env("XDG_SESSION_TYPE", "wayland");
179+ }
176180 let token = self.launch_token();
177181 cmd.env("XDG_ACTIVATION_TOKEN", &token)
178182 .env("DESKTOP_STARTUP_ID", &token);
Modified file: crates/monolith/src/main.rs+24 additions
@@ -129,6 +129,27 @@ fn main() -> ExitCode {
129129 }
130130 }
131131
132+/// Hands the session's variables to D-Bus and systemd activated services,
133+/// which portals need to find the compositor and pick monolith-portals.conf.
134+fn export_session(state: &State) {
135+ let result = std::process::Command::new("dbus-update-activation-environment")
136+ .arg("--systemd")
137+ .arg(format!(
138+ "WAYLAND_DISPLAY={}",
139+ state.socket_name.to_string_lossy()
140+ ))
141+ .arg("XDG_CURRENT_DESKTOP=monolith")
142+ .arg("XDG_SESSION_TYPE=wayland")
143+ .stdin(std::process::Stdio::null())
144+ .spawn();
145+ match result {
146+ Ok(mut child) => {
147+ std::thread::spawn(move || child.wait());
148+ }
149+ Err(e) => tracing::warn!("cannot export the session to D-Bus: {e}"),
150+ }
151+}
152+
132153 fn run(
133154 config: Option<PathBuf>,
134155 backend: Backend,
@@ -153,6 +174,9 @@ fn run(
153174 ipc::init(&event_loop, &mut state)?;
154175 tracing::info!(socket = ?state.socket_name, device = state.renderer.device_name(), "monolith running");
155176
177+ if gpu.is_some() {
178+ export_session(&state);
179+ }
156180 let mut startup = state.config.startup.clone();
157181 if !program.is_empty() {
158182 startup.push(program.to_vec());
Modified file: flake.nix+5 additions−1 deletions
@@ -24,7 +24,7 @@
2424 craneLib = crane.mkLib pkgs;
2525 src = lib.cleanSourceWith {
2626 src = ./.;
27- filter = path: type: (craneLib.filterCargoSources path type) || lib.hasInfix "/shaders" path;
27+ filter = path: type: (craneLib.filterCargoSources path type) || lib.hasInfix "/shaders" path || lib.hasInfix "/res" path;
2828 name = "source";
2929 };
3030 lavapipeIcd = "${pkgs.mesa}/share/vulkan/icd.d/lvp_icd.${pkgs.stdenv.hostPlatform.parsed.cpu.name}.json";
@@ -57,6 +57,10 @@
5757 // {
5858 inherit cargoArtifacts;
5959 doCheck = false;
60+ postInstall = ''
61+ install -Dm644 res/monolith-portals.conf -t $out/share/xdg-desktop-portal
62+ install -Dm644 res/monolith.desktop -t $out/share/wayland-sessions
63+ '';
6064 }
6165 );
6266
Added file: res/monolith-portals.conf+4 additions
@@ -0,0 +1,4 @@
1+[preferred]
2+default=gtk
3+org.freedesktop.impl.portal.Screenshot=wlr
4+org.freedesktop.impl.portal.ScreenCast=wlr
Added file: res/monolith.desktop+6 additions
@@ -0,0 +1,6 @@
1+[Desktop Entry]
2+Name=monolith
3+Comment=A tiling Wayland compositor
4+Exec=monolith run
5+Type=Application
6+DesktopNames=monolith