feat(mirada): marco de ventana — distinguir y resaltar el foco

Sin decoración, las ventanas se confundían entre sí. Ahora el backend
DRM dibuja un marco fino alrededor de cada ventana: azul la que tiene
el foco del teclado, gris las demás.

- `ManagedWindow` gana `focused: bool` (lo fija `exec_op` al atender
  `BodyOp::Focus`/`Unfocus`) y `borders: [SolidColorBuffer; 4]` — un
  búfer por lado, cada uno con su `Id` estable para el seguimiento de
  daño; `SolidColorBuffer` sube su contador sólo si tamaño o color
  cambian, así un marco quieto no fuerza recomposición.
- El enum `Frame` pasa de `Cursor` a `Solid`: una variante de color
  sólido que sirve para el cursor y para los marcos (dos variantes con
  el mismo tipo chocarían en el `From` que genera `render_elements!`).
- `render()` en dos pasos: refresca los búferes (tamaño = contenido,
  color = foco) y luego arma los elementos. El marco va metido hacia
  adentro, sobre el borde de la superficie, así no pisa al vecino.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
sergio
2026-05-21 04:10:32 +00:00
parent fb3091d995
commit 751416252f
5 changed files with 81 additions and 10 deletions
+3 -1
View File
@@ -210,7 +210,9 @@ Cerebro: **autónomo** (`Desktop` embebido) o **enlazado** (`MIRADA_SOCKET`
(`BodyEvent::PointerEntered`) y clics y rueda van a la ventana debajo.
`Super`+arrastre mueve/redimensiona: el Cuerpo calcula el rectángulo y
emite `BodyEvent::WindowFloatTo { id, rect }`; el Cerebro hace flotar
la ventana ahí (`Workspace::set_floating`).
la ventana ahí (`Workspace::set_floating`). Cada ventana lleva un marco
de 2 px (4 `SolidColorBuffer` por ventana, `Id` estable): azul si tiene
el foco, gris si no.
**Pendiente** — refinamientos del Cuerpo: