Properly set XDG_SESSION_DESKTOP, DESKTOP_SESSION and XDG_CURRENT_DESKTOP according to desktop file (#120).

This commit is contained in:
Antoine POPINEAU 2024-04-25 08:18:27 +02:00
parent a918caefc1
commit 2f4d5efae7
No known key found for this signature in database
GPG Key ID: E8379674E92D25D2
3 changed files with 39 additions and 2 deletions

View File

@ -236,14 +236,18 @@ where
let desktop = Ini::load_from_file(path.as_ref())?; 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 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 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 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 { Ok(Session {
slug,
name: name.to_string(), name: name.to_string(),
command: exec.to_string(), command: exec.to_string(),
session_type, session_type,
path: Some(path.as_ref().into()), path: Some(path.as_ref().into()),
xdg_desktop_names,
}) })
} }

View File

@ -191,10 +191,23 @@ impl Ipc {
fn wrap_session_command<'a>(greeter: &Greeter, session: Option<&Session>, command: &'a str) -> (Cow<'a, str>, Vec<String>) { fn wrap_session_command<'a>(greeter: &Greeter, session: Option<&Session>, command: &'a str) -> (Cow<'a, str>, Vec<String>) {
let mut env: Vec<String> = vec![]; let mut env: Vec<String> = 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 { if *session_type != SessionType::None {
env.push(format!("XDG_SESSION_TYPE={}", session_type.as_xdg_session_type())); 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 *session_type == SessionType::X11 {
if let Some(ref wrap) = greeter.xsession_wrapper { if let Some(ref wrap) = greeter.xsession_wrapper {
@ -230,6 +243,7 @@ mod test {
session_type: SessionType::Wayland, session_type: SessionType::Wayland,
command: "Session1Cmd".into(), command: "Session1Cmd".into(),
path: Some(PathBuf::from("/Session1Path")), path: Some(PathBuf::from("/Session1Path")),
..Default::default()
}; };
let (command, env) = wrap_session_command(&greeter, Some(&session), &session.command); let (command, env) = wrap_session_command(&greeter, Some(&session), &session.command);
@ -248,6 +262,7 @@ mod test {
session_type: SessionType::Wayland, session_type: SessionType::Wayland,
command: "Session1Cmd".into(), command: "Session1Cmd".into(),
path: Some(PathBuf::from("/Session1Path")), path: Some(PathBuf::from("/Session1Path")),
..Default::default()
}; };
let (command, env) = wrap_session_command(&greeter, Some(&session), &session.command); let (command, env) = wrap_session_command(&greeter, Some(&session), &session.command);
@ -264,15 +279,21 @@ mod test {
println!("{:?}", greeter.xsession_wrapper); println!("{:?}", greeter.xsession_wrapper);
let session = Session { let session = Session {
slug: Some("thede".to_string()),
name: "Session1".into(), name: "Session1".into(),
session_type: SessionType::X11, session_type: SessionType::X11,
command: "Session1Cmd".into(), command: "Session1Cmd".into(),
path: Some(PathBuf::from("/Session1Path")), 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); let (command, env) = wrap_session_command(&greeter, Some(&session), &session.command);
assert_eq!(command.as_ref(), "startx /usr/bin/env Session1Cmd"); 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;"]
);
} }
} }

View File

@ -68,6 +68,9 @@ impl SessionType {
// A session, as defined by an XDG session file. // A session, as defined by an XDG session file.
#[derive(SmartDefault, Clone)] #[derive(SmartDefault, Clone)]
pub struct Session { pub struct Session {
// Slug of the session, being the name of the desktop file without its
// extension.
pub slug: Option<String>,
// Human-friendly name for the session, maps to the `Name` attribute. // Human-friendly name for the session, maps to the `Name` attribute.
pub name: String, pub name: String,
// Command used to start the session, maps to the `Exec` attribute. // 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 // Path to the session file. Used to uniquely identify sessions, since names
// and commands can be identital between two different sessions. // and commands can be identital between two different sessions.
pub path: Option<PathBuf>, pub path: Option<PathBuf>,
// Desktop names as defined with the `DesktopNames` desktop file property
pub xdg_desktop_names: Option<String>,
} }
impl MenuItem for Session { impl MenuItem for Session {
@ -134,12 +139,14 @@ mod test {
command: "Session1Cmd".into(), command: "Session1Cmd".into(),
session_type: super::SessionType::Wayland, session_type: super::SessionType::Wayland,
path: Some("/Session1Path".into()), path: Some("/Session1Path".into()),
..Default::default()
}, },
Session { Session {
name: "Session2".into(), name: "Session2".into(),
command: "Session2Cmd".into(), command: "Session2Cmd".into(),
session_type: super::SessionType::X11, session_type: super::SessionType::X11,
path: Some("/Session2Path".into()), path: Some("/Session2Path".into()),
..Default::default()
}, },
], ],
}; };
@ -164,6 +171,7 @@ mod test {
command: "Session1Cmd".into(), command: "Session1Cmd".into(),
session_type: super::SessionType::Wayland, session_type: super::SessionType::Wayland,
path: Some("/Session1Path".into()), path: Some("/Session1Path".into()),
..Default::default()
}], }],
}; };
@ -193,12 +201,14 @@ mod test {
command: "Session1Cmd".into(), command: "Session1Cmd".into(),
session_type: super::SessionType::Wayland, session_type: super::SessionType::Wayland,
path: Some("/Session1Path".into()), path: Some("/Session1Path".into()),
..Default::default()
}, },
Session { Session {
name: "Session2".into(), name: "Session2".into(),
command: "Session2Cmd".into(), command: "Session2Cmd".into(),
session_type: super::SessionType::X11, session_type: super::SessionType::X11,
path: Some("/Session2Path".into()), path: Some("/Session2Path".into()),
..Default::default()
}, },
], ],
}; };
@ -224,12 +234,14 @@ mod test {
command: "Session1Cmd".into(), command: "Session1Cmd".into(),
session_type: super::SessionType::Wayland, session_type: super::SessionType::Wayland,
path: Some("/Session1Path".into()), path: Some("/Session1Path".into()),
..Default::default()
}, },
Session { Session {
name: "Session".into(), name: "Session".into(),
command: "Session2Cmd".into(), command: "Session2Cmd".into(),
session_type: super::SessionType::X11, session_type: super::SessionType::X11,
path: Some("/Session2Path".into()), path: Some("/Session2Path".into()),
..Default::default()
}, },
], ],
}; };