use freedesktop instead of gtk
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
use gio::prelude::{AppInfoExt, IconExt};
|
||||
use gtk::traits::IconThemeExt;
|
||||
use freedesktop::{ApplicationEntry, IconTheme};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
// compatibility with wayvr-ipc
|
||||
@@ -31,6 +30,8 @@ pub struct EntrySearchCell {
|
||||
pub categories: Vec<String>,
|
||||
}
|
||||
|
||||
const ICON_SIZE: u32 = 128;
|
||||
|
||||
const CMD_BLACKLIST: [&str; 1] = [
|
||||
"lsp-plugins", // LSP Plugins collection. They clutter the application list a lot
|
||||
];
|
||||
@@ -38,45 +39,32 @@ const CMD_BLACKLIST: [&str; 1] = [
|
||||
const CATEGORY_TYPE_BLACKLIST: [&str; 5] = ["GTK", "Qt", "X-XFCE", "X-Bluetooth", "ConsoleOnly"];
|
||||
|
||||
pub fn find_entries() -> anyhow::Result<Vec<DesktopEntry>> {
|
||||
let Some(icon_theme) = gtk::IconTheme::default() else {
|
||||
anyhow::bail!("Failed to get current icon theme information");
|
||||
};
|
||||
|
||||
let mut res = Vec::<DesktopEntry>::new();
|
||||
let theme = IconTheme::current();
|
||||
|
||||
let info = gio::AppInfo::all();
|
||||
|
||||
log::debug!("app entry count {}", info.len());
|
||||
|
||||
'outer: for app_entry in info {
|
||||
'outer: for app_entry in ApplicationEntry::all() {
|
||||
let Some(app_entry_id) = app_entry.id() else {
|
||||
log::warn!(
|
||||
"failed to get desktop entry ID for application named \"{}\"",
|
||||
app_entry.name()
|
||||
"No desktop entry id for application \"{}\"",
|
||||
app_entry.name().as_deref().unwrap_or("")
|
||||
);
|
||||
continue;
|
||||
};
|
||||
|
||||
let Some(desktop_app) = gio::DesktopAppInfo::new(&app_entry_id) else {
|
||||
log::warn!(
|
||||
"failed to find desktop app file from application named \"{}\"",
|
||||
app_entry.name()
|
||||
);
|
||||
let Some(name) = app_entry.name() else {
|
||||
log::warn!("No Name on desktop entry {}", app_entry_id);
|
||||
continue;
|
||||
};
|
||||
|
||||
if desktop_app.is_nodisplay() || desktop_app.is_hidden() {
|
||||
let Some(exec) = app_entry.exec() else {
|
||||
log::warn!("No Exec on desktop entry {}", app_entry_id);
|
||||
continue;
|
||||
};
|
||||
|
||||
if app_entry.no_display() || app_entry.is_hidden() || app_entry.terminal() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let Some(cmd) = desktop_app.commandline() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let name = String::from(desktop_app.name());
|
||||
|
||||
let exec = String::from(cmd.to_string_lossy());
|
||||
|
||||
for blacklisted in CMD_BLACKLIST {
|
||||
if exec.contains(blacklisted) {
|
||||
continue 'outer;
|
||||
@@ -95,37 +83,17 @@ pub fn find_entries() -> anyhow::Result<Vec<DesktopEntry>> {
|
||||
None => (exec, Vec::new()),
|
||||
};
|
||||
|
||||
let icon_path = match desktop_app.icon() {
|
||||
Some(icon) => {
|
||||
if let Some(icon_str) = icon.to_string() {
|
||||
if let Some(s_icon) = icon_theme.lookup_icon(&icon_str, 128, gtk::IconLookupFlags::GENERIC_FALLBACK) {
|
||||
s_icon.filename().map(|p| String::from(p.to_string_lossy()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
let icon_path = app_entry
|
||||
.icon()
|
||||
.and_then(|icon_name| theme.get_with_size(&icon_name, ICON_SIZE))
|
||||
.and_then(|path_buf| path_buf.into_os_string().into_string().ok());
|
||||
|
||||
let categories: Vec<String> = match desktop_app.categories() {
|
||||
Some(categories) => categories
|
||||
.split(";")
|
||||
.filter(|s| !s.is_empty())
|
||||
.filter(|s| {
|
||||
for b in CATEGORY_TYPE_BLACKLIST {
|
||||
if *s == b {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
})
|
||||
.map(String::from)
|
||||
.collect(),
|
||||
None => Vec::new(),
|
||||
};
|
||||
let categories = app_entry.categories().map_or_else(Vec::default, |inner| {
|
||||
inner
|
||||
.into_iter()
|
||||
.filter(|s| !(s.is_empty() || CATEGORY_TYPE_BLACKLIST.contains(&s.as_str())))
|
||||
.collect()
|
||||
});
|
||||
|
||||
let entry = DesktopEntry {
|
||||
app_name: name,
|
||||
|
||||
Reference in New Issue
Block a user