feat(infra): auto-commit con 11 cambios

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-10 13:30:27 +02:00
parent 0c1727fef7
commit 231d5d87a6
10 changed files with 496 additions and 12 deletions
+40 -2
View File
@@ -165,6 +165,37 @@ Beneficios:
- Reset trivial (basta borrar `local_files/`).
- Separacion clara para backup/sync (solo `local_files/` es propio del PC).
### 7.1 Anti-jitter automatico (AltSnap, tiling WMs)
`fn::run_app` aplica tres capas de proteccion contra jitter al mover la
ventana con herramientas externas (AltSnap en Windows, snap-assist, tiling
WMs). Activado por defecto, sin opt-in:
1. **GLFW pos/size callbacks**`vp->Pos/Size` se sincronizan al instante
con `glfwSetWindowPos/Size` (no espera al siguiente NewFrame).
2. **Per-frame viewport sync** al inicio del main loop — cubre viewports
secundarios (paneles drag-out) que la backend crea dinamicamente.
3. **Win32 WndProc subclass** (`#ifdef _WIN32`) — observa `WM_ENTERSIZEMOVE`
/ `WM_EXITSIZEMOVE` que AltSnap fakea alrededor de cada drag. Mientras
el bracket esta abierto el main loop SKIPEA `render_fn` + `glfwSwapBuffers`,
replicando el contrato del title-bar drag native (DefWindowProc bloquea
el hilo, DWM compositor mueve el framebuffer existente).
Tests: `cpp/apps/altsnap_jitter_test/` corre dos fases:
- `p1.sync` (cross-platform): drives `glfwSetWindowPos` cada frame, asserta
`vp->Pos` sigue OS dentro de 1px.
- `p2.altsnap` (Windows): worker thread fakea `WM_ENTERSIZEMOVE` +
burst de `SetWindowPos(SWP_ASYNCWINDOWPOS)` + `WM_EXITSIZEMOVE`, asserta
que `render()` no se llama durante el bracket.
Lanzar con `e2e_run_cpp_windows altsnap_jitter_test`.
NO hace falta nada en cada app — toda `fn::run_app` lo hereda. Si una app
necesita renderizar incluso durante external move (caso raro: telemetria
en vivo, video stream), tendria que evitar el bypass — actualmente no hay
flag para desactivarlo (anadir `cfg.pause_on_external_sizemove = true` por
default si surge necesidad).
### 8. Convenciones de runtime
Cumplir el checklist completo de `cpp/PATTERNS.md`. Resumen de lo que NUNCA debe aparecer en una app:
@@ -196,8 +227,15 @@ Si la app tiene componentes que se quieren proteger contra regresiones visuales,
### 10. Layouts persistentes (default)
`fn::run_app` provee menu Layouts (Save current as.../Apply/Delete/Reset) sin
codigo. Crea `<exe_dir>/local_files/layouts.db` (tabla `imgui_layouts`) y
persiste el `imgui.ini` serializado por nombre.
codigo. Crea `<exe_dir>/local_files/layouts.db` (tabla `imgui_layouts` +
`layout_meta`) y persiste el `imgui.ini` serializado por nombre.
**Restore-on-open / save-on-close (1.1.0+):** al cerrar la app, el slot del
layout activo se reescribe con el `imgui.ini` actual (los retoques de
docking sobreviven). Al abrir, si habia un layout activo persistido en
`layout_meta.last_active`, se carga en el primer frame. Si la app no usa
named layouts (nunca clico Save/Apply), el comportamiento sigue siendo el
de antes: `imgui.ini` es la unica fuente.
- App nueva: nada que tocar — Layouts viene activo.
- App quiere personalizar `on_reset` (ej. re-mostrar paneles especificos como