Skip to content

fix(widget): arrastre por compositor en Wayland nativo y estado de posicionamiento (#180) - #210

Merged
egdev6 merged 22 commits into
egdev6:mainfrom
SrStamm:fix/180-wayland-compositor-drag
Oct 29, 2026
Merged

egdev6 merged 22 commits into
egdev6:mainfrom
SrStamm:fix/180-wayland-compositor-drag

Conversation

@SrStamm

@SrStamm SrStamm commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Related issue / Issue relacionada

Closes #180.
ODD: alcance aprobado por egdev6 en este comentario con correcciones en WU1/WU4 (decisión por backend GDK efectivo); evidencia del smoke manual en mi comentario.

Scope / Alcance

Resultado: el arrastre del asa usa el gesto del compositor (startDragging()/xdg_toplevel.move) en Wayland nativo, sin imán ni persistencia de dockEdge/dockOffset al soltar (no se escribe el config.json con coordenadas no fiables). En X11/XWayland (GDK_BACKEND=x11) el pipeline nativo queda intacto: imán y persistencia. La detección se decide por el backend GDK efectivo (sonda del display en runtime, cacheada desde el hilo principal; fallback GDK_BACKEND), no por el tipo de sesión. «Sesión de escritorio» gana la fila windowPositioning por compositor.

Exclusiones (por diseño del alcance aprobado): layer-shell (Mutter no lo implementa), selección de monitor (#113), márgenes ventana/tira (#179/#205); la documentación de GDK_BACKEND=x11 como alternativa queda condicionada a integrar #205.

Coordination / Coordinación

Contributor / Contribuidor: @SrStamm
Evidencia: asignación en #180 verificada vía gh api; plan aprobado por el mantenedor en el hilo.

Acceptance and validation / Aceptación y validación

  • Criterios cumplidos: en Wayland nativo el arrastre mueve la ventana y al soltar no cambia config.json (diff antes/después → SIN CAMBIOS); en XWayland el modo nativo conserva imán y persistencia (dockEdge right→bottom verificado); fila nueva coherente por compositor (limited Mutter / ok bajo backend X11).
  • Comprobaciones ejecutadas: npm test (60 archivos vitest + 258 node:test, 0 fallos), npm run typecheck (limpio), cd src-tauri && cargo test (45/45 wm_compat, 0 fallos), cargo fmt (limpio), node scripts/i18n-inventory.mjs --check (verde), smoke manual en ambos escenarios con evidencia en el issue.
  • Comprobaciones no ejecutadas y motivo: tests de eventos de puntero sobre Widget.tsx vía DOM (jsdom/happy-dom): el repo no tiene entorno DOM en tests y añadirlo es decisión de dependencia del repo (postergo la decisión al mantenedor). La cobertura determinista pedida vive en drag-session y en wm_compat; el cableado está cubierto por el smoke manual.
  • Bloqueos pendientes: ninguno para revisar la PR.

Una PR abierta no implica integración: release, secretos y firma requieren autorización separada.

@egdev6 egdev6 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SrStamm gracias por la PR y por el smoke: la decisión por backend GDK efectivo es justo la corrección de WU1, la sonda en setup con caché resuelve bien el problema del hilo, y en Windows/macOS el modo sigue siendo native. Con #205 ya integrada en main, hay algunos cambios antes de mergear.

Cambios necesarios

  1. Rebase sobre main (f71039b). Hay conflictos en src-tauri/Cargo.toml (las dos PRs añaden gtk = "0.18") y en docs/i18n-inventory.md (regenerarlo con node scripts/i18n-inventory.mjs).
  2. Una sola detección del backend GDK. #205 introdujo widget_placement::transport() (GdkX11Display frente a Wayland, en el hilo de UI y con OnceLock). Esta PR añade wm_compat::probe_gdk_display_backend() con otra caché para el mismo dato. Tras el rebase, deja una sola fuente y que la otra la consuma, para que el arrastre y la colocación nunca puedan discrepar.
  3. El estado de arrastre puede quedarse activo en modo compositor. onGripDown pone setDragging(true) y solo onPointerUp/onPointerCancel lo devuelven a false. Con startDragging() el compositor toma el grab del puntero, y en Wayland es habitual que la webview no reciba el pointerup de ese gesto. Si no llega, dragging queda en true: el panel de detalle no vuelve a abrir (su estado exige !dragging), el auto-ocultado lo trata como ocupado y la colocación de la tira no se vuelve a pedir. El smoke acredita el movimiento y que config.json no cambia, pero no que el detalle abra después de soltar. Comprueba ese caso en GNOME Wayland y, si el pointerup no llega, añade una salida robusta (por ejemplo, limpiar el estado en el siguiente pointermove con buttons === 0 o en pointerenter, o no usar dragging en esta rama).
  4. Lo que quedó condicionado a #205:
    • La nota de windowPositioning para X11 sigue mencionando los márgenes abajo/derecha de #179; ya no aplica.
    • La evidencia que acordamos: capturas con GDK_BACKEND=x11 en los cuatro bordes, sin la caja translúcida de la ventana.
    • La documentación de GDK_BACKEND=x11 como alternativa (vía 3), con el aviso de que la variable tiene que ir en la misma línea o exportada.
  5. Fuera de alcance: odd/tasks/184-rustfmt-ci-format-gate.md pertenece a #184. Sácalo de esta PR.

Menores

  • Si get_wm_info falla, el fallback a compositor se aplica en todas las plataformas. Limítalo a Linux para que un fallo puntual no quite el imán en Windows/macOS.
  • En drag-session.ts, el comentario de dragMode() quedó encima de storedDragMode.
  • En Widget.tsx (cerca de la línea 219) hay un bloque de comentario sin código debajo.
  • El enlace a la aprobación en la descripción termina en issuecomment-*.

Con los puntos 1 a 5 resueltos vuelvo a revisar.

…egdev6#180)

Decidir la capacidad de posicionamiento por el backend GDK efectivo
(GType del display en runtime, fallback por GDK_BACKEND), no por el tipo
de sesión: bajo XWayland (GDK_BACKEND=x11 en sesión Wayland) el
posicionamiento es ok; el Wayland nativo reporta limited con nota
específica de Mutter.

WU4 de odd/tasks/180-wayland-compositor-drag.md; plan aprobado en egdev6#180.
…gdev6#180)

dragMode(backend): X11 (XWayland incluido) → native con imán y
persistencia; Wayland → gesto del compositor sin imán ni persistencia,
para no contaminar el config.json compartido con la sesión X11.

WU1 de odd/tasks/180-wayland-compositor-drag.md; decisión por backend
efectivo según la corrección del mantenedor en egdev6#180.
…v6#180)

Decisión de estrategia una sola vez al arrancar desde el backend GDK
efectivo:
- Wayland: el asa delega en startDragging() (xdg_toplevel.move); sin
  captura de puntero, sin pipeline delta, y al soltar sin imán, sin
  outerPosition() ni persistencia de config.
- X11/XWayland: el pipeline delta nativo queda intacto (regresión
  segura).
- Bloqueado hasta que la detección de arranque resuelve; si falla, cae
  en la rama compositor (la que no hace daño).

Tests de eventos del widget diferidos: el entorno de tests del repo no
tiene DOM (jsdom/happy-dom es decisión de alcance del mantenedor); la
cobertura determinista vive en los tests de drag-session y de
wm_compat (Rust), y el cableado lo cubre el smoke manual exigido (WU6).

WU2 de odd/tasks/180-wayland-compositor-drag.md.
…6#180

Pin de regresión para la WU3 de egdev6#180: el widget ahora ramifica la
estrategia de arrastre por backend efectivo, y la auditoría de posición
nativa debe seguir siendo solo-Windows (bajo xdg-shell outerPosition()
es (0,0) por diseño, auditar pelearía contra la colocación del
compositor). Sin cambios de lógica: el gate ya excluye Linux; este test
lo deja fijado frente a la rama WU2.

WU3 de odd/tasks/180-wayland-compositor-drag.md.
…ritorio (egdev6#180)

Espejo TS de la superficie WU4: displayBackend tipado en
WindowManagerInfo (clase DisplayBackend importada de drag-session, sin
duplicar la unión) y windowPositioning en DesktopSurfaces; la fila nueva
del bloque «Sesión de escritorio» usa la clave
settings.shell.surfaces.windowPositioning (es/en), con la nota del
backend pasando de largo; Widget.tsx lee el campo tipado (sin cast).

Fixture del test SSR extendido con windowPositioning para que
desktopCompatRows no tropiece con undefined.

WU5 de odd/tasks/180-wayland-compositor-drag.md; inventario i18n
regenerado tras el commit.
)

El ref local quedaba eternamente sin resolver en el harness SSR
(renderToStaticMarkup no ejecuta efectos de React), bloqueando los 15
tests de gestos del asa en auto-hide.test.ts. La decisión vive ahora en
un store de módulo en drag-session.ts (setDragMode/currentDragMode/
resetDragMode): el efecto de arranque escribe la decisión y el unmount
la resetea para re-detectar en remounts; los handlers leen el store con
el mismo guard null-bloquea.

El harness siembra/cribe el store explícitamente (native en
configureNative, reset en afterEach). Suite completa en baseline verde
(60 archivos vitest + 258 node:test).

WU2 follow-up de odd/tasks/180-wayland-compositor-drag.md.
@SrStamm
SrStamm force-pushed the fix/180-wayland-compositor-drag branch from e148f6a to 5cf41b7 Compare October 29, 2026 22:10

@egdev6 egdev6 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SrStamm gracias por la ronda: los cinco puntos y los menores quedan resueltos.

  • Rebase sobre f71039b, sin conflictos con main.
  • Una sola detección del backend GDK: widget_placement::display_kind() es la única fuente y get_wm_info la consume, así que el arrastre y la colocación ya no pueden discrepar.
  • dragging en modo compositor: la salida por pointermove con buttons === 0 cubre el caso aunque no lo hayas podido reproducir, y no toca el pipeline de X11.
  • Lo condicionado a #205: la nota de X11 ya no menciona márgenes, la alternativa GDK_BACKEND=x11 está documentada con el aviso de la misma línea y las cuatro capturas cierran la evidencia sin la caja translúcida.
  • Alcance: el documento de #184 ya no forma parte de la PR, y el fallback a compositor queda limitado a Linux.

Los dos avisos que detectaste no vienen de esta rama, así que los abro como issues aparte (enlazadas abajo). Gracias también por el smoke en los dos escenarios.

@egdev6

egdev6 commented Oct 29, 2026

Copy link
Copy Markdown
Owner

Seguimientos de lo que detectó @SrStamm fuera del alcance de esta PR:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(linux/wayland): la ventana no se puede posicionar: tira centrada, arrastre y cambio de monitor inoperativos

2 participants