From 2f4d5efae7ed8ed19354774b61ff7914ae2831b5 Mon Sep 17 00:00:00 2001 From: Antoine POPINEAU Date: Thu, 25 Apr 2024 08:18:27 +0200 Subject: [PATCH] Properly set XDG_SESSION_DESKTOP, DESKTOP_SESSION and XDG_CURRENT_DESKTOP according to desktop file (#120). --- src/info.rs | 4 ++++ src/ipc.rs | 25 +++++++++++++++++++++++-- src/ui/sessions.rs | 12 ++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/info.rs b/src/info.rs index 10c66f5..8af759d 100644 --- a/src/info.rs +++ b/src/info.rs @@ -236,14 +236,18 @@ where let desktop = Ini::load_from_file(path.as_ref())?; let section = desktop.section(Some("Desktop Entry")).ok_or("no Desktop Entry section in desktop file")?; + let slug = path.as_ref().file_stem().map(|slug| slug.to_string_lossy().to_string()); let name = section.get("Name").ok_or("no Name property in desktop file")?; let exec = section.get("Exec").ok_or("no Exec property in desktop file")?; + let xdg_desktop_names = section.get("DesktopNames").map(str::to_string); Ok(Session { + slug, name: name.to_string(), command: exec.to_string(), session_type, path: Some(path.as_ref().into()), + xdg_desktop_names, }) } diff --git a/src/ipc.rs b/src/ipc.rs index e542fff..b8d6de4 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -191,10 +191,23 @@ impl Ipc { fn wrap_session_command<'a>(greeter: &Greeter, session: Option<&Session>, command: &'a str) -> (Cow<'a, str>, Vec) { let mut env: Vec = vec![]; - if let Some(Session { session_type, .. }) = session { + if let Some(Session { + slug, + session_type, + xdg_desktop_names, + .. + }) = session + { + if let Some(slug) = slug { + env.push(format!("XDG_SESSION_DESKTOP={slug}")); + env.push(format!("DESKTOP_SESSION={slug}")); + } if *session_type != SessionType::None { env.push(format!("XDG_SESSION_TYPE={}", session_type.as_xdg_session_type())); } + if let Some(xdg_desktop_names) = xdg_desktop_names { + env.push(format!("XDG_CURRENT_DESKTOP={xdg_desktop_names}")); + } if *session_type == SessionType::X11 { if let Some(ref wrap) = greeter.xsession_wrapper { @@ -230,6 +243,7 @@ mod test { session_type: SessionType::Wayland, command: "Session1Cmd".into(), path: Some(PathBuf::from("/Session1Path")), + ..Default::default() }; let (command, env) = wrap_session_command(&greeter, Some(&session), &session.command); @@ -248,6 +262,7 @@ mod test { session_type: SessionType::Wayland, command: "Session1Cmd".into(), path: Some(PathBuf::from("/Session1Path")), + ..Default::default() }; let (command, env) = wrap_session_command(&greeter, Some(&session), &session.command); @@ -264,15 +279,21 @@ mod test { println!("{:?}", greeter.xsession_wrapper); let session = Session { + slug: Some("thede".to_string()), name: "Session1".into(), session_type: SessionType::X11, command: "Session1Cmd".into(), path: Some(PathBuf::from("/Session1Path")), + xdg_desktop_names: Some("one;two;three;".to_string()), + ..Default::default() }; let (command, env) = wrap_session_command(&greeter, Some(&session), &session.command); assert_eq!(command.as_ref(), "startx /usr/bin/env Session1Cmd"); - assert_eq!(env, vec!["XDG_SESSION_TYPE=x11"]); + assert_eq!( + env, + vec!["XDG_SESSION_DESKTOP=thede", "DESKTOP_SESSION=thede", "XDG_SESSION_TYPE=x11", "XDG_CURRENT_DESKTOP=one;two;three;"] + ); } } diff --git a/src/ui/sessions.rs b/src/ui/sessions.rs index 3956ab6..c7296ee 100644 --- a/src/ui/sessions.rs +++ b/src/ui/sessions.rs @@ -68,6 +68,9 @@ impl SessionType { // A session, as defined by an XDG session file. #[derive(SmartDefault, Clone)] pub struct Session { + // Slug of the session, being the name of the desktop file without its + // extension. + pub slug: Option, // Human-friendly name for the session, maps to the `Name` attribute. pub name: String, // Command used to start the session, maps to the `Exec` attribute. @@ -78,6 +81,8 @@ pub struct Session { // Path to the session file. Used to uniquely identify sessions, since names // and commands can be identital between two different sessions. pub path: Option, + // Desktop names as defined with the `DesktopNames` desktop file property + pub xdg_desktop_names: Option, } impl MenuItem for Session { @@ -134,12 +139,14 @@ mod test { command: "Session1Cmd".into(), session_type: super::SessionType::Wayland, path: Some("/Session1Path".into()), + ..Default::default() }, Session { name: "Session2".into(), command: "Session2Cmd".into(), session_type: super::SessionType::X11, path: Some("/Session2Path".into()), + ..Default::default() }, ], }; @@ -164,6 +171,7 @@ mod test { command: "Session1Cmd".into(), session_type: super::SessionType::Wayland, path: Some("/Session1Path".into()), + ..Default::default() }], }; @@ -193,12 +201,14 @@ mod test { command: "Session1Cmd".into(), session_type: super::SessionType::Wayland, path: Some("/Session1Path".into()), + ..Default::default() }, Session { name: "Session2".into(), command: "Session2Cmd".into(), session_type: super::SessionType::X11, path: Some("/Session2Path".into()), + ..Default::default() }, ], }; @@ -224,12 +234,14 @@ mod test { command: "Session1Cmd".into(), session_type: super::SessionType::Wayland, path: Some("/Session1Path".into()), + ..Default::default() }, Session { name: "Session".into(), command: "Session2Cmd".into(), session_type: super::SessionType::X11, path: Some("/Session2Path".into()), + ..Default::default() }, ], };