tawasuyu

tawasuyu/llimphi

Sovereign retained-mode GPU UI framework in Rust (wgpu+vello+taffy+parley), Elm loop, 40+ widgets.

Rust 660Markdown 302TOML 157RON 312382 Definiciones

⎇ main widgets/app-icon/examples/diag_iconos.rs Rust · 81 líneas · 3.3 KB Historia Quién tocó qué crudo

chore: refresco desde el monorepo (pin tawasuyu.git v0.3.0) b575c63f1 · Sergio ·

1//! `diag_iconos` — ¿qué ícono le toca a cada `app_id`?
2//!
3//! El instrumento del índice `app_id → Icon= → archivo`. Se le pasan los
4//! `app_id` de Wayland por argumento (los de las ventanas abiertas salen de
5//! `mirada-ctl windows`) y por cada uno imprime la vía por la que resolvió y el
6//! archivo que se va a pintar — o `LETRA`, que es lo que hoy ve el usuario.
7//!
8//! Sin argumentos barre todos los `.desktop` del sistema y da el conteo: cuántas
9//! entradas declaran `StartupWMClass` (las que el `app_id` a pelo NO alcanzaba).
10
11fn main() {
12    let ids: Vec<String> = std::env::args().skip(1).collect();
13    if ids.is_empty() {
14        eprintln!("uso: diag_iconos <app_id> [app_id...]");
15        return;
16    }
17    // Lo que cuesta armar el índice: se arma UNA vez, pero se arma dentro de un
18    // cuadro de UI (el primer ícono que alguien pide), así que el número
19    // importa — un barrido caro ahí es un tirón visible.
20    // `precargar_indice` es la vía SÍNCRONA (la que mide el barrido de verdad);
21    // el camino normal de una app lo arma en un hilo y no bloquea el cuadro.
22    let t0 = std::time::Instant::now();
23    llimphi_widget_app_icon::precargar_indice();
24    let armado = t0.elapsed();
25    let t1 = std::time::Instant::now();
26    let _ = llimphi_widget_app_icon::icon_name_for_app_id("segunda-llamada-ya-cacheada");
27    let cacheado = t1.elapsed();
28    println!("indice: armado {armado:?} · lookup posterior {cacheado:?}\n");
29
30    let (mut por_indice, mut por_directo, mut letra) = (0, 0, 0);
31    // El camino VIEJO, para contrastar: el `app_id` probado como nombre de
32    // ícono a pelo, que es lo único que tenía el dock (y la taskbar ni eso).
33    let mut antes = 0;
34    for id in &ids {
35        let via_indice = llimphi_widget_app_icon::icon_name_for_app_id(id);
36        let nombre = via_indice.clone().unwrap_or_else(|| id.clone());
37        // Un `Icon=` puede ser un **path absoluto** (`/opt/pycharm/bin/x.svg`),
38        // que no se busca en ningún tema. `get_or_load` ya lo contempla; si el
39        // diag no, reporta LETRA sobre un ícono que en realidad se pinta.
40        let ruta = if nombre.starts_with('/') {
41            let p = std::path::PathBuf::from(&nombre);
42            p.is_file().then_some(p)
43        } else {
44            llimphi_widget_app_icon::resolve_icon_path(&nombre)
45        };
46        let via = match (&via_indice, &ruta) {
47            (_, None) => {
48                letra += 1;
49                "LETRA".to_string()
50            }
51            (Some(_), Some(_)) => {
52                por_indice += 1;
53                "indice".to_string()
54            }
55            (None, Some(_)) => {
56                por_directo += 1;
57                "directo".to_string()
58            }
59        };
60        let resolvia_antes = llimphi_widget_app_icon::resolve_icon_path(id).is_some();
61        if resolvia_antes {
62            antes += 1;
63        }
64        println!(
65            "{:<30} {:<7} {:<8} {:<28} {}",
66            id,
67            if resolvia_antes { "antes✓" } else { "antes·" },
68            via,
69            via_indice.as_deref().unwrap_or("—"),
70            ruta.map(|p| p.display().to_string()).unwrap_or_else(|| "—".into())
71        );
72    }
73    println!(
74        "\n{} ids · ANTES resolvia {} · AHORA indice={} directo={} LETRA={}",
75        ids.len(),
76        antes,
77        por_indice,
78        por_directo,
79        letra
80    );
81}