Files
brahman/crates/modules/mirada/SDD.md
T
sergio b31f988833 feat(mirada): API de acciones — mirada-ctl + HUD interactivo
Toda acción de escritorio converge en Desktop::apply(DesktopAction); el
keymap era sólo un front-end. Esta tanda añade los otros tres.

- DesktopAction::FocusWindow(WindowId): direccionamiento directo de una
  ventana (no sólo ciclar); si está en otro escritorio, salta a él.
  DesktopAction pasa a ser Serialize/Deserialize (postcard) además de
  Display/FromStr.

- mirada-brain::ctl: el API de control externo. CtlRequest/CtlReply
  (marco postcard), CtlServer/CtlConn no bloqueantes y send_request.
  El Cerebro abre el socket y atiende en su bucle: la app mirada
  siempre, mirada-compositor sólo con el Cerebro embebido.

- mirada-ctl: CLI de control estilo swaymsg/hyprctl —
  `mirada-ctl focus-next | focus-window 5 | workspace 3 | windows`.
  Parsea la acción de los argumentos vía FromStr.

- HUD interactivo en la app mirada: pips de escritorio y ventanas del
  lienzo clicables (SwitchWorkspace / FocusWindow).

- Ejemplo headless-ctl: un Cerebro sin gráficos para probar mirada-ctl
  en modo desatendido. Verificado end-to-end.

mirada-brain: 29 -> 37 tests.

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

8.6 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)
mirada-ctl (app) bin/CLI Control externo del Cerebro (estilo swaymsg): acciones y consultas

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). Pips de escritorio y ventanas clicables.
  • mirada-ctl (app) — CLI de control: parsea la acción de los argumentos (DesktopAction: FromStr) y la manda al Cerebro por el socket de control; windows y actions para consultar.

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.

API de acciones

Toda acción de escritorio converge en un único embudo: Desktop::apply(DesktopAction) -> Vec<BrainCommand>. El keymap no es más que un front-end (Keybindlookupapply); hay otros tres:

  • DesktopAction::FocusWindow(WindowId) — direccionamiento directo de una ventana (no sólo ciclar con FocusNext/Prev); si está en otro escritorio, salta a él. Lo usan la taskbar y mirada-ctl.
  • HUD interactivo (app mirada) — los pips de escritorio y las ventanas del lienzo son clicables: clic = apply de la acción.
  • mirada-ctl — control externo por línea de comandos (mirada-ctl focus-next, workspace 3, windows). Habla con el Cerebro por un socket Unix aparte; el módulo mirada-brain::ctl define CtlRequest/CtlReply (marco postcard), CtlServer/CtlConn y send_request. El Cerebro (la app mirada siempre; mirada-compositor sólo embebido) abre el socket y atiende en su bucle. DesktopAction viaja como enum serializado: contrato tipado de punta a punta.

cargo run -p mirada-brain --example headless-ctl levanta un Cerebro sin gráficos para ejercitar mirada-ctl en modo desatendido.

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 (37), mirada-link (7), mirada-body (13), las apps mirada y mirada-compositor (compilan; verificación visual manual) y mirada-ctl (CLI, probado vía el ejemplo headless-ctl).

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.