Add deentry for desktop entry sessions

This commit is contained in:
coastalwhite 2024-04-06 16:50:42 +02:00 committed by Gijs Burghoorn
parent 465566f40a
commit 74e1122fc2
5 changed files with 124 additions and 0 deletions

7
Cargo.lock generated
View file

@ -60,6 +60,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "deentry"
version = "0.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "866170d551fbf7e49a7fe5160092933f210fe1853cf0cbf5d81957b941bdb690"
[[package]]
name = "env_logger"
version = "0.9.3"
@ -92,6 +98,7 @@ name = "lemurs"
version = "0.3.2"
dependencies = [
"crossterm",
"deentry",
"env_logger",
"libc",
"log",

View file

@ -34,6 +34,8 @@ unicode-width = "0.1"
mio = { version = "0.8.8", features = [ "os-poll", "os-ext" ] }
deentry = "0.0.1"
# Interacting with the kernel interfaces
rand = "0.8.4"
nix = "0.23.1"

View file

@ -340,7 +340,13 @@ scripts_path = "/etc/lemurs/wms"
# window manager.
xsetup_path = "/etc/lemurs/xsetup.sh"
# The directory to use for desktop entries X11 sessions.
xsessions_path = "/usr/share/xsessions"
[wayland]
# Path to the directory where the startup scripts for the Wayland sessions are
# found
scripts_path = "/etc/lemurs/wayland"
# The directory to use for desktop entries wayland sessions.
wayland_sessions_path = "/usr/share/wayland-sessions"

View file

@ -374,10 +374,12 @@ toml_config_struct! { X11Config, PartialX11Config, RoughX11Config,
scripts_path => String,
xsetup_path => String,
xsessions_path => String,
}
toml_config_struct! { WaylandConfig, PartialWaylandConfig, RoughWaylandConfig,
scripts_path => String,
wayland_sessions_path => String,
}
#[derive(Debug, Clone, Deserialize)]

View file

@ -234,10 +234,111 @@ impl PostLoginEnvironment {
}
}
fn parse_desktop_entry(path: &Path, _: &Config) -> Result<(String, String), String> {
let content = match fs::read_to_string(path) {
Ok(content) => content,
Err(err) => {
return Err(format!("file cannot be read. Reason: {err}"));
}
};
let desktop_entry = match deentry::DesktopEntry::try_from(&content[..]) {
Ok(v) => v,
Err(err) => {
return Err(format!("file cannot be parsed. Reason: {err}"));
}
};
let Some(desktop_entry) = desktop_entry
.groups()
.iter()
.find(|g| g.name() == "Desktop Entry")
else {
return Err(format!("file does not contain 'Desktop Entry' group"));
};
let Some(exec) = desktop_entry.get("Exec") else {
return Err(format!("'Exec' key cannot be found"));
};
let exec = match exec.value().as_string() {
Ok(v) => v,
Err(err) => {
return Err(format!(
"'Exec' key does not contain a string. Reason: {err}"
));
}
};
let name = match desktop_entry.get("Name") {
Some(name) => match name.value().as_string() {
Ok(v) => v,
Err(err) => {
warn!(
"Cannot use 'Name' in '{}' because it does not contain a string. Reason: {err}",
path.display()
);
exec
}
},
None => exec,
};
Ok((name.to_string(), exec.to_string()))
}
pub fn get_envs(config: &Config) -> Vec<(String, PostLoginEnvironment)> {
// NOTE: Maybe we can do something smart with `with_capacity` here.
let mut envs = Vec::new();
match fs::read_dir(&config.x11.xsessions_path) {
Ok(paths) => {
for path in paths {
let Ok(path) = path else {
continue;
};
let path = path.path();
match parse_desktop_entry(&path, config) {
Ok((name, exec)) => {
info!("Added environment '{name}' from xsessions");
envs.push((name, PostLoginEnvironment::X { xinitrc_path: exec }));
}
Err(err) => warn!("Skipping '{}', because {err}", path.display()),
}
}
}
Err(err) => {
warn!("Failed to read from the xsessions folder '{err}'",);
}
}
match fs::read_dir(&config.wayland.wayland_sessions_path
) {
Ok(paths) => {
for path in paths {
let Ok(path) = path else {
continue;
};
let path = path.path();
match parse_desktop_entry(&path, config) {
Ok((name, exec)) => {
info!("Added environment '{name}' from wayland sessions");
envs.push((name, PostLoginEnvironment::Wayland { script_path: exec }))
}
Err(err) => warn!("Skipping '{}', because {err}", path.display()),
}
}
}
Err(err) => {
warn!("Failed to read from the wayland sessions folder '{err}'",);
}
}
match fs::read_dir(&config.x11.scripts_path) {
Ok(paths) => {
for path in paths {
@ -255,6 +356,7 @@ pub fn get_envs(config: &Config) -> Vec<(String, PostLoginEnvironment)> {
}
}
info!("Added environment '{file_name}' from lemurs x11 scripts");
envs.push((
file_name,
PostLoginEnvironment::X {
@ -303,6 +405,7 @@ pub fn get_envs(config: &Config) -> Vec<(String, PostLoginEnvironment)> {
}
}
info!("Added environment '{file_name}' from lemurs wayland scripts");
envs.push((
file_name,
PostLoginEnvironment::Wayland {
@ -334,6 +437,10 @@ pub fn get_envs(config: &Config) -> Vec<(String, PostLoginEnvironment)> {
}
if envs.is_empty() || config.environment_switcher.include_tty_shell {
if envs.is_empty() {
info!("Added TTY SHELL because no other environments were found");
}
envs.push(("TTYSHELL".to_string(), PostLoginEnvironment::Shell));
}