This commit is contained in:
Javier Feliz 2025-09-03 17:51:18 -04:00
parent 36a5f1b85f
commit 3f6de3806f

View File

@ -1,4 +1,5 @@
use gio::prelude::*; use gio::prelude::*;
use gio::{File, FileIcon, Icon as GioIcon, ThemedIcon};
use gtk::{ use gtk::{
Application, ApplicationWindow, Box as GtkBox, Entry, Image, Label, ListBox, Orientation, Application, ApplicationWindow, Box as GtkBox, Entry, Image, Label, ListBox, Orientation,
ScrolledWindow, ScrolledWindow,
@ -52,8 +53,66 @@ impl ListItem {
let display = gtk::gdk::Display::default().unwrap(); let display = gtk::gdk::Display::default().unwrap();
let icon_theme = gtk::IconTheme::for_display(&display); let icon_theme = gtk::IconTheme::for_display(&display);
// Get current paths and filter out problematic ones
let current_paths = icon_theme.search_path();
let clean_pathbufs: Vec<_> = current_paths
.into_iter()
.filter(|path| {
let path_str = path.to_string_lossy();
// Keep user paths, flatpak, and system paths - remove nix store
!path_str.starts_with("/nix/store/")
// !path_str.contains("patchelf") &&
// !path_str.contains("vscode-1.") && // Individual app store paths
// !path_str.contains("gsettings-desktop-schemas")
})
.collect();
// Convert to &Path references for the API
let clean_paths: Vec<&std::path::Path> =
clean_pathbufs.iter().map(|p| p.as_path()).collect();
println!("Filtered paths:");
for path in &clean_paths {
println!(" {}", path.to_string_lossy());
}
// Set the clean path list
icon_theme.set_search_path(&clean_paths);
if let Ok(gicon) = GioIcon::for_string(&self.icon) {
// Check if it's a file icon (absolute path)
if let Some(file_icon) = gicon.downcast_ref::<gio::FileIcon>() {
let file = file_icon.file();
if let Some(path) = file.path() {
if path.exists() {
println!("Loading file icon: {:?}", path);
// return gtk::Image::from_file(path);
}
}
}
// Check if it's a themed icon
if let Some(themed_icon) = gicon.downcast_ref::<gio::ThemedIcon>() {
let icon_names = themed_icon.names();
for name in &icon_names {
if icon_theme.has_icon(name) {
println!("Found themed icon: {}", name);
// let paintable = icon_theme.lookup_icon(
// name,
// &[], // Empty fallback array - let GTK handle it
// icon_size,
// scale,
// gtk::TextDirection::None,
// IconLookupFlags::empty(),
// );
// return Image::from_paintable(Some(&paintable));
}
}
}
}
let scale = container.scale_factor(); let scale = container.scale_factor();
let icon_size = 48; let icon_size = 48;
let lookup_flags = IconLookupFlags::empty();
let image = if icon_theme.has_icon(&self.icon) { let image = if icon_theme.has_icon(&self.icon) {
println!("Has icon: {}", self.icon); println!("Has icon: {}", self.icon);
let paintable = icon_theme.lookup_icon( let paintable = icon_theme.lookup_icon(
@ -62,8 +121,11 @@ impl ListItem {
icon_size, icon_size,
scale, scale,
gtk::TextDirection::None, gtk::TextDirection::None,
IconLookupFlags::empty(), lookup_flags,
); );
if let Some(icon_name) = paintable.icon_name() {
println!("Got icon name: {}", icon_name.to_string_lossy());
}
gtk::Image::from_paintable(Some(&paintable)) gtk::Image::from_paintable(Some(&paintable))
} else { } else {
println!("No icon: {}", self.icon); println!("No icon: {}", self.icon);
@ -161,6 +223,30 @@ impl AppModel {
// let display = gtk::gdk::Display::default().unwrap(); // let display = gtk::gdk::Display::default().unwrap();
// let icon_theme = gtk::IconTheme::for_display(&display); // let icon_theme = gtk::IconTheme::for_display(&display);
// Get current paths and filter out problematic ones
// let current_paths = icon_theme.search_path();
// let clean_pathbufs: Vec<_> = current_paths
// .into_iter()
// .filter(|path| {
// let path_str = path.to_string_lossy();
// // Keep user paths, flatpak, and system paths - remove nix store
// !path_str.starts_with("/nix/store/")
// // !path_str.contains("patchelf") &&
// // !path_str.contains("vscode-1.") && // Individual app store paths
// // !path_str.contains("gsettings-desktop-schemas")
// })
// .collect();
// // Convert to &Path references for the API
// let clean_paths: Vec<&std::path::Path> =
// clean_pathbufs.iter().map(|p| p.as_path()).collect();
// println!("Filtered paths:");
// for path in &clean_paths {
// println!(" {}", path.to_string_lossy());
// }
// // Set the clean path list
// icon_theme.set_search_path(&clean_paths);
// for p in icon_theme.search_path() { // for p in icon_theme.search_path() {
// println!("{}", p.to_string_lossy()); // println!("{}", p.to_string_lossy());
@ -189,21 +275,249 @@ impl AppModel {
} }
} }
fn main() { // fn find_icon_file_directly(icon_name: &str) -> Option<std::path::PathBuf> {
let app = Application::builder() // // Search in the filtered paths manually, bypassing GTK entirely
.application_id("dev.thegrind.waycast") // let search_paths = [
.build(); // "/home/javi/.local/share/icons",
// "/home/javi/.icons",
// "/home/javi/.local/share/flatpak/exports/share/icons",
// "/var/lib/flatpak/exports/share/icons",
// "/home/javi/.nix-profile/share/icons",
// "/nix/profile/share/icons",
// "/home/javi/.local/state/nix/profile/share/icons",
// "/etc/profiles/per-user/javi/share/icons",
// "/nix/var/nix/profiles/default/share/icons",
// "/run/current-system/sw/share/icons",
// "/home/javi/.local/share/flatpak/exports/share/pixmaps",
// "/var/lib/flatpak/exports/share/pixmaps",
// "/home/javi/.nix-profile/share/pixmaps",
// "/nix/profile/share/pixmaps",
// "/home/javi/.local/state/nix/profile/share/pixmaps",
// "/etc/profiles/per-user/javi/share/pixmaps",
// "/nix/var/nix/profiles/default/share/pixmaps",
// "/run/current-system/sw/share/pixmaps",
// ];
app.connect_activate(|app| { // let sizes = ["48", "64", "32", "scalable"];
let model = AppModel::new(app); // let categories = ["apps", "applications"];
model.borrow().show(); // let extensions = ["png", "svg", "xpm"];
});
app.run(); // for base_path in &search_paths {
// for e in drun::get_desktop_entries() { // let base = std::path::Path::new(base_path);
// println!("---"); // if !base.exists() {
// println!("Icon: {}", e.icon()); // continue;
// println!("Path: {}", e.path().to_string_lossy());
// println!("---");
// } // }
// // First try: direct pixmaps
// for ext in &extensions {
// let direct = base.join("pixmaps").join(format!("{}.{}", icon_name, ext));
// if direct.exists() {
// println!("Found direct pixmap: {:?}", direct);
// return Some(direct);
// }
// }
// // Second try: theme structure
// if let Ok(theme_dirs) = std::fs::read_dir(base) {
// for theme_entry in theme_dirs.flatten() {
// println!(
// "theme: {} in {}",
// theme_entry.file_name().to_string_lossy(),
// base.to_string_lossy()
// );
// let is_dir = theme_entry.metadata().map(|m| m.is_dir()).unwrap_or(false);
// if !is_dir {
// println!(
// "Skipping cuz not dir: {}",
// theme_entry.file_name().to_string_lossy()
// );
// continue;
// }
// let theme_path = theme_entry.path();
// for size in &sizes {
// for category in &categories {
// for ext in &extensions {
// let icon_path = theme_path
// .join(size)
// .join(category)
// .join(format!("{}.{}", icon_name, ext));
// if icon_path.exists() {
// println!("Found themed icon: {:?}", icon_path);
// return Some(icon_path);
// }
// }
// }
// }
// }
// }
// }
// None
// }
fn find_icon_file(icon_name: &str, size: &str, theme_name: &str) -> Option<std::path::PathBuf> {
let search_paths = [
"/home/javi/.local/share/icons",
"/home/javi/.icons",
"/home/javi/.local/share/flatpak/exports/share/icons",
"/var/lib/flatpak/exports/share/icons",
"/home/javi/.nix-profile/share/icons",
"/nix/profile/share/icons",
"/home/javi/.local/state/nix/profile/share/icons",
"/etc/profiles/per-user/javi/share/icons",
"/nix/var/nix/profiles/default/share/icons",
"/run/current-system/sw/share/icons",
];
let pixmap_paths = [
"/home/javi/.local/share/flatpak/exports/share/pixmaps",
"/var/lib/flatpak/exports/share/pixmaps",
"/home/javi/.nix-profile/share/pixmaps",
"/nix/profile/share/pixmaps",
"/home/javi/.local/state/nix/profile/share/pixmaps",
"/etc/profiles/per-user/javi/share/pixmaps",
"/nix/var/nix/profiles/default/share/pixmaps",
"/run/current-system/sw/share/pixmaps",
];
let sizes = ["48", "64", "32", "scalable"];
let categories = ["apps", "applications", "mimetypes"];
let extensions = ["png", "svg", "xpm"];
// First, search pixmaps directly (no subdirectories)
for pixmap_path in &pixmap_paths {
let base = std::path::Path::new(pixmap_path);
if !base.exists() {
continue;
}
for ext in &extensions {
let direct_icon = base.join(format!("{}.{}", icon_name, ext));
if direct_icon.exists() {
println!("Found direct pixmap: {:?}", direct_icon);
return Some(direct_icon);
}
}
}
// Then search icon theme directories
for base_path in &search_paths {
let base = std::path::Path::new(base_path);
if !base.exists() {
continue;
}
if let Ok(theme_dirs) = std::fs::read_dir(base) {
for theme_entry in theme_dirs.flatten() {
let theme_name = theme_entry.file_name().to_string_lossy().to_string();
println!(
"Checking theme: {} in {}",
theme_name,
base.to_string_lossy()
);
let is_dir = theme_entry.path().is_dir();
if !is_dir {
println!("Skipping no dir");
continue; // Skip files in icon directories
}
let theme_path = theme_entry.path();
for size in &sizes {
for category in &categories {
println!(
"{}",
theme_path
.join(format!("{}x{}", size, size))
.join(category)
.to_string_lossy()
);
for ext in &extensions {
let icon_path = theme_path
.join(format!("{}x{}", size, size))
.join(category)
.join(format!("{}.{}", icon_name, ext));
if icon_path.exists() {
println!("Found themed icon: {:?}", icon_path);
return Some(icon_path);
}
}
}
}
}
}
}
None
}
fn main() {
// let app = Application::builder()
// .application_id("dev.thegrind.waycast")
// .build();
// app.connect_activate(|app| {
// let model = AppModel::new(app);
// model.borrow().show();
// });
// app.run();
// for info in gio::AppInfo::all() {
// if !info.should_show() {
// continue;
// }
// println!("App: {}", info.display_name());
// if let Some(icon) = info.icon() {
// if let Some(x) = icon.to_string() {
// println!("Printed: {}", x.to_string());
// }
// if let Ok(ti) = icon.clone().downcast::<gio::ThemedIcon>() {
// // ThemedIcon may have multiple names, we take the first
// if let Some(name) = ti.names().first() {
// println!("Themed: {}", name.to_string());
// }
// }
// if let Ok(fi) = icon.clone().downcast::<gio::FileIcon>() {
// if let Some(path) = fi.file().path() {
// println!("File: {}", path.to_string_lossy().to_string());
// }
// }
// }
// println!("\n");
// }
// let scale = 1;
// let icon_size = 48;
// let lookup_flags = IconLookupFlags::empty();
// let icon = gio::ThemedIcon::new("vscode");
// let finded = icon_theme.lookup_by_gicon(
// &icon,
// icon_size,
// scale,
// gtk::TextDirection::None,
// lookup_flags,
// );
// let appinfo = gio::AppInfo::all();
gtk::init().expect("Failed to init GTK");
let display = gtk::gdk::Display::default().unwrap();
let icon_theme = gtk::IconTheme::for_display(&display);
// for i in icon_theme.icon_names() {
// println!("Icon: {}", i);
// for s in icon_theme.icon_sizes(i) {
// println!("- {}", s);
// }
// }
println!("Current icon theme: {:?}", icon_theme.theme_name());
if let Some(path) = find_icon_file_directly("application-x-trash") {
println!("Found at: {}", path.to_string_lossy());
} else {
println!("Not working");
}
} }