srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/wayland/src/desktop_icons.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/wayland/src/desktop_icons.rs')
-rw-r--r--crates/wayland/src/desktop_icons.rs52
1 files changed, 33 insertions, 19 deletions
diff --git a/crates/wayland/src/desktop_icons.rs b/crates/wayland/src/desktop_icons.rs
index 470a965..4ba54f4 100644
--- a/crates/wayland/src/desktop_icons.rs
+++ b/crates/wayland/src/desktop_icons.rs
@@ -85,17 +85,6 @@ fn desktop_dir(home: &Path) -> PathBuf {
home.join("Desktop")
}
-/// `$XDG_DATA_HOME/Trash/files`, else `~/.local/share/Trash/files` - the
-/// freedesktop.org Trash spec's home-filesystem trash directory. Only the
-/// same-filesystem case is handled anywhere in this codebase (see this
-/// feature's own plan doc for why the per-mountpoint `.Trash-$uid`
-/// fallback is out of scope for now); this is purely where the Trash
-/// desktop icon opens to, nothing currently moves a file into it.
-fn trash_files_dir(home: &Path) -> PathBuf {
- let data_home = std::env::var("XDG_DATA_HOME").map(PathBuf::from).unwrap_or_else(|_| home.join(".local/share"));
- data_home.join("Trash/files")
-}
-
/// Rebuilds the full icon list from the real filesystem: the three fixed
/// icons first, then one per direct, non-hidden entry of `~/Desktop`
/// (creating that directory if it doesn't exist yet, matching how a real
@@ -132,7 +121,7 @@ pub(crate) fn rescan(saved: &HashMap<String, (i32, i32)>, rows_per_column: i32)
id: "trash".to_string(),
label: "Trash".to_string(),
kind: IconKind::Trash,
- target: home_dir().map(|h| trash_files_dir(&h)).unwrap_or_else(|| PathBuf::from("/")),
+ target: home_dir().map(|h| crate::trash::files_dir(&h)).unwrap_or_else(|| PathBuf::from("/")),
cell: (0, 0),
selected: false,
},
@@ -141,7 +130,7 @@ pub(crate) fn rescan(saved: &HashMap<String, (i32, i32)>, rows_per_column: i32)
let desktop = desktop_dir(&home);
if std::fs::create_dir_all(&desktop).is_ok() {
if let Ok(entries) = std::fs::read_dir(&desktop) {
- let mut files: Vec<(String, bool)> = entries
+ let files: Vec<(String, bool)> = entries
.filter_map(|e| e.ok())
.filter_map(|e| {
let name = e.file_name().to_string_lossy().into_owned();
@@ -152,7 +141,6 @@ pub(crate) fn rescan(saved: &HashMap<String, (i32, i32)>, rows_per_column: i32)
Some((name, is_dir))
})
.collect();
- files.sort_by(|a, b| a.0.cmp(&b.0));
for (name, is_dir) in files {
let target = desktop.join(&name);
icons.push(DesktopIcon {
@@ -167,6 +155,14 @@ pub(crate) fn rescan(saved: &HashMap<String, (i32, i32)>, rows_per_column: i32)
}
}
}
+ // One alphabetical list, fixed icons included - not fixed-three-then-
+ // files. Confirmed directly: the fixed shortcuts shouldn't always come
+ // first just because they're synthetic rather than real files.
+ // Case-insensitive so "computer"/"Computer" and a real lowercase
+ // filename interleave the way a user actually expects, not by raw
+ // byte value (which would put every uppercase name before any
+ // lowercase one).
+ icons.sort_by_key(|a| a.label.to_lowercase());
assign_cells(&mut icons, saved, rows_per_column);
icons
}
@@ -212,12 +208,30 @@ mod tests {
use super::*;
#[test]
- fn fixed_icons_always_come_first_in_a_stable_order() {
+ fn the_three_fixed_icons_sort_alphabetically_among_themselves() {
+ // Reported live, confirmed via direct question: fixed icons must
+ // NOT always come before real files just because they're
+ // synthetic - the whole list sorts by label together. This
+ // checks that sort using only the three fixed icons (present on
+ // any machine, unlike a specific `~/Desktop` file), whose labels
+ // - "Computer", "Home", "Trash" - already happen to be in
+ // alphabetical order, so a correct sort leaves them exactly
+ // where `rescan` built them.
let icons = rescan(&HashMap::new(), 10);
- assert!(icons.len() >= 3, "at least the three fixed icons");
- assert_eq!(icons[0].id, "home");
- assert_eq!(icons[1].id, "computer");
- assert_eq!(icons[2].id, "trash");
+ let fixed: Vec<&str> = icons.iter().filter(|i| matches!(i.kind, IconKind::Home | IconKind::Computer | IconKind::Trash)).map(|i| i.label.as_str()).collect();
+ assert_eq!(fixed, vec!["Computer", "Home", "Trash"]);
+ }
+
+ #[test]
+ fn sorting_is_case_insensitive_and_covers_the_whole_list() {
+ let mut icons = [
+ DesktopIcon { id: "zebra".into(), label: "zebra".into(), kind: IconKind::File, target: PathBuf::new(), cell: (0, 0), selected: false },
+ DesktopIcon { id: "Home".into(), label: "Home".into(), kind: IconKind::Home, target: PathBuf::new(), cell: (0, 0), selected: false },
+ DesktopIcon { id: "apple".into(), label: "apple".into(), kind: IconKind::File, target: PathBuf::new(), cell: (0, 0), selected: false },
+ ];
+ icons.sort_by_key(|a| a.label.to_lowercase());
+ let labels: Vec<&str> = icons.iter().map(|i| i.label.as_str()).collect();
+ assert_eq!(labels, vec!["apple", "Home", "zebra"], "a fixed icon's label interleaves with real filenames, not always first");
}
#[test]