Merge pull request #1330 from Cheong-Lau/item-display-name

perf: optimise `tab::folder_name`
This commit is contained in:
Jeremy Soller 2025-11-11 19:05:46 -07:00 committed by GitHub
commit fa0be29199
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -569,6 +569,36 @@ pub fn fs_kind(_metadata: &Metadata) -> FsKind {
FsKind::Local
}
fn get_desktop_file_display_name(path: &Path) -> Option<String> {
let entry = match freedesktop_entry_parser::parse_entry(path) {
Ok(ok) => ok,
Err(err) => {
log::warn!("failed to parse {}: {}", path.display(), err);
return None;
}
};
entry
.section("Desktop Entry")
.attr("Name")
.map(str::to_string)
}
fn get_desktop_file_icon(path: &Path) -> Option<String> {
let entry = match freedesktop_entry_parser::parse_entry(path) {
Ok(ok) => ok,
Err(err) => {
log::warn!("failed to parse {}: {}", path.display(), err);
return None;
}
};
entry
.section("Desktop Entry")
.attr("Icon")
.map(str::to_string)
}
pub fn parse_desktop_file(path: &Path) -> (Option<String>, Option<String>) {
let entry = match freedesktop_entry_parser::parse_entry(path) {
Ok(ok) => ok,
@ -577,25 +607,33 @@ pub fn parse_desktop_file(path: &Path) -> (Option<String>, Option<String>) {
return (None, None);
}
};
let section = entry.section("Desktop Entry");
(
entry
.section("Desktop Entry")
.attr("Name")
.map(str::to_string),
entry
.section("Desktop Entry")
.attr("Icon")
.map(str::to_string),
section.attr("Name").map(str::to_string),
section.attr("Icon").map(str::to_string),
)
}
fn display_name_for_file(path: &Path, name: &str, get_from_gvfs: bool, is_desktop: bool) -> String {
if is_desktop {
get_desktop_file_display_name(path).map_or_else(
|| Item::display_name(name),
|desktop_name| Item::display_name(desktop_name.as_str()),
)
} else if get_from_gvfs {
Item::display_name(glib::filename_display_name(path).as_str())
} else {
Item::display_name(name)
}
}
#[cfg(feature = "gvfs")]
pub fn item_from_gvfs_info(path: PathBuf, file_info: gio::FileInfo, sizes: IconSizes) -> Item {
let file_name = file_info
.attribute_as_string(gio::FILE_ATTRIBUTE_STANDARD_NAME)
.unwrap_or_default();
let mtime = file_info.attribute_uint64(gio::FILE_ATTRIBUTE_TIME_MODIFIED);
let mut display_name = Item::display_name(&file_info.display_name());
let mut is_desktop = false;
let remote = file_info.boolean(gio::FILE_ATTRIBUTE_FILESYSTEM_REMOTE);
let is_dir = matches!(file_info.file_type(), gio::FileType::Directory);
@ -616,11 +654,8 @@ pub fn item_from_gvfs_info(path: PathBuf, file_info: gio::FileInfo, sizes: IconS
//TODO: clean this up, implement for trash
let icon_name_opt = if mime == "application/x-desktop" {
let (desktop_name_opt, icon_name_opt) = parse_desktop_file(&path);
if let Some(desktop_name) = desktop_name_opt {
display_name = Item::display_name(&desktop_name);
}
icon_name_opt
is_desktop = true;
get_desktop_file_icon(&path)
} else {
None
};
@ -662,6 +697,7 @@ pub fn item_from_gvfs_info(path: PathBuf, file_info: gio::FileInfo, sizes: IconS
}
}
let display_name = display_name_for_file(&path, &file_info.display_name(), false, is_desktop);
let hidden = file_name.starts_with('.');
Item {
@ -701,7 +737,8 @@ pub fn item_from_entry(
metadata: fs::Metadata,
sizes: IconSizes,
) -> Item {
let mut display_name = Item::display_name(&name);
let mut is_desktop = false;
let mut is_gvfs = false;
let hidden = name.starts_with('.') || hidden_attribute(&metadata);
@ -710,20 +747,8 @@ pub fn item_from_entry(
FsKind::Remote => true,
#[cfg(feature = "gvfs")]
FsKind::Gvfs => {
is_gvfs = true;
let file = gio::File::for_path(&path);
match gio::prelude::FileExt::query_info(
&file,
gio::FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
gio::FileQueryInfoFlags::NONE,
gio::Cancellable::NONE,
) {
Ok(info) => {
display_name = Item::display_name(&info.display_name());
}
Err(err) => {
log::warn!("failed to get GIO info for {}: {}", path.display(), err);
}
}
match gio::prelude::FileExt::query_filesystem_info(
&file,
@ -764,11 +789,8 @@ pub fn item_from_entry(
let mime = mime_for_path(&path, Some(&metadata), remote);
//TODO: clean this up, implement for trash
let icon_name_opt = if mime == "application/x-desktop" {
let (desktop_name_opt, icon_name_opt) = parse_desktop_file(&path);
if let Some(desktop_name) = desktop_name_opt {
display_name = Item::display_name(&desktop_name);
}
icon_name_opt
is_desktop = true;
get_desktop_file_icon(&path)
} else {
None
};
@ -810,6 +832,8 @@ pub fn item_from_entry(
}
}
let display_name = display_name_for_file(&path, &name, is_gvfs, is_desktop);
Item {
name,
display_name,
@ -836,9 +860,8 @@ pub fn item_from_entry(
}
}
pub fn item_from_path<P: Into<PathBuf>>(path: P, sizes: IconSizes) -> Result<Item, String> {
let path = path.into();
let name = match path.file_name() {
fn get_filename_from_path(path: &Path) -> Result<String, String> {
Ok(match path.file_name() {
Some(name_os) => name_os
.to_str()
.ok_or_else(|| {
@ -849,7 +872,12 @@ pub fn item_from_path<P: Into<PathBuf>>(path: P, sizes: IconSizes) -> Result<Ite
})?
.to_string(),
None => fl!("filesystem"),
};
})
}
pub fn item_from_path<P: Into<PathBuf>>(path: P, sizes: IconSizes) -> Result<Item, String> {
let path = path.into();
let name = get_filename_from_path(&path)?;
let metadata = fs::metadata(&path)
.map_err(|err| format!("failed to read metadata for {}: {}", path.display(), err))?;
Ok(item_from_entry(path, name, metadata, sizes))
@ -2486,10 +2514,12 @@ fn folder_name<P: AsRef<Path>>(path: P) -> (String, bool) {
found_home = true;
fl!("home")
} else {
// This is not optimized but it helps ensure the same display names
match item_from_path(path, IconSizes::default()) {
Ok(item) => item.display_name,
Err(_err) => name.to_string_lossy().into_owned(),
match (get_filename_from_path(path), fs::metadata(path)) {
(Ok(name), Ok(metadata)) => {
let is_gvfs = fs_kind(&metadata) == FsKind::Gvfs;
display_name_for_file(path, &name, is_gvfs, false)
}
_ => name.to_string_lossy().into_owned(),
}
}
}