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>
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, sobresmithay) 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 emiteBrainCommand(Placecon la geometría completa,Close,GrabKeys…). - El Cuerpo (
BodyState::apply) traduce cada comando aBodyOpconcretas y sólo emite lo que de verdad cambia.
Detalle por crate
mirada-layout—Rect+split(reparto exacto de píxeles),LayoutMode(MasterStack/Monocle/Grid/Columns),Workspacecon foco cíclico y reordenado. Determinista.mirada-protocol—WindowPlacement, los enumsBrainCommandyBodyEvent, el marcopostcardcon prefijou32LE (write_frame/read_frame, guardMAX_FRAME) y el puenteplacements(&Workspace, Rect).mirada-brain—Desktop: salidas, 9 escritorios virtuales, registro de ventanas.on_event(BodyEvent) -> Vec<BrainCommand>;DesktopAction+Keymapconfigurable.set_keymaplo cambia en caliente y devuelve elGrabKeysa reenviar.mirada-link—Link<Out,In>sobre socket Unix; hilo lector de fondo + canalmpscpara sondeo no bloqueante.BrainLink/BodyLink,connected_pair(socketpair),connect/listenpor ruta.mirada-body—BodyState: salidas + superficies;applytraduceBrainCommand→BodyOp(idempotente), los mutadores del backend devuelven losBodyEventa mandar. Ejemploheadless: un Cuerpo sin gráficos guiado por stdin para ejercitar el bucle entero.mirada(app) — envuelveDesktopy lo pinta (barra de escritorios + modo + foco, lienzo teselado). ConMIRADA_SOCKETconecta 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 marcopostcardque 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 caliente —
Keymap::watch(sobrenotify) vigila el archivo; al cambiar, el dueño delDesktoprecarga, llama aset_keymapy reenvía elGrabKeys. 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 APIKeymap).cargo run -p mirada-brain --example keymap-defaultimprime el archivo por defecto.
Dependencias
- Todos los
libcon#![forbid(unsafe_code)]. Cero Wayland, cerosmithayen 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.