El Desktop deja de teselar sólo la salida primaria. Cada Output muestra
un escritorio virtual distinto y relayout() las tesela todas en un solo
Place que cubre todas las pantallas.
- Output { id, rect, workspace }; focused_output reemplaza al índice
global active. active_index() = el escritorio de la salida enfocada.
- OutputAdded asigna el primer escritorio libre; OutputRemoved deja sus
ventanas en su escritorio y reajusta el foco. reflow_outputs() las
recoloca en fila.
- SwitchWorkspace actúa sobre la salida enfocada; si el escritorio
pedido ya lo muestra otra salida, las intercambia (invariante: un
escritorio se ve en una salida como mucho).
- DesktopAction::FocusOutputNext (Super+o) mueve el foco entre
monitores. El foco del teclado es único — relayout() lo unifica a la
ventana enfocada de la salida enfocada.
Verificado end-to-end con headless-ctl (ahora 2 salidas).
mirada-brain 52->58 tests.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
mirada-brain::rules — config declarativa que decide qué hacer con una
ventana al abrirse, mismo patrón que el keymap.
- Rule casa por subcadena de app_id y/o title (sin distinguir
mayúsculas; vacío = cualquiera) y aplica un destino: workspace (1..9)
y/o floating. Gana la primera regla que case.
- Rules en RON (~/.config/mirada/rules.ron); la primera vez se escribe
una plantilla con ejemplos comentados, si está corrupta se ignora.
- Desktop consulta Rules::resolve en cada WindowOpened — el evento ya
trae app_id/title — y abre la ventana en su escritorio, flotando si
toca. set_rules en Desktop; las apps cargan rules.ron al arrancar.
mirada-brain 42->51 tests.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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>
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>
Desktop agnóstico de GPUI/smithay: salidas, 9 escritorios virtuales,
registro de ventanas y foco. on_event(BodyEvent) -> Vec<BrainCommand>;
DesktopAction + mapa de teclas estilo tiling WM (Super). 17 tests.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>