Files
umutray/src/util.rs
T
funman300 2f4f1c64d2 refactor: idiomatic Rust cleanup and quality improvements
- Replace .map().unwrap_or(false) with .is_some_and()/.is_ok_and()
- Use path.display() instead of {:?} for user-facing messages
- Replace Option<Option<Vec<String>>> with GamescopeUpdate enum
- Replace manual parent-walking loops with .ancestors() iterators
- Simplify kill()/kill_all() signatures to return () instead of Result
- Use tokio::task::spawn_blocking instead of hand-rolled thread+oneshot
- Read /proc/self/status for UID instead of spawning id subprocess
- Build Exec= line directly in render_desktop instead of string-replace
- Bump PKGBUILD pkgrel to 6
2026-04-19 11:29:42 -07:00

60 lines
2.1 KiB
Rust

/// Run a blocking closure on the tokio blocking thread pool and await its result.
/// Used to offload blocking work (HTTP, disk, process spawning) without
/// stalling the iced event loop.
pub async fn async_blocking<T, F>(f: F) -> T
where
T: Send + 'static,
F: FnOnce() -> T + Send + 'static,
{
tokio::task::spawn_blocking(f)
.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
}
/// Open a native file picker dialog starting in `start_dir`, or None if
/// the user cancelled. Tries zenity then kdialog.
pub fn pick_file(title: &str, start_dir: &str) -> Option<String> {
// zenity uses --filename with a trailing slash to open a directory
let start_slash = format!("{}/", start_dir.trim_end_matches('/'));
let zenity_args = vec![
"--file-selection",
"--title",
title,
"--filename",
&start_slash,
];
let kdialog_args = vec!["--getopenfilename", start_dir, "--title", title];
for (cmd, args) in [("zenity", zenity_args.as_slice()), ("kdialog", kdialog_args.as_slice())] {
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
}