aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2023-08-27 07:37:36 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2023-08-27 07:37:36 +0400
commitd268cfcf9f2d86a58456f3f3b946a763d1cc6140 (patch)
tree6b086ff15246e3a68c3e5a7052f8adcf50dfeb62
parent99484afe526dde4c04050f0ea7c98dc63f444fdf (diff)
downloadniri-d268cfcf9f2d86a58456f3f3b946a763d1cc6140.tar.gz
niri-d268cfcf9f2d86a58456f3f3b946a763d1cc6140.tar.bz2
niri-d268cfcf9f2d86a58456f3f3b946a763d1cc6140.zip
Add initial session / systemd integration
-rw-r--r--Cargo.lock7
-rw-r--r--Cargo.toml1
-rwxr-xr-xresources/niri-session30
-rw-r--r--resources/niri.desktop6
-rw-r--r--resources/niri.service9
-rw-r--r--src/main.rs6
-rw-r--r--src/niri.rs23
7 files changed, 82 insertions, 0 deletions
diff --git a/Cargo.lock b/Cargo.lock
index f01f6e80..97e854a4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -813,6 +813,7 @@ dependencies = [
"clap",
"keyframe",
"profiling",
+ "sd-notify",
"smithay",
"smithay-drm-extras",
"tracing",
@@ -1187,6 +1188,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
[[package]]
+name = "sd-notify"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "621e3680f3e07db4c9c2c3fb07c6223ab2fab2e54bd3c04c3ae037990f428c32"
+
+[[package]]
name = "sharded-slab"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 4699fbec..c1634f3b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,6 +12,7 @@ bitflags = "2.3.3"
clap = { version = "4.3.21", features = ["derive"] }
keyframe = { version = "1.1.1", default-features = false }
profiling = "1.0.9"
+sd-notify = "0.4.1"
smithay-drm-extras = { version = "0.1.0", path = "../smithay/smithay-drm-extras" }
tracing = "0.1.37"
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
diff --git a/resources/niri-session b/resources/niri-session
new file mode 100755
index 00000000..77332e32
--- /dev/null
+++ b/resources/niri-session
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+# Make sure there's no already running session.
+if systemctl --user -q is-active niri.service; then
+ echo 'A niri session is already running.'
+ exit 1
+fi
+
+# Reset failed state of all user units.
+systemctl --user reset-failed
+
+# Set the current desktop for xdg-desktop-portal.
+export XDG_CURRENT_DESKTOP=niri
+
+# Ensure the session type is set to Wayland for xdg-autostart apps.
+export XDG_SESSION_TYPE=wayland
+
+# Import the login manager environment.
+systemctl --user import-environment
+
+# DBus activation environment is independent from systemd. While most of
+# dbus-activated services are already using `SystemdService` directive, some
+# still don't and thus we should set the dbus environment with a separate
+# command.
+if hash dbus-update-activation-environment 2>/dev/null; then
+ dbus-update-activation-environment --all
+fi
+
+# Start niri and wait for it to terminate.
+exec systemctl --user --wait start niri.service
diff --git a/resources/niri.desktop b/resources/niri.desktop
new file mode 100644
index 00000000..5470fe76
--- /dev/null
+++ b/resources/niri.desktop
@@ -0,0 +1,6 @@
+[Desktop Entry]
+Name=Niri
+Comment=A scrollable-tiling Wayland compositor
+Exec=niri-session
+Type=Application
+DesktopNames=niri
diff --git a/resources/niri.service b/resources/niri.service
new file mode 100644
index 00000000..97c6e449
--- /dev/null
+++ b/resources/niri.service
@@ -0,0 +1,9 @@
+[Unit]
+Description=A scrollable-tiling Wayland compositor
+BindsTo=graphical-session.target
+Wants=graphical-session-pre.target
+After=graphical-session-pre.target
+
+[Service]
+Type=notify
+ExecStart=/usr/bin/niri
diff --git a/src/main.rs b/src/main.rs
index 40953348..2b5715fd 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -19,6 +19,7 @@ use std::ffi::OsString;
use backend::Backend;
use clap::Parser;
use niri::Niri;
+use sd_notify::NotifyState;
use smithay::reexports::calloop::EventLoop;
use smithay::reexports::wayland_server::{Display, DisplayHandle};
use tracing_subscriber::EnvFilter;
@@ -121,4 +122,9 @@ fn main() {
}
})
.unwrap();
+
+ // Tell systemd we're stopping.
+ if let Err(err) = sd_notify::notify(false, &[NotifyState::Stopping]) {
+ warn!("error notifying systemd: {err:?}");
+ }
}
diff --git a/src/niri.rs b/src/niri.rs
index 05a2b3a4..b428345a 100644
--- a/src/niri.rs
+++ b/src/niri.rs
@@ -1,8 +1,10 @@
use std::collections::HashMap;
use std::os::unix::io::AsRawFd;
+use std::process::Command;
use std::sync::{Arc, Mutex};
use std::time::Duration;
+use sd_notify::NotifyState;
use smithay::backend::renderer::element::surface::{
render_elements_from_surface_tree, WaylandSurfaceRenderElement,
};
@@ -149,6 +151,27 @@ impl Niri {
socket_name.to_string_lossy()
);
+ if std::env::var_os("NOTIFY_SOCKET").is_some() {
+ // We're starting as a systemd service. Export our variables and tell systemd we're
+ // ready.
+ let rv = Command::new("/bin/sh")
+ .args([
+ "-c",
+ "systemctl --user import-environment WAYLAND_DISPLAY && \
+ hash dbus-update-activation-environment 2>/dev/null && \
+ dbus-update-activation-environment WAYLAND_DISPLAY",
+ ])
+ .spawn();
+ if let Err(err) = rv {
+ warn!("error spawning shell to import environment into systemd: {err:?}");
+ }
+
+ // Notify systemd we're ready.
+ if let Err(err) = sd_notify::notify(false, &[NotifyState::Ready]) {
+ warn!("error notifying systemd: {err:?}");
+ };
+ }
+
let display_source = Generic::new(
display.backend().poll_fd().as_raw_fd(),
Interest::READ,