diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index e6ca28b..63abe52 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,8 +1,10 @@ -- [ ] I have disclosed use of any AI generated code in my commit messages. - - If you are using an LLM, and do not fully understand the changes it is making to the code base, do not create a PR. - - In our experience, AI generated code often results in overly complex code that lacks enough context for a proper fix or feature inclusion. This results in considerably longer code reviews. Due to this, AI authored or partially authored PRs may be closed without comment. -- [ ] I understand these changes in full and will be able to respond to review comments. -- [ ] My change is accurately described in the commit message. -- [ ] My contribution is tested and working as described. -- [ ] I have read the [Developer Certificate of Origin](https://developercertificate.org/) and certify my contribution under its conditions. +Replace this text with a description of your changes, and why these changes are important. Read and acknowledge the list below. PRs without a completed checkbox will be closed. +--- + +- I have not included any LLM (also known as AI) generated content in this PR, including code, comments, and descriptions. +- I understand these changes in full and will be able to respond to review comments. +- My change is accurately described in the commit message. +- My contribution is tested and working as described. +- I have read the [Developer Certificate of Origin](https://developercertificate.org/) and certify my contribution under its conditions. +- [ ] I have read and followed all of the above requirements. For more information, see our [contributor guide](https://github.com/pop-os/pop/blob/master/CONTRIBUTING.md). diff --git a/.github/workflows/require-checklist.yml b/.github/workflows/require-checklist.yml new file mode 100644 index 0000000..fd4ca8c --- /dev/null +++ b/.github/workflows/require-checklist.yml @@ -0,0 +1,14 @@ +# From https://github.com/mheap/require-checklist-action, license MIT +name: Require Checklist + +on: + pull_request: + types: [opened, edited, synchronize] + +jobs: + job1: + runs-on: ubuntu-latest + steps: + - uses: mheap/require-checklist-action@v2 + with: + requireChecklist: true diff --git a/Cargo.lock b/Cargo.lock index c6c101b..f7710a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -113,13 +113,13 @@ dependencies = [ [[package]] name = "async-recursion" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" +checksum = "4f8abc12baad266b1c8cec146854c195b5864b4221d4b2ca7296a7ae82d9e451" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn 3.0.6", ] [[package]] @@ -154,7 +154,7 @@ checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667" dependencies = [ "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -234,9 +234,9 @@ checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] name = "cc" -version = "1.4.6" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3eb0f42d6c360dc3f8a821f6bf2fdea7f72bfd36b3076eb0e6d1e9e0752fff4" +checksum = "f74872d07caf508b30a21f6836e7d7016a2eaf7d9ff4f48deaa58cd8a0407630" dependencies = [ "find-msvc-tools", "shlex", @@ -244,9 +244,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" [[package]] name = "color-eyre" @@ -293,7 +293,7 @@ dependencies = [ [[package]] name = "cosmic-session" -version = "1.9.0" +version = "1.10.0" dependencies = [ "color-eyre", "cosmic-dbus-a11y", @@ -426,9 +426,9 @@ checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" [[package]] name = "find-msvc-tools" -version = "0.1.12" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e0f1c7c3a72c66fd80abe965175f7523475c0489a87d3ff9d6e8c87d87a9d2d" +checksum = "aedcfb3409746eddb02b9e19ebda1c3394f759a152e48ee875a0844d1b955484" [[package]] name = "freedesktop-desktop-entry" @@ -478,7 +478,7 @@ checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" dependencies = [ "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -506,17 +506,6 @@ dependencies = [ "slab", ] -[[package]] -name = "getrandom" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - [[package]] name = "getrandom" version = "0.3.4" @@ -608,9 +597,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "js-sys" -version = "0.3.105" +version = "0.3.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce57d20d1ea864ce2ac172ab472d409214f4fd359f0b2a2775abdf522e2af99e" +checksum = "7883d941dae510fb2d978fc3fe018c71c9e2892fd38854de3e8b92c2e5ad9cc5" dependencies = [ "cfg-if", "futures-util", @@ -635,21 +624,21 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +checksum = "20870f649af7073d53e38067b2a84312175d56ea15217e1b15bc83506ec50afb" [[package]] name = "libc" -version = "0.2.189" +version = "0.2.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" +checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78" [[package]] name = "libredox" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6480ccc157a1389bb2e4891b24751b0f798ba640d22386f23143fbcc89da195a" +checksum = "61ff90caf6077a803a240f62fdbe88645a890bbca49ef8174c3cb0404362171d" dependencies = [ "libc", ] @@ -752,9 +741,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.3" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b18443e9c262bfe8fa82f51666e2642c53393f7e5c27b3e1aeab922cff5b9d8" +checksum = "1788edb87fdc09c7e26304471e2f5be8cdefb1b6930d6e3985fc02ff53bf86ee" dependencies = [ "libc", "wasi", @@ -984,11 +973,10 @@ dependencies = [ [[package]] name = "redox_users" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" +checksum = "60dc65c0ff1a7ae1294b0c67b9f14baf70b644404010370171787bfac1038fc0" dependencies = [ - "getrandom 0.2.17", "libredox", "thiserror", ] @@ -1030,9 +1018,9 @@ checksum = "b74b56ffa8bb2830709a538c2cbcae9aa062db0d2a42563bfb09bdaae44020eb" [[package]] name = "rustix" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +checksum = "891efababe418670775f199f0d233d84843c227a0949a883ce15b37c78d6629d" dependencies = [ "bitflags", "errno", @@ -1080,7 +1068,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -1104,7 +1092,7 @@ checksum = "8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906" dependencies = [ "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -1155,9 +1143,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.16.1" +version = "1.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba467056f1b547ed52077911161fc86985becbc60e8e1857c8a144dab0def891" +checksum = "f9395f0f0eee849a9b707b2f06bb92a6a422090e2123bb2ef8e87a0e61892a8e" [[package]] name = "socket2" @@ -1182,9 +1170,9 @@ dependencies = [ [[package]] name = "syn" -version = "3.0.5" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" dependencies = [ "proc-macro2", "quote", @@ -1218,22 +1206,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.20" +version = "2.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" +checksum = "09e52cb86a36cede5cb101bf8908837b3e4c6e5e59fe7fd85c23fb56200d189e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.20" +version = "2.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" +checksum = "fe5197923287db20a58125f0bc85c062f7f2c892de97b18c356f9efb14b28524" dependencies = [ "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -1247,9 +1235,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.53.1" +version = "1.53.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" +checksum = "e95f91fcc7a621e8b030f6aa23c71fe9838ae2fb4d8118b75602a328f5144044" dependencies = [ "bytes", "libc", @@ -1271,7 +1259,7 @@ checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" dependencies = [ "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", ] [[package]] @@ -1412,21 +1400,21 @@ dependencies = [ [[package]] name = "unicase" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" +checksum = "357cc3acc6a036009fd6c973ed009037c732d60d0b4f6c673e9041497482a28f" [[package]] name = "unicode-ident" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" [[package]] name = "uuid" -version = "1.26.1" +version = "1.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ef6dac1e96601b4fb3acccccff2139741fcb757cb9a36089bf5be91cfb285ce" +checksum = "97277d36b9c3ace13e58fa6e753f8b0bbbf302a18dd193240d70f9e29681059a" dependencies = [ "js-sys", "serde_core", @@ -1462,9 +1450,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.128" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aecb87a33d3b0c5e3b7aa46336eaf486cffafbd281b195e4c8b80d50df2351bf" +checksum = "9bb54f33acc68fd454578d9820b0bde1a1a3d17aa17bb7b6595806d02886d409" dependencies = [ "cfg-if", "once_cell", @@ -1475,9 +1463,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.128" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a690d511e3c1a8b3a55e33511e3c2c00c78415cd23650f32b808627f5696b9ed" +checksum = "2e29d0c35b16e224a7eeb5cd2d25e3e1968fbd65604117b44d3b789d00ee8535" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1485,22 +1473,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.128" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "411e4887f0071ef2d2164a9d5fdf2d20efbef78fccd3a78b0c10a1dc5295e48a" +checksum = "6f501a8bc3719dba86ef8ae4728879c08001bea749eb1333ac5b91e040e2a6b7" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.128" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81941cd78d0c92026c33e5e01312845a4cb1e9af3407f9134b100dd03144103e" +checksum = "23f0c9c52aa7cd7d77769a4cfe2a9adb1b331f489a41d912ce14513d5ab995c6" dependencies = [ "unicode-ident", ] @@ -1608,7 +1596,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", "zbus_names", "zvariant", "zvariant_utils", @@ -1646,18 +1634,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.57" +version = "0.8.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d35102a9f36d089ccae9e4c6802bc118be4487b80aaffc0ab4e0cf5ce92d2873" +checksum = "6df92bf3d9227be3d53173901ddbffac2babc27ae50f397776ffd6dc33f800cb" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.57" +version = "0.8.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c01f5ab44258da43cf276c74a2763db2ff3969c9c652c3f2de07041d0b2bc" +checksum = "ac4f328cf2f05d084e496c3e9c3f33ed0a183656a16e1fcec4d464d8373aec82" dependencies = [ "proc-macro2", "quote", @@ -1694,7 +1682,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 3.0.5", + "syn 3.0.6", "zvariant_utils", ] @@ -1707,7 +1695,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 3.0.5", + "syn 3.0.6", "winnow", ] diff --git a/Cargo.toml b/Cargo.toml index 8fb9e74..d595f96 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cosmic-session" description = "The session manager for the COSMIC desktop environment" -version = "1.9.0" +version = "1.10.0" license = "GPL-3.0-only" edition = "2024" rust-version = "1.93" @@ -46,6 +46,6 @@ logind-zbus = { version = "5.3.2", optional = true } [features] systemd = ["dep:zbus_systemd", "dep:tracing-journald"] -logind = ["systemd", "logind-zbus"] -default = ["logind"] +logind = ["dep:logind-zbus"] +default = ["logind", "systemd"] autostart = ["dep:shell-words", "dep:dirs", "dep:freedesktop-desktop-entry"] diff --git a/cargo.just b/cargo.just new file mode 100644 index 0000000..fb09e1e --- /dev/null +++ b/cargo.just @@ -0,0 +1,70 @@ +cargo-target-dir := env('CARGO_TARGET_DIR', 'target') + +# Compile with debug profile +[no-cd] +build-debug *args: + cargo build {{args}} + +# Compile with release profile +[no-cd] +build-release *args: (build-debug '--release' args) + +# Compile with a vendored tarball +[no-cd] +build-vendored *args: vendor-extract (build-release '--frozen --offline' args) + +# Check for errors and linter warnings +[no-cd] +check *args: + cargo clippy --all-features {{args}} -- -W clippy::pedantic + +# Runs a check with JSON message format for IDE integration +[no-cd] +check-json: (check '--message-format=json') + +# Remove Cargo build artifacts +[no-cd] +clean: + cargo clean + +# Also remove .cargo and vendored dependencies +[no-cd] +clean-dist: clean + rm -rf .cargo vendor vendor.tar target + +# Run the application for testing purposes +[no-cd] +run *args: + cargo run {{args}} + +# Run `cargo test` +[no-cd] +test *args: + cargo test {{args}} + +# Vendor Cargo dependencies locally +[no-cd] +vendor: + #!/usr/bin/env bash + mkdir -p .cargo + cargo vendor --locked | head -n -1 > .cargo/config.toml + echo 'directory = "vendor"' >> .cargo/config.toml + echo >> .cargo/config.toml + echo '[env]' >> .cargo/config.toml + if [ -n "${SOURCE_DATE_EPOCH}" ] + then + source_date="$(date -d "@${SOURCE_DATE_EPOCH}" "+%Y-%m-%d")" + echo "VERGEN_GIT_COMMIT_DATE = \"${source_date}\"" >> .cargo/config.toml + fi + if [ -n "${SOURCE_GIT_HASH}" ] + then + echo "VERGEN_GIT_SHA = \"${SOURCE_GIT_HASH}\"" >> .cargo/config.toml + fi + tar pcf vendor.tar .cargo vendor + rm -rf .cargo vendor + +# Extracts vendored dependencies +[no-cd] +vendor-extract: + rm -rf vendor + tar pxf vendor.tar diff --git a/data/start-cosmic b/data/start-cosmic index a5f1842..46dec47 100755 --- a/data/start-cosmic +++ b/data/start-cosmic @@ -66,13 +66,14 @@ if [ -d "$XDG_RUNTIME_DIR/keyring" ]; then echo "gnome-keyring-daemon not found in PATH" >&2 fi - # Only set SSH_AUTH_SOCK if the socket actually exists. Either - # set the correct one, or don't set one at all. Don't set the - # wrong value. - if [ -S "$XDG_RUNTIME_DIR/gcr/ssh" ]; then - export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/gcr/ssh" - elif [ -S "$XDG_RUNTIME_DIR/keyring/ssh" ]; then - export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/keyring/ssh" + # Preserve an SSH agent configured by the user. Otherwise, use a + # Gnome Keyring SSH socket if one exists. + if [ -z "$SSH_AUTH_SOCK" ]; then + if [ -S "$XDG_RUNTIME_DIR/gcr/ssh" ]; then + export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/gcr/ssh" + elif [ -S "$XDG_RUNTIME_DIR/keyring/ssh" ]; then + export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/keyring/ssh" + fi fi fi diff --git a/debian/changelog b/debian/changelog index 3201725..d205827 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +cosmic-session (1.10.0) noble; urgency=medium + + * Epoch 1.10.0 version update + + -- Michael Murphy Mon, 05 Oct 2026 21:26:30 +0200 + cosmic-session (1.9.0) noble; urgency=medium * Epoch 1.9.0 version update diff --git a/debian/source/options b/debian/source/options new file mode 100644 index 0000000..2f8c4a1 --- /dev/null +++ b/debian/source/options @@ -0,0 +1,6 @@ +tar-ignore=.github +tar-ignore=target/.rustc_info.json +tar-ignore=target/CACHEDIR.TAG +tar-ignore=target/debug +tar-ignore=target/release +tar-ignore=vendor diff --git a/src/comp.rs b/src/comp.rs index 47ec37c..feeb103 100644 --- a/src/comp.rs +++ b/src/comp.rs @@ -99,6 +99,7 @@ pub fn run_compositor( process_manager: &ProcessManager, exec: String, args: Vec, + env: Vec<(String, String)>, _token: CancellationToken, env_tx: oneshot::Sender>, session_dbus_tx: mpsc::Sender, @@ -119,13 +120,15 @@ pub fn run_compositor( OwnedFd::from(std_stream) }; mark_as_not_cloexec(&comp).expect("Failed to mark fd as not cloexec"); + Ok(tokio::spawn(async move { // Create a new process handler for cosmic-comp, with our compositor socket's // file descriptor as the `COSMIC_SESSION_SOCK` environment variable. - let mut comp_env = vec![( + let mut comp_env = env; + comp_env.push(( "COSMIC_SESSION_SOCK".to_string(), comp.as_raw_fd().to_string(), - )]; + )); // NVIDIA keeps a growing pool of pre-rendered compositor frames // (smithay#1562 / cosmic-comp#1179). Cap it to a single buffer. if std::path::Path::new("/proc/driver/nvidia").exists() { diff --git a/src/main.rs b/src/main.rs index 163fb88..b62d2ac 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ mod comp; mod notifications; mod process; mod service; +#[cfg(feature = "systemd")] mod systemd; use color_eyre::Result; @@ -15,16 +16,11 @@ use launch_pad::ProcessManager; use launch_pad::process::Process; use service::SessionRequest; use std::borrow::Cow; -#[cfg(feature = "autostart")] -use std::collections::HashSet; use std::env; use std::os::fd::AsRawFd; -#[cfg(feature = "autostart")] -use std::path::PathBuf; -#[cfg(feature = "autostart")] -use std::process::{Command, Stdio}; use std::sync::Arc; -use systemd::is_systemd_used; +#[cfg(any(feature = "autostart", feature = "systemd"))] +use std::{path::Path, sync::OnceLock}; #[cfg(feature = "systemd")] use systemd::{get_systemd_env, spawn_scope}; use tokio::signal::unix::{SignalKind, signal}; @@ -36,14 +32,20 @@ use tracing::Instrument; use tracing::metadata::LevelFilter; use tracing_subscriber::prelude::*; use tracing_subscriber::{EnvFilter, fmt}; +#[cfg(feature = "autostart")] +use { + std::collections::HashSet, + std::path::PathBuf, + std::process::{Command, Stdio}, +}; use crate::notifications::{ DAEMON_NOTIFICATIONS_FD, PANEL_NOTIFICATIONS_FD, notifications_process, }; #[cfg(feature = "autostart")] -const AUTOSTART_DIR: &'static str = "autostart"; +const AUTOSTART_DIR: &str = "autostart"; #[cfg(feature = "autostart")] -const ENVIRONMENT_NAME: &'static str = "COSMIC"; +const ENVIRONMENT_NAME: &str = "COSMIC"; #[tokio::main(flavor = "current_thread")] async fn main() -> Result<()> { @@ -143,10 +145,20 @@ async fn start( .await; let token = CancellationToken::new(); let (env_tx, env_rx) = oneshot::channel(); + + #[cfg(feature = "systemd")] + let systemd_env = if *is_systemd_used() { + get_systemd_env().await + } else { + Vec::new() + }; + #[cfg(not(feature = "systemd"))] + let systemd_env = Vec::new(); let compositor_handle = comp::run_compositor( &process_manager, executable.clone(), args, + systemd_env.clone(), token.child_token(), env_tx, session_tx, @@ -164,7 +176,12 @@ async fn start( ); // now that cosmic-comp is ready, set XDG_SESSION_TYPE=wayland for new processes - env_vars.push(("XDG_SESSION_TYPE".to_string(), "wayland".to_string())); + env_vars.extend( + systemd_env + .into_iter() + .chain([("XDG_SESSION_TYPE".to_string(), "wayland".to_string())]), + ); + #[cfg(feature = "systemd")] systemd::set_systemd_environment("XDG_SESSION_TYPE", "wayland").await; // expose the session version @@ -172,68 +189,36 @@ async fn start( "COSMIC_VERSION".to_string(), env!("CARGO_PKG_VERSION").to_string(), )); + #[cfg(feature = "systemd")] systemd::set_systemd_environment("COSMIC_VERSION", env!("CARGO_PKG_VERSION")).await; - #[cfg(feature = "systemd")] - let _inhibit_fd = if *is_systemd_used() { - match get_systemd_env().await { - Ok(env) => { - for systemd_env in env { - // Only update the envvar if unset - if std::env::var_os(&systemd_env.key).is_none() { - // Blacklist of envvars that we shouldn't touch (taken from KDE) - if (!systemd_env.key.starts_with("XDG_") - || systemd_env.key == "XDG_DATA_DIRS" - || systemd_env.key == "XDG_CONFIG_DIRS") - && systemd_env.key != "DISPLAY" - && systemd_env.key != "XAUTHORITY" - && systemd_env.key != "WAYLAND_DISPLAY" - && systemd_env.key != "WAYLAND_SOCKET" - && systemd_env.key != "_" - && systemd_env.key != "SHELL" - && systemd_env.key != "SHLVL" - { - env_vars.push((systemd_env.key, systemd_env.value)); - } - } - } - } - Err(err) => { - warn!("Failed to sync systemd environment {}.", err); - } - }; - #[cfg(feature = "logind")] - match zbus::Connection::system().await { - Ok(connection) => match logind_zbus::manager::ManagerProxy::new(&connection).await { - Ok(proxy) => match proxy - .inhibit( - logind_zbus::manager::InhibitType::HandlePowerKey, - "Cosmic Session", - "Show confirmation dialog.", - "block", - ) - .await - { - Ok(fd) => Some(fd), - Err(err) => { - error!("Failed to inhibit power key {err:?}"); - None - } - }, + #[cfg(feature = "logind")] + let _inhibit_fd = match zbus::Connection::system().await { + Ok(connection) => match logind_zbus::manager::ManagerProxy::new(&connection).await { + Ok(proxy) => match proxy + .inhibit( + logind_zbus::manager::InhibitType::HandlePowerKey, + "Cosmic Session", + "Show confirmation dialog.", + "block", + ) + .await + { + Ok(fd) => Some(fd), Err(err) => { - error!("Failed to connect to logind manager {err:?}"); + error!("Failed to inhibit power key {err:?}"); None } }, Err(err) => { - error!("Failed to connect to system dbus {err:?}"); + error!("Failed to connect to logind manager {err:?}"); None } + }, + Err(err) => { + error!("Failed to connect to system dbus {err:?}"); + None } - #[cfg(not(feature = "logind"))] - None - } else { - None }; let (settings_exit_tx, settings_exit_rx) = oneshot::channel(); @@ -260,8 +245,10 @@ async fn start( // - cosmic-comp is ready // - we've set any related variables // - cosmic-settings-daemon is ready + #[cfg(feature = "systemd")] systemd::start_systemd_target().await; // Always stop the target when the process exits or panics. + #[cfg(feature = "systemd")] scopeguard::defer! { systemd::stop_systemd_target(); } @@ -394,17 +381,17 @@ async fn start( } // skip if we have an OnlyShowIn entry that doesn't include COSMIC - if let Some(only_show_in) = entry.only_show_in() { - if !only_show_in.contains(&ENVIRONMENT_NAME) { - continue; - } + if let Some(only_show_in) = entry.only_show_in() + && !only_show_in.contains(&ENVIRONMENT_NAME) + { + continue; } // ... OR we have a NotShowIn entry that includes COSMIC - if let Some(not_show_in) = entry.not_show_in() { - if not_show_in.contains(&ENVIRONMENT_NAME) { - continue; - } + if let Some(not_show_in) = entry.not_show_in() + && not_show_in.contains(&ENVIRONMENT_NAME) + { + continue; } info!( @@ -423,7 +410,7 @@ async fn start( .collect::>(); // escape them - let escaped_args = shell_words::split(&*filtered_args.join(" ")); + let escaped_args = shell_words::split(&filtered_args.join(" ")); if let Ok(args) = escaped_args { info!("trying to start {} {}", program_name, args.join(" ")); @@ -665,3 +652,11 @@ async fn start_component( error!("failed to start {}: {}", cmd, err); } } + +/// Determine if systemd is used as the init system. This should work on all +/// linux distributions. +#[cfg(any(feature = "autostart", feature = "systemd"))] +fn is_systemd_used() -> &'static bool { + static IS_SYSTEMD_USED: OnceLock = OnceLock::new(); + IS_SYSTEMD_USED.get_or_init(|| Path::new("/run/systemd/system").exists()) +} diff --git a/src/systemd.rs b/src/systemd.rs index cbf64d5..77c03e9 100644 --- a/src/systemd.rs +++ b/src/systemd.rs @@ -1,28 +1,9 @@ // SPDX-License-Identifier: GPL-3.0-only -use std::path::Path; use std::process::{Command, Stdio}; -use std::sync::OnceLock; use zbus::Connection; use zbus::zvariant::{Array, OwnedValue}; - -#[derive(Debug)] -pub struct EnvVar { - pub key: String, - pub value: String, -} - -impl From<(&str, &str)> for EnvVar { - fn from(val: (&str, &str)) -> Self { - EnvVar { - key: val.0.to_owned(), - value: val.1.to_owned(), - } - } -} - -#[cfg(feature = "systemd")] use zbus_systemd::systemd1::ManagerProxy as SystemdManagerProxy; pub async fn set_systemd_environment(key: &str, value: &str) { @@ -46,29 +27,44 @@ pub fn stop_systemd_target() { ) } -/// Determine if systemd is used as the init system. This should work on all -/// linux distributions. -pub fn is_systemd_used() -> &'static bool { - static IS_SYSTEMD_USED: OnceLock = OnceLock::new(); - IS_SYSTEMD_USED.get_or_init(|| Path::new("/run/systemd/system").exists()) -} - -#[cfg(feature = "systemd")] -pub async fn get_systemd_env() -> Result, zbus::Error> { +async fn load_systemd_env() -> zbus::Result> { let connection = Connection::session().await?; let systemd_manager = SystemdManagerProxy::new(&connection).await?; - let systemd_env = systemd_manager.environment().await?; - - let mut out: Vec = Vec::new(); - for i in systemd_env { - if let Some(b) = i.split_once("=") { - out.push(b.into()); - } - } - Ok(out) + systemd_manager.environment().await +} + +/// Get the systemd user manager environment variables. +pub async fn get_systemd_env() -> Vec<(String, String)> { + match load_systemd_env().await { + Ok(env) => { + env.iter() + // split into key value pairs + .filter_map(|var| var.split_once("=")) + .filter(|&(key, _value)| { + // Only update the envvar if unset + std::env::var_os(key).is_none() + // Blocklist of envvars that we shouldn't touch (taken from KDE) + && (!key.starts_with("XDG_") + || key == "XDG_DATA_DIRS" + || key == "XDG_CONFIG_DIRS") + && key != "DISPLAY" + && key != "XAUTHORITY" + && key != "WAYLAND_DISPLAY" + && key != "WAYLAND_SOCKET" + && key != "_" + && key != "SHELL" + && key != "SHLVL" + }) + .map(|(key, value)| (key.to_owned(), value.to_owned())) + .collect() + } + Err(err) => { + warn!("Failed to sync systemd environment {}.", err); + Vec::new() + } + } } -#[cfg(feature = "systemd")] /// Spawn a systemd scope unit with the given name and PIDs. pub async fn spawn_scope(mut command: String, pids: Vec) -> Result<(), zbus::Error> { let connection = Connection::session().await?;