Repository navigation
fix(linux/x11): la tira alcanza el borde del área de trabajo (#179) - #205
Conversation
) The widget window is created with `resizable: false`, so under X11 the window manager discards every programmatic resize and the strip keeps the 320x260 default, leaving the bottom of the work area unreachable. Open the programmatic resize path and pin the window with equal size hints (min == max == the strip size): the manager cannot offer another size and GTK clips any reconfiguration, so a manual resize stays impossible while the programmatic one is applied. The placement cycle asks for size and position, maps the window, reads back what the compositor granted (GDK absolute client origin plus size), repositions with the effective geometry and reads back again. The placement report is now the source of truth for the frontend cache, and a structured reason code is reported when the manager does not grant the requested geometry. The reason labels live in the ES/EN catalogs (`widget.reason*`), like the rest of the strip UI after upstream egdev6#195. Native Wayland and the Windows/macOS paths keep their current behaviour.
Regenerate the text inventory over the committed tree, with the stable format from egdev6#186: the only new user-facing texts are the `widget.reason*` labels (four of them reachable in the UI; the `superseded` code is reported by the backend but the widget treats a superseded placement as "no reason").
ODD artifact for egdev6#179: the approved scope, the measured design decisions, the four-edge evidence and the human accreditations still pending.
|
@Rafaeldelinares gracias por la PR y por la evidencia de #179: el A/B, la tabla de los cuatro bordes con Lo que está bien
Cambios necesarios
Opcional
Con los puntos 1, 3, 4 y 5 resueltos, la verificación del punto 2 y la prueba del cursor en la app real, vuelvo a revisar. |
) The widget window is created with `resizable: false`, so under X11 the window manager discards every programmatic resize and the strip keeps the 320x260 default, leaving the bottom of the work area unreachable. Open the programmatic resize path and pin the window with equal size hints (min == max == the strip size): the manager cannot offer another size and GTK clips any reconfiguration, so a manual resize stays impossible while the programmatic one is applied. The placement cycle asks for size and position, reads back what the compositor granted (GDK absolute client origin plus size), repositions with the effective geometry and reads back again. The placement report is now the source of truth for the frontend cache, and a structured reason code is reported when the manager does not grant the requested geometry. The resize permission is opened and closed inside one native call, and the size is re-verified after that withdrawal, so the report always describes what is on screen and the manual resize interaction stays closed outside the programmatic resize. The reason labels live in the ES/EN catalogs (`widget.reason*`), like the rest of the strip UI after upstream egdev6#195. Native Wayland and the Windows/macOS paths keep their current behaviour.
La review pidió cambios que reescribieron la secuencia nativa del ciclo de colocación (permiso de resize cerrado salvo en el resize programático, read-back del tamaño tras la retirada, señal de visibilidad real) y una auditoría ciega encontró además seis defectos menores. El work se rehízo sobre el main actual (0.8.0) en tres commits (8c3ee37 implementación, a7bab32 inventario i18n, 42c62d0 artefacto ODD) y este merge lo integra en la rama ya publicada sin reescribir la historia: el diff de la PR egdev6#205 pasa a ser el árbol final verificado y el hilo de la review se conserva.
Integra los tres commits nuevos de main (firma de macOS egdev6#209/egdev6#211 y logo de Copilot egdev6#208), que no tocan el mecanismo de colocación; el inventario i18n se regenera encima en el commit siguiente.
|
@egdev6 gracias por la review: los cinco puntos eran buenos y dos de ellos no estaban realmente cerrados por nuestra primera corrección. Van resueltos, con las cuatro opcionales también, y con el mecanismo corregido donde nuestra primera respuesta describía mal lo que ocurría. Punto 1 — el permiso de resize. Ahora se abre y se cierra dentro de una sola llamada nativa ( Medido (GTK3 + WebKit2 real, X11): con la petición de tamaño puesta, retirar el permiso no cambia el tamaño ni genera configure (contador 4 → 6 → 6) y el 61×181 concedido sobrevive con su posición; sin la petición de tamaño, el mismo retiro devuelve la ventana a 320×260. Son dos escenarios distintos y los medimos por separado. Lo que conserva el granted size es la petición de tamaño del widget ( Punto 2 — el tamaño efectivo tras ese evento. El read-back final vuelve a leer tamaño y posición después de la retirada, y el informe usa esa geometría: si tras el retiro el compositor cambió el tamaño, no se informa Una precisión sobre el mecanismo, porque nuestra primera respuesta lo describía mal: el handler de un solo uso de Punto 3 — el mapeo en el ciclo. Fuera: el backend no mapea ni muestra la ventana en ningún camino (el único Punto 4 — la señal de «visible». La real: Punto 5 — la tolerancia de ±1 px. El informe lleva Opcionales. Timeout de 2 s en la espera de Además, una auditoría ciega independiente del diff encontró seis cosas más que también están cerradas: la cabecera del módulo describía el diseño anterior · la fijación de restricciones no comprobaba la generación (una colocación cancelada podía pisar las pistas de la sucesora) · la red de seguridad de 2,5 s podía volver a mostrar una tira oculta · el origen tenía un fallback en coordenadas relativas al padre (otro espacio de coordenadas) · Evidencia (binario de este head). KDE Plasma 6.7.5, app en X11/XWayland, área de trabajo
Comprobado también con sondas: un Comprobaciones. CI 5/5 · Lo que sigue sin acreditar, dicho explícitamente: el gesto manual de resize del gestor (lo medido es que el gestor recibe Tamaño del diff: Sobre la forma de la rama: la reconstruimos sobre el |
|
@Rafaeldelinares gracias por la segunda vuelta. He revisado el árbol final (
Las opcionales también están, y la auditoría adicional suma. Queda integrada. Dos notas que no bloqueaban, para un seguimiento:
Lo que declaráis sin acreditar (GNOME/XWayland, HiDPI real, monitores con distinto factor) queda en #107, no en esta PR. |
…and (#215) (#224) * fix(linux/x11): ajustar la ventana del detail al contenido bajo XWayland (#215) La ventana detail nace resizable(false) y GTK retiene un piso PMinSize sticky, así que el resize externo es rechazado en el ancho y el aviso de API key muestra la caja del contenedor (~16 px de banda). El detalle pasa por el mismo ciclo X11 de la tira (#205): una sola llamada al hilo de UI hace la pista de tamaño, las pistas min == max == pedido, el permiso de resize abierto sólo alrededor del resize y confirmado cerrado; luego la posición explícita y un read-back de GDK con presupuesto acotado. Generación de cancelación propia del detail (no comparte la del widget), sin anclaje y con informe {status, bounds, reason, read_back} espejo de set_widget_bounds; Windows, macOS y Wayland nativo quedan en su ruta anterior (unverified, bounds=null). * fix(linux/x11): el panel del detail consume el informe de colocación (#215) DetallePanel cachea sólo la geometría confirmada por read-back (nunca la pedida), repide en silencio tras show() ante not_viewable con el presupuesto acotado de #221 (readPlacementWithRetries reutilizado) y deja intacto el flujo de Wayland nativo/Windows/macOS (unverified sin read-back, comparación exacta). La apertura no se bloquea: place → clip → positioned → show conserva su orden. * docs(i18n): regenerar el inventario de textos (#215) Secciones nuevas de detail_placement.rs y detail_placement_test.rs (cuerpos de error y nombres de test, nada de interfaz de usuario) tras los commits 9a6622d y 15aea55; el frontend no añade textos. * test(linux/x11): pedir posición dentro del área en la prueba en vivo (#215) Ejecutar la prueba en vivo contra el XWayland real marcó el hallazgo del fixture: movía la ventana 314×379 a (1859,899), fuera de pantalla, y el gestor la reubicaba (1606,701) para que quepa. La petición ahora es (100,100) y el resto de la secuencia queda intacto: tamaño exacto concedido, permiso cerrado y tamaño sobreviviente a la retirada. * docs(odd): artefacto de la colocación nativa del detail en X11 (#215) Ciclo, decisiones (D1–D3), TDD por unidad, hallazgo del fixture de la prueba en vivo y evidencia de sesión GNOME/XWayland (geometría 314×379, pistas min == max, sin caja translúcica) según los criterios de aceptación (#215). * docs(i18n): regenerar el inventario de textos * fix(linux/x11): mover el detail a coordenadas lógicas en HiDPI (#215) request_position pasaba la petición física tal cual a gtk.move_, que mide en píxeles lógicos: a escala ×2 el panel quedaba desplazado aproximadamente al doble (P2 del review de PR #224, diagnosticado por el mantenedor y contrastado con el recorrido del código). Se introduce el seam testeable del propio archivo (Positioner + GtkPositioner + position_call, espejo de Sizable/GtkSizable): la conversión con to_logical cubre los dos ejes antes del movimiento, el mismo mapeo que el adaptador del widget. La cobertura nueva (escala ×2: (200,300) físico -> (100,150) lógico) falla contra el código anterior, así que la omisión queda atrapada por test. Verificación: cargo test 402 + 4 ignoradas (0 fallos), fmt limpio, clippy sin avisos nuevos en detail_placement*; verificador independiente en PASS sobre los 5 checks. * docs(odd): bitácora L5 del fix HiDPI del review de PR #224 (#215) * docs(i18n): regenerar el inventario de textos (#215) * docs(odd): cierre L5 con el inventario i18n regenerado (#215) --------- Co-authored-by: Quique <egdev6@gmail.com>
Related issue / Issue relacionada
Issue: #179
ODD: alcance aprobado por el mantenedor en #179 (comment) · evidencia de verificación en #179 (comment)
Scope / Alcance
La tira visible no alcanzaba el borde del área de trabajo bajo Linux/X11: la ventana del widget nace con
resizable: false, así que el gestor de ventanas descarta cualquier resize programático y la ventana conserva su tamaño natural de 320×260 (medido: ~84 px sin usar en el borde inferior). La causa está en la superficie nativa, no en la posición: no es un offset.PMinSize == PMaxSize == tamaño de la tira) y con la petición de tamaño del widget (gtk_widget_set_size_request), y el permiso de resize se abre y se cierra dentro de una sola llamada nativa (apply_size), que confirma su propio resultado. Fuera de ese resize no hay cursor de redimensionado ni arrastre de borde; lo que conserva el tamaño concedido es la petición de tamaño (medido: sin ella, retirar el permiso devuelve la ventana a 320×260).applied. Una lectura fallida nunca se convierte en 0×0, y el borde anclado se conserva aunque el tamaño concedido sea otro.read_failed); el backend nunca mapea ni muestra la ventana, y el frontend no vuelve a mostrar una tira que el usuario ocultó desde la bandeja.size_refused,position_refused,not_viewable,read_failed,superseded), cuya etiqueta vive en los catálogos ES/EN (widget.reason*), como el resto de la tira desde feat(i18n): migrar la tira y el detalle a los catálogos ES/EN — T2c slice 1 (#66) #195. La tolerancia de ±1 px (el redondeo del gestor de píxeles lógicos a píxeles de dispositivo) se aplica sólo a la geometría que vino del read-back de X11; Windows, macOS y Wayland nativo comparan exacto.El transporte se detecta por el tipo real de display de GDK (
GdkX11DisplayvsGdkWaylandDisplay), cacheado en el hilo de UI: con Wayland nativo el transporte es "otro" y la ruta anterior queda intacta.Desviaciones documentadas del alcance aprobado
min == max(que el gestor respeta y GTK también clampa) y la ausencia de decoraciones.tauri.conf.jsonse sustituye en tiempo de ejecución por el tamaño real de la tira en la ruta X11 (set_geometry_hints+set_size_request). La config compartida no se toca; el mínimo de la config sigue aplicando en el resto de plataformas.Fuera de alcance: Wayland nativo (#180, transporte y contrato distintos), Windows/macOS (siguen con
detail_geometry::apply_widgety devuelvenunverified), el imán al soltar (comportamiento preexistente:src/lib/dock.ts, sin cambios aquí), la persistencia dedockEdge/dockOffset/dockMonitory la selección de monitor (#113).Commits revisables (sobre
upstream/main@a0e999b, la 0.8.0):fix(linux/x11)(backend, frontend y sus tests),docs(i18n)(inventario regenerado con el script de #186, sobre el árbol de la unidad) ydocs(odd)(artefacto ODD), más dos merges: uno integra esta reconstrucción en la rama ya publicada y otro elmainactual (4a5363e), sin reescribir la historia publicada; de modo que el diff de esta PR es el árbol final y el hilo de la review se conserva.Tamaño:
+2617 / -29(código y tests+2352: 1274 tests, 1078 producción; más el artefacto ODD y el inventario regenerado). El grueso es el ciclo nativo con cobertura determinista (25 tests Rust del módulo + 1 prueba en vivo GTK+WebKit2 + tests de frontend y de catálogo): el ciclo tiene que ser verificable sin un compositor real en cada caso. Si prefieres dos PRs (ciclo nativo / contrato IPC), lo parto antes de mergear.Coordination / Coordinación
Contribuidor / Contribuidor: @Rafaeldeliners
Claim or agreement evidence / Evidencia de asignación o acuerdo: alcance aprobado por el mantenedor en #179 (#179 (comment)); la issue sigue sin assignee porque nuestro token no puede asignar. Sin PR solapadas: al abrir, las PRs abiertas upstream son #203 (smoke de secretos), #207 (provider Antigravity) y #210 (arrastre por compositor en Wayland nativo, #180); ninguna sobre la geometría nativa de la tira bajo X11, que es lo que aporta esta PR.
Roadmap ODD (#45, revisión
quorb-linux-local-v1): esta corrección aporta el caso X11 de #107 «Escritorio y widget Linux» (milestone 8, en desarrollo), cuyo pendiente incluye el smoke en sesión real X11; el resto de #107 (GNOME/XFCE y matriz Wayland) sigue abierto. La documentación de la vía 3 de #180 (GDK_BACKEND=x11como alternativa) queda condicionada a integrar esta PR, como acordaste.Acceptance and validation / Aceptación y validación
Criteria satisfied / Criterios cumplidos: S1 (el límite es el área de trabajo
y=30…1080, respetando el panel reservado) · S2 (se corrige la superficie nativa, sin offset, y el resize manual queda cerrado: permiso fuera del resize, pistasmin == maxy sin decoraciones) · S3 (el mínimo de 240 px se resuelve en runtime y los bordes horizontales se comprueban: 61×181 exacto) · S4 (resize → estabilización → posicionamiento con geometría efectiva → read-back; ciclo acotado, cancelable y sin fingir aplicaciones no confirmadas; si el gestor rechaza, se informa el motivo y no se cachea la solicitud) · S5 (Wayland nativo sin read-back de posición absoluta) · S6 (tests deterministas de orden, estabilización, rechazo y solicitudes obsoletas; evidencia KDE/X11 por borde; imán y persistencia conservados).Checks actually run and results / Comprobaciones ejecutadas y resultados:
cargo test --locked(354 pasan, 0 fallan, 3 ignorados) · prueba en vivo GTK+WebKit2 bajo X11 (GDK_BACKEND=x11 cargo test --locked widget_placement -- --ignored, verde, con el cruce contra el servidor X) ·npm test(751 vitest + 240 node, 0 fallan) ·npm run typecheck(verde) ·cargo clippy --all-targets(los mismos avisos que la base deupstream/main, ninguno en el código nuevo) ·cargo fmt --all -- --check(limpio en todo el crate, el gate nuevo de chore(tooling): adoptar rustfmt con gate de CI de formato (#184) #185) ·node scripts/i18n-inventory.mjs --check(verde, con el formato estable de chore(i18n): inventario estable, contrato de CI estructural y mensajes de drift (#160) #186) · evidencia app-faithful en KDE/X11 (webview real) por borde, conWM_NORMAL_HINTS=min == max == tamaño de la tiraen los cuatro:WM_NORMAL_HINTS181x61+870+30181x61+870+101961x181+0+46561x181+1859+465(área de trabajo
0, 30, 1920, 1050; reproducible conxprop -root _NET_WORKAREA,xwininfo -id <id>yxprop -id <id> WM_NORMAL_HINTS) · sondas con webview real: unXResizeWindow(200,200)externo y unConfigureRequest(200,200)sintético quedan clampados a 61×181 · sesión manual en KDE/X11 sobre este mismo binario: la tira se movió por los bordes, se acopló al borde más cercano con el mismo tamaño, sin parpadeo ni rectángulo 320×260, y al intentar redimensionarla no se observó cursor de redimensionado, arrastre de borde ni cambio de tamaño · escaneo del mismo binario durante 30 s de arrastre (288 muestras cada 100 ms): sólo los dos tamaños esperados (181×61 y 61×181), ninguna aparición del tamaño natural 320×260,WM_NORMAL_HINTSsiempre acordes con el tamaño actual, ningún fotograma sin mapear y el recorrido siempre dentro del área de trabajo (x 0…1859, y 30…1019).Checks not run and why / Comprobaciones no ejecutadas y motivo: el gesto manual de resize del gestor (lo medido es que el gestor recibe
min == maxy que un resize externo queda clampado; el gesto no se ejercitó) · GNOME/XWayland (donde la ventana se pintaba como una caja translúcida mayor que la tira; con la ventana al tamaño de la tira debería desaparecer, y queda por comprobar en ese entorno) · la escala HiDPI real en un monitor 1,5/2 (la regla de conversión está medida conGDK_SCALE=2y probada por unidad, no en pantalla) · la ausencia de destello: en la sesión manual no se vio parpadeo, pero medido el resize previo al mapeo se pierde en ~1 de cada 9 carreras, así que puede haber un parpadeo breve del tamaño por defecto (acotado por el reintento con la ventana ya visible); no se afirma ausencia de flash porque no hay evidencia en pantalla de esa carrera.Remaining blockers / Bloqueos pendientes: ninguno técnico; el tamaño del diff queda sujeto a tu aceptación (o a tu preferencia por partirlo en dos PRs). El merge es decisión del mantenedor.
An open PR does not mean integration. Release, secrets and signing operations require separate authorization.
Una PR abierta no implica integración. Release, secretos y firma requieren autorización separada.