feat(mirada): reglas de ventana — escritorio y flotante por app_id

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>
This commit is contained in:
sergio
2026-05-21 01:01:14 +00:00
parent 4719f7c9f9
commit 6dfd9e62ac
7 changed files with 311 additions and 8 deletions
+17 -3
View File
@@ -61,8 +61,8 @@ ejecuta operaciones de geometría".
`placements(&Workspace, Rect)`.
- **`mirada-brain`** — `Desktop`: 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.
`DesktopAction` + `Keymap` configurable (`set_keymap` en caliente) +
`Rules` de ventana.
- **`mirada-link`** — `Link<Out,In>` sobre socket Unix; hilo lector de
fondo + canal `mpsc` para sondeo no bloqueante. `BrainLink`/`BodyLink`,
`connected_pair` (socketpair), `connect`/`listen` por ruta.
@@ -137,6 +137,20 @@ que un front-end (`Keybind` → `lookup` → `apply`); hay otros tres:
`cargo run -p mirada-brain --example headless-ctl` levanta un Cerebro sin
gráficos para ejercitar `mirada-ctl` en modo desatendido.
## Reglas de ventana
`mirada-brain::rules` decide qué hacer con una ventana **al abrirse**:
config declarativa en RON (`~/.config/mirada/rules.ron`), mismo patrón
que el keymap. Cada `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.
El `Desktop` consulta `Rules::resolve` en cada `WindowOpened` — el evento
ya trae `app_id`/`title` — y manda la ventana a su escritorio, flotando
si toca. Se carga al arrancar (la primera vez se escribe una plantilla
con ejemplos comentados); las reglas afectan a las ventanas futuras, no
a las ya abiertas.
## Dependencias
- Todos los `lib` con `#![forbid(unsafe_code)]`. Cero Wayland, cero
@@ -146,7 +160,7 @@ gráficos para ejercitar `mirada-ctl` en modo desatendido.
## Estado
Implementado y verde: `mirada-layout` (32 tests), `mirada-protocol`
(10), `mirada-brain` (42), `mirada-link` (7), `mirada-body` (14), las
(10), `mirada-brain` (51), `mirada-link` (7), `mirada-body` (14), las
apps `mirada` y `mirada-compositor` (compilan; verificación visual
manual) y `mirada-ctl` (CLI, probado vía el ejemplo `headless-ctl`).