Revert "fix: new matching algorithm for desktop entries"
This reverts commit 9519b86ec9.
This commit is contained in:
parent
84afe7b50a
commit
c9f8f48537
2 changed files with 28 additions and 107 deletions
|
|
@ -33,7 +33,6 @@ desktop = [
|
||||||
"dep:freedesktop-desktop-entry",
|
"dep:freedesktop-desktop-entry",
|
||||||
"dep:mime",
|
"dep:mime",
|
||||||
"dep:shlex",
|
"dep:shlex",
|
||||||
"dep:textdistance",
|
|
||||||
"dep:zbus",
|
"dep:zbus",
|
||||||
]
|
]
|
||||||
# Enables keycode serialization
|
# Enables keycode serialization
|
||||||
|
|
@ -92,7 +91,6 @@ rustix = { version = "0.38.34", features = ["pipe", "process"], optional = true
|
||||||
serde = { version = "1.0.180", features = ["derive"] }
|
serde = { version = "1.0.180", features = ["derive"] }
|
||||||
slotmap = "1.0.6"
|
slotmap = "1.0.6"
|
||||||
smol = { version = "2.0.0", optional = true }
|
smol = { version = "2.0.0", optional = true }
|
||||||
textdistance = { version = "1.0.2", optional = true }
|
|
||||||
thiserror = "1.0.44"
|
thiserror = "1.0.44"
|
||||||
tokio = { version = "1.24.2", optional = true }
|
tokio = { version = "1.24.2", optional = true }
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
|
|
|
||||||
133
src/desktop.rs
133
src/desktop.rs
|
|
@ -1,9 +1,7 @@
|
||||||
pub use freedesktop_desktop_entry::DesktopEntry;
|
pub use freedesktop_desktop_entry::DesktopEntry;
|
||||||
use iced_widget::canvas::path::lyon_path::geom::euclid::approxord::min;
|
|
||||||
pub use mime::Mime;
|
pub use mime::Mime;
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
cmp::max,
|
|
||||||
ffi::OsStr,
|
ffi::OsStr,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
|
|
@ -83,121 +81,46 @@ pub fn app_id_or_fallback_matches(app_id: &str, entry: &DesktopEntryData) -> boo
|
||||||
|| app_id.to_lowercase() == entry.name.to_lowercase()
|
|| app_id.to_lowercase() == entry.name.to_lowercase()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// From 0 to 1.
|
|
||||||
/// 1 is a perfect match.
|
|
||||||
fn match_entry(id: &str, de: &DesktopEntry) -> f32 {
|
|
||||||
let cmp = |id, de| {
|
|
||||||
let lcsstr = textdistance::str::lcsstr(id, de);
|
|
||||||
lcsstr as f32 / (max(id.len(), de.len())) as f32
|
|
||||||
};
|
|
||||||
|
|
||||||
fn max_f32(a: f32, b: f32) -> f32 {
|
|
||||||
if a > b {
|
|
||||||
return a;
|
|
||||||
} else {
|
|
||||||
b
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let id = id.to_lowercase();
|
|
||||||
let de_id = de.appid.to_lowercase();
|
|
||||||
let de_wm_class = de.startup_wm_class().unwrap_or_default().to_lowercase();
|
|
||||||
let de_name = de.name(None).unwrap_or_default().to_lowercase();
|
|
||||||
|
|
||||||
return max_f32(
|
|
||||||
cmp(&id, &de_id),
|
|
||||||
max_f32(cmp(&id, &de_wm_class), cmp(&id, &de_name)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn load_applications_for_app_ids<'a, 'b>(
|
pub fn load_applications_for_app_ids<'a, 'b>(
|
||||||
locale: impl Into<Option<&'a str>>,
|
locale: impl Into<Option<&'a str>>,
|
||||||
app_ids: impl Iterator<Item = &'b str>,
|
app_ids: impl Iterator<Item = &'b str>,
|
||||||
fill_missing_ones: bool,
|
fill_missing_ones: bool,
|
||||||
include_no_display: bool,
|
include_no_display: bool,
|
||||||
) -> Vec<DesktopEntryData> {
|
) -> Vec<DesktopEntryData> {
|
||||||
// need to be owned
|
let mut app_ids = app_ids.collect::<Vec<_>>();
|
||||||
let all_desktop_entries_string =
|
let mut applications = load_applications_filtered(locale, |de| {
|
||||||
freedesktop_desktop_entry::Iter::new(freedesktop_desktop_entry::default_paths())
|
if !include_no_display && de.no_display() {
|
||||||
.filter_map(|path| {
|
return false;
|
||||||
std::fs::read_to_string(&path)
|
|
||||||
.ok()
|
|
||||||
.map(|content| (path, content))
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let all_desktop_entries = all_desktop_entries_string
|
|
||||||
.iter()
|
|
||||||
.filter_map(|(path, content)| DesktopEntry::decode(&path, &content).ok())
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let mut applications = Vec::new();
|
|
||||||
let mut missing = Vec::new();
|
|
||||||
|
|
||||||
let locale = locale.into();
|
|
||||||
|
|
||||||
for id in app_ids {
|
|
||||||
let mut max_score = None;
|
|
||||||
let mut second_max_score = 0.;
|
|
||||||
|
|
||||||
for de in &all_desktop_entries {
|
|
||||||
if !include_no_display && de.no_display() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let score = match_entry(id, de);
|
|
||||||
|
|
||||||
match max_score {
|
|
||||||
Some((prev_max_score, _)) => {
|
|
||||||
if prev_max_score < score {
|
|
||||||
second_max_score = prev_max_score;
|
|
||||||
max_score = Some((score, de));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
max_score = Some((score, de));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if score > 0.99 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// If appid matches, or startup_wm_class matches...
|
||||||
let mut add_missing = false;
|
if let Some(i) = app_ids.iter().position(|id| {
|
||||||
match max_score {
|
id == &de.appid
|
||||||
Some((max_score, de)) => {
|
|| id
|
||||||
let entropy = max_score - second_max_score;
|
.to_lowercase()
|
||||||
|
.eq(&de.startup_wm_class().unwrap_or_default().to_lowercase())
|
||||||
if max_score > 0.7 || entropy > 0.2 && max_score > 0.2 {
|
}) {
|
||||||
applications.push(DesktopEntryData::from_desktop_entry(
|
app_ids.remove(i);
|
||||||
locale,
|
true
|
||||||
Some(de.path.to_path_buf()),
|
// Fallback: If the name matches...
|
||||||
de,
|
} else if let Some(i) = app_ids.iter().position(|id| {
|
||||||
));
|
de.name(None)
|
||||||
} else {
|
.map(|n| n.to_lowercase() == id.to_lowercase())
|
||||||
add_missing = true;
|
.unwrap_or_default()
|
||||||
}
|
}) {
|
||||||
}
|
app_ids.remove(i);
|
||||||
None => {
|
true
|
||||||
add_missing = true;
|
} else {
|
||||||
}
|
false
|
||||||
}
|
}
|
||||||
|
});
|
||||||
if fill_missing_ones && add_missing {
|
|
||||||
missing.push(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if fill_missing_ones {
|
if fill_missing_ones {
|
||||||
applications.extend(missing.into_iter().map(|app_id| DesktopEntryData {
|
applications.extend(app_ids.into_iter().map(|app_id| DesktopEntryData {
|
||||||
id: app_id.to_string(),
|
id: app_id.to_string(),
|
||||||
name: app_id.to_string(),
|
name: app_id.to_string(),
|
||||||
icon: IconSource::default(),
|
icon: IconSource::default(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
applications
|
applications
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -218,7 +141,7 @@ pub fn load_applications_filtered<'a, F: FnMut(&DesktopEntry) -> bool>(
|
||||||
Some(DesktopEntryData::from_desktop_entry(
|
Some(DesktopEntryData::from_desktop_entry(
|
||||||
locale,
|
locale,
|
||||||
path.clone(),
|
path.clone(),
|
||||||
&de,
|
de,
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
@ -234,7 +157,7 @@ pub fn load_desktop_file<'a>(
|
||||||
std::fs::read_to_string(path).ok().and_then(|input| {
|
std::fs::read_to_string(path).ok().and_then(|input| {
|
||||||
DesktopEntry::decode(path, &input)
|
DesktopEntry::decode(path, &input)
|
||||||
.ok()
|
.ok()
|
||||||
.map(|de| DesktopEntryData::from_desktop_entry(locale, PathBuf::from(path), &de))
|
.map(|de| DesktopEntryData::from_desktop_entry(locale, PathBuf::from(path), de))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -242,7 +165,7 @@ impl DesktopEntryData {
|
||||||
fn from_desktop_entry<'a>(
|
fn from_desktop_entry<'a>(
|
||||||
locale: impl Into<Option<&'a str>>,
|
locale: impl Into<Option<&'a str>>,
|
||||||
path: impl Into<Option<PathBuf>>,
|
path: impl Into<Option<PathBuf>>,
|
||||||
de: &DesktopEntry,
|
de: DesktopEntry,
|
||||||
) -> DesktopEntryData {
|
) -> DesktopEntryData {
|
||||||
let locale = locale.into();
|
let locale = locale.into();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue