Files
brahman/crates/modules/mirada/SDD.md
T
sergio 8204852e3a feat(mirada): keymap configurable en RON, recargable en caliente
Los atajos de teclado dejan de estar cableados: ahora son un Keymap
configurable que vive sólo en el Cerebro. El Cuerpo nunca lo ve — sólo
recibe la lista de cadenas a interceptar (GrabKeys) y devuelve la
pulsada; es Desktop quien la traduce. Esa separación (qué interceptar
vs. qué significa) hace innecesario cualquier candado o Arc.

mirada-brain:
- keymap.rs — Keymap: from_ron/to_ron, load/save, load_or_init (escribe
  un archivo por defecto documentado si falta; default sin pisar si está
  corrupto), default_path (~/.config/mirada/keymap.ron), y watch sobre
  notify para la recarga en caliente (KeymapWatch).
- DesktopAction: Display + FromStr — vocabulario textual estable
  ("focus-next", "layout:grid", "workspace:3"); evita los guiones que
  romperían el RON de un enum.
- Desktop: with_keymap, set_keymap (cambio en caliente -> nuevo GrabKeys).
- Ejemplo keymap-default: imprime el archivo por defecto en RON.

Apps: mirada y mirada-compositor (modo embebido) cargan el keymap del
usuario al arrancar y lo recargan en caliente cuando el archivo cambia.

Disco RON, cable postcard (sólo la lista de cadenas), sin ejecutable
configurador. mirada-brain: 17 -> 29 tests.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 00:04:11 +00:00

7.0 KiB

modules/mirada/ — Compositor Wayland (carmen)

Propósito. Un compositor Wayland teselante. La decisión de diseño central es partirlo en dos procesos, el Cerebro y el Cuerpo:

  • El Cuerpo (mirada-compositor, sobre smithay) habla Wayland con los clientes, posee el hardware (DRM/GPU/libinput) y compone las superficies reales. Los píxeles nunca salen de él — composición zero-copy.
  • El Cerebro (la app mirada, GPUI) decide dónde va cada ventana —pura aritmética de rectángulos— y orquesta el escritorio: layouts, atajos, focos, escritorios virtuales.

Los dos hablan por un socket Unix con un contrato mínimo de enums. Así, toda la lógica espacial es agnóstica de Wayland y se prueba sin un servidor gráfico; el Cuerpo queda reducido a "habla el protocolo y ejecuta operaciones de geometría".

Crates

crate tipo rol
mirada-layout lib Motor de teselado: Rect, modos de layout, Workspace (ventanas, foco)
mirada-protocol lib Contrato Cerebro↔Cuerpo: BrainCommand/BodyEvent + marco de cable
mirada-brain lib Orquestador del escritorio: Desktop, eventos→comandos, atajos
mirada-link lib Transporte: el socket Unix con hilo lector + canal
mirada-body lib Contabilidad del Cuerpo: BodyState, traduce comandos a BodyOp
mirada (app) bin/GPUI El Cerebro: ventana que tesela el escritorio y manda geometría
mirada-compositor bin/smithay El Cuerpo: compositor Wayland real (backend winit, anidado)

Flujo

  mirada-layout ─► mirada-protocol ─► mirada-brain ─► [app mirada · Cerebro]
                          │                                  │
                          │                            mirada-link
                          │                                  │
                          └────► mirada-body ─► [mirada-compositor · Cuerpo]
  • El Cuerpo reporta hardware/clientes con BodyEvent (salida conectada, ventana abierta, atajo pulsado…).
  • El Cerebro (Desktop::on_event) recalcula y emite BrainCommand (Place con la geometría completa, Close, GrabKeys…).
  • El Cuerpo (BodyState::apply) traduce cada comando a BodyOp concretas y sólo emite lo que de verdad cambia.

Detalle por crate

  • mirada-layoutRect + split (reparto exacto de píxeles), LayoutMode (MasterStack/Monocle/Grid/Columns), Workspace con foco cíclico y reordenado. Determinista.
  • mirada-protocolWindowPlacement, los enums BrainCommand y BodyEvent, el marco postcard con prefijo u32 LE (write_frame/read_frame, guard MAX_FRAME) y el puente placements(&Workspace, Rect).
  • mirada-brainDesktop: salidas, 9 escritorios virtuales, registro de ventanas. on_event(BodyEvent) -> Vec<BrainCommand>; DesktopAction + Keymap configurable. set_keymap lo cambia en caliente y devuelve el GrabKeys a reenviar.
  • mirada-linkLink<Out,In> sobre socket Unix; hilo lector de fondo + canal mpsc para sondeo no bloqueante. BrainLink/BodyLink, connected_pair (socketpair), connect/listen por ruta.
  • mirada-bodyBodyState: salidas + superficies; apply traduce BrainCommandBodyOp (idempotente), los mutadores del backend devuelven los BodyEvent a mandar. Ejemplo headless: un Cuerpo sin gráficos guiado por stdin para ejercitar el bucle entero.
  • mirada (app) — envuelve Desktop y lo pinta (barra de escritorios + modo + foco, lienzo teselado). Con MIRADA_SOCKET conecta a un Cuerpo; sin él corre en simulación (ventanas sintéticas, teclado de la propia ventana).

Atajos de teclado configurables

El keymap vive sólo en el Cerebro (mirada-brain::Keymap). El Cuerpo nunca lo ve: recibe únicamente la lista de cadenas a interceptar en un GrabKeys, hace un Vec::contains ciego y devuelve la combinación pulsada como Keybind; es Desktop quien la traduce a DesktopAction. Esa separación —qué interceptar (lista barata, Cuerpo) vs. qué significa (el mapa, Cerebro)— hace innecesario cualquier candado o Arc: el mapa es monohilo y la lista se reemplaza de golpe.

  • Disco — RON de texto en ~/.config/mirada/keymap.ron, editable a mano y versionable. La app lo crea documentado en el primer arranque; si está corrupto, avisa y usa el de por defecto sin pisar el archivo.
  • Cable — sólo viaja la lista de cadenas (GrabKeys), vía el marco postcard que ya existe. No hay formato binario de configuración.
  • Vocabulario — la acción es una cadena estable ("focus-next", "layout:grid", "workspace:3"): DesktopAction: Display + FromStr.
  • Recarga en calienteKeymap::watch (sobre notify) vigila el archivo; al cambiar, el dueño del Desktop recarga, llama a set_keymap y reenvía el GrabKeys. Sin reiniciar.
  • Configurador — no hay ejecutable aparte: el editor de texto del usuario, y la app mirada (que a futuro puede dibujar un editor visual sobre el mismo API Keymap). cargo run -p mirada-brain --example keymap-default imprime el archivo por defecto.

Dependencias

  • Todos los lib con #![forbid(unsafe_code)]. Cero Wayland, cero smithay en los seis crates de arriba.
  • El acoplamiento a Wayland/hardware vive sólo en mirada-compositor.

Estado

Implementado y verde: mirada-layout (22 tests), mirada-protocol (9), mirada-brain (29), mirada-link (7), mirada-body (13), y la app mirada (compila; verificación visual manual).

El Cuerpo ya existe: mirada-compositor es un compositor Wayland teselante real sobre smithay, con backend winit — corre anidado como una ventana dentro de la sesión gráfica actual. Habla wl_compositor/xdg_shell/wl_shm/wl_seat/wl_data_device, compone las superficies de los clientes con GlesRenderer y aplica la geometría del Cerebro. Reusa mirada-body (contabilidad) y mirada-link (cable). Dos modos: autónomo (Cerebro Desktop embebido, un solo proceso) o enlazado (MIRADA_SOCKET → la app mirada decide la geometría). Compila y pasa clippy; verificación visual manual — ver crates/apps/mirada-compositor/README.md.

Pendiente — refinamientos del Cuerpo, no verificables en modo desatendido:

capa pendiente rol
backend DRM/libinput de winit anidado a sesión nativa: superficies KMS, GPU
mirada-input puntero/ratón completo, repetición de teclas, gestos
mirada-sandbox aislamiento de clientes sobre arje-incarnate

CRIU (congelar/restaurar ventanas) queda anotado como futuro.