xdg: startup activation

pass an activation token to process spawned through actions
This commit is contained in:
Christian Meissl
2024-11-03 14:29:36 +01:00
committed by Ivan Molodetskikh
parent 39a9f55205
commit 61f2ac01d7
3 changed files with 17 additions and 6 deletions
+2 -1
View File
@@ -520,7 +520,8 @@ impl State {
self.niri.debug_toggle_damage(); self.niri.debug_toggle_damage();
} }
Action::Spawn(command) => { Action::Spawn(command) => {
spawn(command); let (token, _) = self.niri.activation_state.create_external_token(None);
spawn(command, Some(token.clone()));
} }
Action::DoScreenTransition(delay_ms) => { Action::DoScreenTransition(delay_ms) => {
self.backend.with_primary_renderer(|renderer| { self.backend.with_primary_renderer(|renderer| {
+2 -2
View File
@@ -236,10 +236,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
}; };
// Spawn commands from cli and auto-start. // Spawn commands from cli and auto-start.
spawn(cli.command); spawn(cli.command, None);
for elem in spawn_at_startup { for elem in spawn_at_startup {
spawn(elem.command); spawn(elem.command, None);
} }
// Show the config error notification right away if needed. // Show the config error notification right away if needed.
+13 -3
View File
@@ -9,6 +9,7 @@ use std::{io, thread};
use atomic::Atomic; use atomic::Atomic;
use libc::{getrlimit, rlim_t, rlimit, setrlimit, RLIMIT_NOFILE}; use libc::{getrlimit, rlim_t, rlimit, setrlimit, RLIMIT_NOFILE};
use niri_config::Environment; use niri_config::Environment;
use smithay::wayland::xdg_activation::XdgActivationToken;
use crate::utils::expand_home; use crate::utils::expand_home;
@@ -61,7 +62,7 @@ pub fn restore_nofile_rlimit() {
} }
/// Spawns the command to run independently of the compositor. /// Spawns the command to run independently of the compositor.
pub fn spawn<T: AsRef<OsStr> + Send + 'static>(command: Vec<T>) { pub fn spawn<T: AsRef<OsStr> + Send + 'static>(command: Vec<T>, token: Option<XdgActivationToken>) {
let _span = tracy_client::span!(); let _span = tracy_client::span!();
if command.is_empty() { if command.is_empty() {
@@ -73,7 +74,7 @@ pub fn spawn<T: AsRef<OsStr> + Send + 'static>(command: Vec<T>) {
.name("Command Spawner".to_owned()) .name("Command Spawner".to_owned())
.spawn(move || { .spawn(move || {
let (command, args) = command.split_first().unwrap(); let (command, args) = command.split_first().unwrap();
spawn_sync(command, args); spawn_sync(command, args, token);
}); });
if let Err(err) = res { if let Err(err) = res {
@@ -81,7 +82,11 @@ pub fn spawn<T: AsRef<OsStr> + Send + 'static>(command: Vec<T>) {
} }
} }
fn spawn_sync(command: impl AsRef<OsStr>, args: impl IntoIterator<Item = impl AsRef<OsStr>>) { fn spawn_sync(
command: impl AsRef<OsStr>,
args: impl IntoIterator<Item = impl AsRef<OsStr>>,
token: Option<XdgActivationToken>,
) {
let _span = tracy_client::span!(); let _span = tracy_client::span!();
let mut command = command.as_ref(); let mut command = command.as_ref();
@@ -122,6 +127,11 @@ fn spawn_sync(command: impl AsRef<OsStr>, args: impl IntoIterator<Item = impl As
} }
drop(env); drop(env);
if let Some(token) = token.as_ref() {
process.env("XDG_ACTIVATION_TOKEN", token.as_str());
process.env("DESKTOP_STARTUP_ID", token.as_str());
}
let Some(mut child) = do_spawn(command, process) else { let Some(mut child) = do_spawn(command, process) else {
return; return;
}; };