From 4ca17d1337acfbbc21c04058d97f689a1cce60a6 Mon Sep 17 00:00:00 2001 From: Jake Stanger Date: Wed, 5 Jul 2023 23:18:43 +0100 Subject: [PATCH] fix(launcher): incorrectly resolving some applications Potentially also fixes some mismatches with icons. Fixes #222. --- src/desktop_file.rs | 87 +++++++++++++++++++++++++++++++-------------- 1 file changed, 61 insertions(+), 26 deletions(-) diff --git a/src/desktop_file.rs b/src/desktop_file.rs index 723dcb5..7a143ce 100644 --- a/src/desktop_file.rs +++ b/src/desktop_file.rs @@ -65,33 +65,40 @@ pub fn find_desktop_file(app_id: &str) -> Option { // this is necessary to invalidate the cache let files = find_desktop_files(); - if let Some(path) = find_desktop_file_by_filename(app_id, &files) { - return Some(path); - } - - find_desktop_file_by_filedata(app_id, &files) + find_desktop_file_by_filename(app_id, &files) + .or_else(|| find_desktop_file_by_filedata(app_id, &files)) } /// Finds the correct desktop file using a simple condition check fn find_desktop_file_by_filename(app_id: &str, files: &[PathBuf]) -> Option { - let app_id = app_id.to_lowercase(); - - files + let with_names = files .iter() - .find(|file| { - let file_name: String = file - .file_name() - .expect("file name doesn't end with ...") - .to_string_lossy() - .to_lowercase(); - - file_name.contains(&app_id) - || app_id - .split(&[' ', ':', '@', '.', '_'][..]) - .any(|part| file_name.contains(part)) // this will attempt to find flatpak apps that are like this - // `com.company.app` or `com.app.something` + .map(|f| { + ( + f, + f.file_stem() + .unwrap_or_default() + .to_string_lossy() + .to_lowercase(), + ) }) - .map(ToOwned::to_owned) + .collect::>(); + + with_names + .iter() + // first pass - check for exact match + .find(|(_, name)| name.eq_ignore_ascii_case(app_id)) + // second pass - check for substring + .or_else(|| { + with_names.iter().find(|(_, name)| { + // this will attempt to find flatpak apps that are in the format + // `com.company.app` or `com.app.something` + app_id + .split(&[' ', ':', '@', '.', '_'][..]) + .any(|part| name.contains(part)) + }) + }) + .map(|(file, _)| file.into()) } /// Finds the correct desktop file using the keys in `DESKTOP_FILES_LOOK_OUT_KEYS` @@ -99,7 +106,7 @@ fn find_desktop_file_by_filedata(app_id: &str, files: &[PathBuf]) -> Option Option>(); + + let file = files + .iter() + // first pass - check name key for exact match .find(|(_, desktop_file)| { desktop_file - .values() - .flatten() - .any(|value| value.to_lowercase().contains(app_id)) + .get("Name") + .map(|names| names.iter().any(|name| name.eq_ignore_ascii_case(app_id))) + .unwrap_or_default() }) - .map(|(path, _)| path) + // second pass - check name key for substring + .or_else(|| { + files.iter().find(|(_, desktop_file)| { + desktop_file + .get("Name") + .map(|names| { + names + .iter() + .any(|name| name.to_lowercase().contains(app_id)) + }) + .unwrap_or_default() + }) + }) + // third pass - check all keys for substring + .or_else(|| { + files.iter().find(|(_, desktop_file)| { + desktop_file + .values() + .flatten() + .any(|value| value.to_lowercase().contains(app_id)) + }) + }); + + file.map(|(path, _)| path).cloned() } /// Parses a desktop file into a hashmap of keys/vector(values).