use std::fs;
use std::io;
use std::path::PathBuf;
pub fn path() -> Option<PathBuf> {
let dir = std::env::var_os("XDG_CONFIG_HOME")
.map(PathBuf::from)
.or_else(|| std::env::var_os("HOME").map(|h| PathBuf::from(h).join(".config")))?;
Some(dir.join("autostart").join("hyprcorrect.desktop"))
}
pub fn is_enabled() -> bool {
path().is_some_and(|p| p.exists())
}
pub fn enable(exec_path: &str) -> io::Result<()> {
let path = path().ok_or_else(|| {
io::Error::other(
"couldn't resolve $XDG_CONFIG_HOME / $HOME — autostart needs one of them set",
)
})?;
if let Some(parent) = path.parent() {
fs::create_dir_all(parent)?;
}
let _ = ensure_user_icon()?;
let contents = format!(
"[Desktop Entry]\n\
Type=Application\n\
Name=hyprcorrect\n\
GenericName=Spelling corrector\n\
Comment=Keyboard-driven desktop spelling and typo correction\n\
Exec={exec_path}\n\
Icon=hyprcorrect\n\
Terminal=false\n\
Categories=Utility;TextTools;\n\
StartupNotify=false\n\
X-GNOME-Autostart-enabled=true\n"
);
fs::write(path, contents)
}
pub fn ensure_user_icon() -> io::Result<Option<PathBuf>> {
let base = std::env::var_os("XDG_DATA_HOME")
.map(PathBuf::from)
.or_else(|| std::env::var_os("HOME").map(|h| PathBuf::from(h).join(".local/share")));
let Some(base) = base else {
return Ok(None);
};
let dir = base.join("icons/hicolor/scalable/apps");
if let Err(e) = fs::create_dir_all(&dir) {
eprintln!(
"hyprcorrect: could not create {} ({e}) — launcher will fall back to icon-theme",
dir.display()
);
return Ok(None);
}
let path = dir.join("hyprcorrect.svg");
if let Err(e) = fs::write(&path, crate::icon::app_icon_svg_bytes()) {
eprintln!(
"hyprcorrect: could not write {} ({e}) — launcher will fall back to icon-theme",
path.display()
);
return Ok(None);
}
Ok(Some(path))
}
pub fn ensure_apps_catalog_entry(exec_path: &str) -> io::Result<Option<PathBuf>> {
let base = std::env::var_os("XDG_DATA_HOME")
.map(PathBuf::from)
.or_else(|| std::env::var_os("HOME").map(|h| PathBuf::from(h).join(".local/share")));
let Some(base) = base else {
return Ok(None);
};
let dir = base.join("applications");
fs::create_dir_all(&dir)?;
let _ = ensure_user_icon()?;
let path = dir.join("hyprcorrect.desktop");
let contents = format!(
"[Desktop Entry]\n\
Type=Application\n\
Name=hyprcorrect\n\
GenericName=Spelling corrector\n\
Comment=Keyboard-driven desktop spelling and typo correction\n\
Exec={exec_path} prefs\n\
Icon=hyprcorrect\n\
Terminal=false\n\
Categories=Utility;TextTools;\n\
Keywords=spell;spellcheck;autocorrect;typo;correction;keyboard;\n\
StartupNotify=false\n"
);
fs::write(&path, contents)?;
Ok(Some(path))
}
pub fn disable() -> io::Result<()> {
let Some(path) = path() else {
return Ok(());
};
match fs::remove_file(path) {
Ok(()) => Ok(()),
Err(e) if e.kind() == io::ErrorKind::NotFound => Ok(()),
Err(e) => Err(e),
}
}