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 llimphi-ui/Cargo.toml TOML · 183 líneas · 8.5 KB Historia crudo

chore: refresco desde el monorepo — 132 miembros, 79 widgets, la galería vuelve y licencia dual d8edd9a9c · Sergio ·

1[package]
2name = "llimphi-ui"
3version.workspace = true
4edition.workspace = true
5license.workspace = true
6authors.workspace = true
7publish.workspace = true
8
9description = "Native Rust UI framework: retained-mode View<Msg> Elm loop over vello + wgpu + taffy + parley."
10repository.workspace = true
11[dependencies]
12# El trait de despacho. `Handle` lo implementa para que animar —y cualquier otra
13# cosa que sólo quiera mandar un `Msg`— deje de arrastrar el bucle de escritorio
14# entero. Ver `llimphi-despacho`.
15llimphi-despacho = { path = "../llimphi-despacho", version = "0.1.0" }
16llimphi-hal = { path = "../llimphi-hal", version = "0.1.0" }
17llimphi-layout = { path = "../llimphi-layout", version = "0.1.0" }
18llimphi-raster = { path = "../llimphi-raster", version = "0.1.0" }
19# `default-features = false` en los dos que conmutan de backend: sus defaults
20# encienden el perfil `vello`, que es EXCLUYENTE del `cpu` que pide la feature
21# `hybrid`. Las features del perfil normal se listan explícitas abajo.
22llimphi-text = { path = "../llimphi-text", version = "0.1.0", default-features = false }
23# El compositor declarativo (winit-free): View, mount, paint, hit-test.
24llimphi-compositor = { path = "../llimphi-compositor", version = "0.1.0", default-features = false }
25pollster = { workspace = true }
26# Árbol de accesibilidad por frame (NVDA/VoiceOver/Orca/TalkBack). Lo
27# alimentamos desde `View::semantics` + el árbol Mounted. `accesskit_winit`
28# es el adapter que conecta el árbol a la API nativa del SO vía winit.
29accesskit = { workspace = true }
30accesskit_winit = { workspace = true }
31# Reloj monotónico portable. En cualquier target NATIVO `web_time::Instant` es
32# literalmente un re-export de `std::time::Instant` — coste cero, mismo tipo,
33# mismo comportamiento. En wasm32 se apoya en `performance.now()`, donde
34# `std::time::Instant::now()` PANICA («time not implemented on this platform»).
35# Es además el tipo con el que winit tipa `ControlFlow::WaitUntil` en web, así
36# que unificarlo acá arregla el reloj y el borde con winit de una vez.
37# Reexportado como `llimphi_ui::Instant`; dentro del crate se usa `crate::Instant`.
38web-time = "1"
39# Portapapeles del sistema para copiar texto seleccionado fuera del editor
40# (Ctrl/Cmd+C). Best-effort: si no hay backend (headless) degrada a no-op sin
41# panicar. Feature `clipboard` (default) para que builds sin display puedan
42# apagarlo con --no-default-features. En Android y en wasm arboard no existe:
43# la dep va target-gated y `copy_to_clipboard` es no-op aunque la feature esté
44# activa (en el navegador el portapapeles es `navigator.clipboard`, asíncrono y
45# detrás de un gesto del usuario — otro camino, no arboard).
46[target.'cfg(all(not(target_os = "android"), not(target_arch = "wasm32")))'.dependencies]
47arboard = { workspace = true, optional = true }
48
49# Pista `wp_content_type_v1` (ver `src/content_type.rs`): winit no habla ese
50# protocolo, así que se monta una conexión wayland-client sobre el MISMO
51# `wl_display` que ya abrió winit (`Backend::from_foreign_display`) y se envuelve
52# su `wl_surface` por `ObjectId::from_ptr`. Es el cruce winit↔wayland-client
53# ajeno que validó el spike `llimphi-video-plane`. Sólo Linux: en macOS/Windows
54# no hay Wayland y el módulo cae a un no-op.
55[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
56# Sólo con la feature `config-wawa` (ver [features]). Fuera de wasm: en el
57# navegador no hay bus de config del SO que leer.
58
59
60[target.'cfg(unix)'.dependencies]
61# El protocolo de dormir (ver `src/dormir.rs`): un socket Unix por el que mirada
62# le pide a la app que guarde su estado y se vaya. Sólo donde hay sockets Unix.
63llimphi-dormir = { workspace = true }
64
65[target.'cfg(target_os = "linux")'.dependencies]
66# `pipe2` + `poll`: el hilo del puente de soltar-archivos duerme sobre DOS fds
67# (el socket de wayland y un despertador) para que se lo pueda apagar antes de
68# que winit cierre el display. Ver `src/file_drop.rs`.
69libc = { workspace = true }
70wayland-client = "0.31"
71wayland-backend = { version = "0.3", features = ["client_system"] }
72# `staging`: content-type-v1 todavía vive en staging/ del repo de protocolos.
73wayland-protocols = { version = "0.32", features = ["client", "staging"] }
74
75[target.'cfg(target_os = "android")'.dependencies]
76# Logging a logcat: en Android eprintln! va a /dev/null; los errores del
77# runtime (event loop, GPU) salen por `log` (la app instala android_logger).
78log = "0.4"
79
80[target.'cfg(target_arch = "wasm32")'.dependencies]
81# El runtime web (`run_web`). `spawn_local` lanza el arranque asíncrono del
82# `Hal`; `web-sys` da el `<canvas>` del documento y la consola (en wasm
83# `eprintln!` no va a ningún lado); `wasm-bindgen` da el `JsCast` para bajar de
84# `Element` a `HtmlCanvasElement`.
85wasm-bindgen = "0.2"
86wasm-bindgen-futures = "0.4"
87web-sys = { version = "0.3", features = [
88    "console",
89    "Document",
90    "Element",
91    "HtmlCanvasElement",
92    "Window",
93] }
94
95[features]
96default = ["clipboard", "vello"]
97clipboard = ["dep:arboard"]
98# El perfil normal: rasterizado con vello y todo lo que cuelga de él (fuentes
99# del sistema, GPU directa). Es el default; `hybrid` es su alternativa.
100vello = ["llimphi-text/vello", "llimphi-text/system", "llimphi-compositor/vello", "llimphi-compositor/system", "llimphi-compositor/gpu"]
101# Rasteriza con vello_hybrid (CPU+GPU, SIN compute shaders) en vez de vello.
102#
103# **No es una preferencia de rendimiento: es el único camino a píxeles en GPUs
104# cuyo compilador de shaders no digiere el compute de vello.** El Mali-G57 del
105# Redmi de pruebas pierde el device en el primer cuadro por Vulkan y aborta por
106# GLES; con este perfil y `Backends::GL` pinta a 119 fps. La matriz completa
107# está en `02_ruway/llimphi/android/DIAGNOSTICO.md`.
108#
109# Enciende el perfil `cpu` de text y compositor —los que pintan en una `Escena`
110# grabada en vez de en una `vello::Scene`— y el backend hybrid del rasterizador.
111# Los tres tienen que ir juntos: son el mismo tipo de escena visto desde tres
112# crates, y `llimphi-text` lleva un `compile_error!` que delata la mezcla.
113#
114# Cuesta el hook de GPU directa (`View::gpu_paint_with`): vive en la feature
115# `gpu` del compositor, que implica el backend vello porque encima una pasada
116# de wgpu sobre la `vello::Scene`. Una app que lo use no puede ir por acá.
117hybrid = [
118    "llimphi-raster/hybrid",
119    "llimphi-text/cpu",
120    "llimphi-text/std",
121    "llimphi-text/system",
122    "llimphi-compositor/cpu",
123    "llimphi-compositor/std",
124    "llimphi-compositor/system",
125]
126# Instala `alloc::ContadorAlloc` como `#[global_allocator]` del binario para
127# que `LLIMPHI_PERF` reporte asignaciones/bytes por frame (Bloque 21). OFF por
128# defecto: cuenta con dos `fetch_add` relajados por asignación, y un runtime no
129# le impone el allocator a nadie sin que lo pidan.
130perf-alloc = []
131# Lee el **sentido de la rueda** (ratón / touchpad, por separado) del bus de
132# config del SO wawa y lo fija al arrancar, con watcher para el cambio en
133# caliente. OFF por defecto porque `llimphi-ui` es toolkit y `wawa-config` es el
134# bus de un sistema operativo concreto: el toolkit publicable no puede depender
135# de él. En tawasuyu la enciende el `[workspace.dependencies]` de la raíz, así
136# que TODAS las apps del monorepo obedecen la misma config sin tocar una línea.
137config-wawa = []
138
139[[example]]
140name = "content_type"
141path = "examples/content_type.rs"
142
143[[example]]
144name = "counter"
145path = "examples/counter.rs"
146
147# El mismo counter, en el navegador. `cdylib` porque es lo que wasm-bindgen
148# necesita; en targets nativos el archivo entero está bajo
149# `#![cfg(target_arch = "wasm32")]`, así que queda una biblioteca vacía y
150# `cargo check --workspace --examples` lo cubre sin ruido.
151[[example]]
152name = "counter_web"
153path = "examples/counter_web.rs"
154crate-type = ["cdylib"]
155
156[[example]]
157name = "editor"
158path = "examples/editor.rs"
159
160[[example]]
161name = "gpu_paint_demo"
162path = "examples/gpu_paint_demo.rs"
163
164[[example]]
165name = "gestos"
166path = "examples/gestos.rs"
167
168# Instrumento del auto-repeat: `view()` duerme a propósito para que un toque de
169# tecla caiga entero dentro de un cuadro. Ver el encabezado del archivo.
170[[example]]
171name = "melaza_teclas"
172path = "examples/melaza_teclas.rs"
173
174[[example]]
175name = "selectable_text"
176path = "examples/selectable_text.rs"
177
178[dev-dependencies]
179# El consumidor de AccessKit — lo que corre del OTRO lado del adapter cuando un
180# lector de pantalla se activa. Está acá sólo para el test: es el único oráculo
181# que dice si el árbol que publicamos se puede publicar de verdad. Sin él, un
182# `TreeUpdate` inválido no se descubre hasta que alguien enciende Orca.
183accesskit_consumer = "0.36"