diff --git a/Justfile b/Justfile index 7f8458f..4f097aa 100644 --- a/Justfile +++ b/Justfile @@ -10,6 +10,7 @@ debug_args := if debug == '1' { '' } else { '--release' } cargo_args := vendor_args + ' ' + debug_args bindir := prefix + '/bin' +systemddir := prefix + '/lib/systemd/user' sessiondir := prefix + '/share/wayland-sessions' all: _extract_vendor @@ -23,6 +24,12 @@ install: # session desktop file install -Dm0644 data/cosmic.desktop {{sessiondir}}/cosmic.desktop + # session start script + install -Dm0755 data/start-cosmic {{bindir}}/start-cosmic + + # systemd target + install -Dm0644 data/cosmic-session.target {{systemddir}}/cosmic-session.target + clean_vendor: rm -rf vendor vendor.tar .cargo/config diff --git a/data/cosmic-session.target b/data/cosmic-session.target new file mode 100644 index 0000000..978aa8e --- /dev/null +++ b/data/cosmic-session.target @@ -0,0 +1,5 @@ +[Unit] +Description=Cosmic Session Target +Documentation=man:systemd.special(7) +BindsTo=graphical-session.target +Before=graphical-session.target diff --git a/data/cosmic.desktop b/data/cosmic.desktop index 1e271af..6b8e0f2 100644 --- a/data/cosmic.desktop +++ b/data/cosmic.desktop @@ -1,7 +1,7 @@ [Desktop Entry] Name=COSMIC Comment=This session logs you into the COSMIC desktop -Exec=/usr/bin/dbus-run-session -- /usr/bin/cosmic-session -TryExec=/usr/bin/cosmic-session +Exec=/usr/bin/start-cosmic +TryExec=/usr/bin/start-cosmic Type=Application DesktopNames=pop:COSMIC diff --git a/data/start-cosmic b/data/start-cosmic new file mode 100755 index 0000000..a4ed56e --- /dev/null +++ b/data/start-cosmic @@ -0,0 +1,28 @@ +#!/bin/bash + +# From: https://people.debian.org/~mpitt/systemd.conf-2016-graphical-session.pdf + +# robustness: if the previous graphical session left some failed units, +# reset them so that they don't break this startup +for unit in $(systemctl --user --no-legend --state=failed --plain list-units | cut -f1 -d' '); do + partof="$(systemctl --user show -p PartOf --value "$unit")" + for target in cosmic-session.target graphical-session.target; do + if [ "$partof" = "$target" ]; then + systemctl --user reset-failed "$unit" + break + fi + done +done + +# /etc/profile contains a lot of important environment variables +source /etc/profile + +export XDG_CURRENT_DESKTOP="${XDG_CURRENT_DESKTOP:=pop:COSMIC}" +export XDG_SESSION_TYPE="${XDG_SESSION_TYPE:=wayland}" +export XCURSOR_THEME="${XCURSOR_THEME:=Adwaita}" + +# import environment variables from the login manager +systemctl --user import-environment XDG_SESSION_TYPE XDG_CURRENT_DESKTOP + +# Run cosmic-session +exec /usr/bin/dbus-run-session -- /usr/bin/cosmic-session diff --git a/src/main.rs b/src/main.rs index 40a93a3..2225cce 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ extern crate tracing; mod comp; mod generic; mod process; +mod systemd; use async_signals::Signals; use color_eyre::{eyre::WrapErr, Result}; @@ -37,6 +38,9 @@ async fn main() -> Result<()> { if let Err(err) = comp::run_compositor(token.child_token(), socket_rx, env_tx) { error!("compositor errored: {:?}", err); } + systemd::start_systemd_target() + .await + .wrap_err("failed to start systemd target")?; let env_vars = env_rx .await .expect("failed to receive environmental variables") diff --git a/src/systemd.rs b/src/systemd.rs new file mode 100644 index 0000000..715eef4 --- /dev/null +++ b/src/systemd.rs @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-3.0-only + +use color_eyre::{ + eyre::{eyre, WrapErr}, + Result, +}; +use tokio::process::Command; + +pub async fn start_systemd_target() -> Result<()> { + let output = Command::new("systemctl") + .arg("--user") + .arg("start") + .arg("cosmic-session.target") + .spawn() + .wrap_err("failed to start systemd target")? + .wait() + .await + .wrap_err("failed to wait for systemd target to start")?; + + if output.success() { + Ok(()) + } else { + Err(eyre!( + "failed to start systemd target: code {}", + output.code().unwrap_or(-1), + )) + } +}