refactor: apply CLAUDE.md code quality improvements and add packaging

- Add #![forbid(unsafe_code)] to main.rs (issue #3)
- Replace raw ANSI escape codes with owo-colors crate (issue #2)
- Replace manual HOME path construction with dirs::home_dir() (issue #5)
- Ship umutray.service as a static file; service::install() substitutes
  the binary path at install time instead of generating the unit at runtime
- Add packaging/PKGBUILD following Arch Rust package guidelines
- Add CLAUDE.md tracking refactor tasks
- setup.rs: clean up downloaded temp files on abort/back, save launcher
  to config only after successful install, auto-start download when a
  preset has an installer_url
- util.rs: add pick_folder() using zenity/kdialog subprocesses (no rfd)
- config.rs: populate installer_url for all 6 built-in presets with
  official download URLs
- Document the Option<Option<Vec<String>>> gamescope pattern at main.rs:307

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
funman300
2026-04-18 19:28:10 -07:00
parent f2f584febf
commit 9b7e474e80
11 changed files with 233 additions and 57 deletions
+20
View File
@@ -14,3 +14,23 @@ where
});
rx.await.expect("blocking task panicked")
}
/// Open a native folder picker dialog and return the chosen path, or None if
/// the user cancelled. Tries zenity (GNOME/GTK) then kdialog (KDE) in order.
pub fn pick_folder(title: &str) -> Option<String> {
for (cmd, args) in [
("zenity", vec!["--file-selection", "--directory", "--title", title]),
("kdialog", vec!["--getexistingdirectory", "/home", "--title", title]),
] {
let Ok(out) = std::process::Command::new(cmd).args(&args).output() else {
continue;
};
if out.status.success() {
let s = String::from_utf8_lossy(&out.stdout).trim().to_string();
if !s.is_empty() {
return Some(s);
}
}
}
None
}