#!/bin/sh # test-craft-ventana.sh — ¿ABRE VENTANA Y PINTA una app de la suite ArtCraft acá, sin Vulkan? # # Copia la mecánica de `scripts/test-atuq-boveda-metal.py` (SDD 26 §7.sexies): rootfs del perfil # `escritorio-sway` hidratado, capas de `bwrap` con la ÚLTIMA ganando, sway headless con el # renderer `pixman` (el compositor no necesita GL) y el CLIENTE por software con **llvmpipe, no # softpipe** — softpipe se queda en GL 3.3 y wgpu exige compute shaders. # # La evidencia no es el log: es la captura y el árbol del compositor. # · `app_id` en el árbol de sway ⇒ la ventana EXISTE # · nº de colores de la captura ⇒ la ventana PINTÓ (1 color = sólo el fondo de swaybg) # # uso: scripts/test-craft-ventana.sh gridcraft # y el control, que es el que vale: # BACKEND=auto scripts/test-craft-ventana.sh gridcraft # sin WGPU_BACKEND, como en la imagen set -e APP=${1:-gridcraft} ROOT=${ROOT:-/opt/takana} STORE=${STORE:-$ROOT/store} RFS=${RFS:-$ROOT/work/sway-rootfs} ALPINE=${ALPINE:-$ROOT/.dev-fs/alpine} SAL=${SAL:-$ROOT/work/$APP-ventana} BACKEND=${BACKEND:-gl} # `gl` fuerza el camino EGL/GLES · `auto` deja el default de egui-wgpu (PRIMARY|GL) ESPERA=${ESPERA:-120} hash_de() { "$ROOT/target/release/takana" --store "$STORE" hash "recipes/$1.toml" | tail -1 | sed 's/^b3://'; } capa() { d="$STORE/$(cd "$ROOT" && hash_de "$1")-$1" [ -d "$d" ] || { echo "!! falta el artefacto vigente de $1 ($d)" >&2; exit 1; } echo "$d" } [ -d "$RFS" ] || { echo "!! no está el rootfs de sway en $RFS — hidratalo con scripts/hydrate-profile.py escritorio-sway --into work/sway-rootfs --allow-missing" >&2; exit 1; } GC=$(capa "$APP") L18=$(capa llvm18) MLP=$(capa mesa-llvmpipe) echo "capas: alpine + sway-rootfs + $(basename "$L18") + $(basename "$MLP") + $(basename "$GC")" rm -rf "$SAL"; mkdir -p "$SAL" cat > "$SAL/dentro.sh" <> /salida/log.txt; exit 1; } export WAYLAND_DISPLAY=wayland-1 export SWAYSOCK=\$(ls /run/user/0/sway-ipc.* 2>/dev/null | head -1) echo "@@ wayland listo" >> /salida/log.txt /usr/bin/swaybg -c '#1a4b8c' >> /salida/swaybg.log 2>&1 & sleep 2 /usr/bin/grim /salida/antes.png 2>>/salida/log.txt echo "@@ lanzo $APP (backend=$BACKEND)" >> /salida/log.txt /usr/bin/$APP > /salida/app.log 2>&1 & PID=\$! j=0 while [ \$j -lt $ESPERA ]; do /usr/bin/swaymsg -t get_tree -r 2>/dev/null | grep -q '"app_id": *"ai.storyteller.$APP"' && break kill -0 \$PID 2>/dev/null || { echo "@@ $APP MURIÓ a los \${j}s" >> /salida/log.txt; break; } sleep 1; j=\$((j+1)) done echo "@@ ventana en el árbol a los \${j}s" >> /salida/log.txt /usr/bin/swaymsg -t get_tree -r > /salida/arbol.json 2>/dev/null # Margen para el PRIMER FRAME: bajo llvmpipe aparecer en el árbol y haber pintado no es lo mismo. sleep 10 /usr/bin/grim /salida/captura.png 2>>/salida/log.txt && echo "@@ grim ok" >> /salida/log.txt sleep 1 /usr/bin/swaymsg exit 2>/dev/null ) & exec /usr/bin/sway -d > /salida/sway.log 2>&1 EOF bwrap \ --overlay-src "$ALPINE" --overlay-src "$RFS" \ --overlay-src "$L18" --overlay-src "$MLP" --overlay-src "$GC" \ --tmp-overlay / \ --dev-bind /dev /dev --proc /proc --bind /sys /sys \ --tmpfs /tmp --tmpfs /run --unshare-pid \ --bind "$SAL" /salida \ --uid 0 --gid 0 \ --setenv PATH /usr/bin:/bin:/usr/sbin:/sbin \ /bin/sh /salida/dentro.sh || echo "(bwrap salió con $?)" echo "── veredicto ──────────────────────────────────────────────" grep -c "\"app_id\": *\"ai.storyteller.$APP\"" "$SAL/arbol.json" 2>/dev/null \ | sed 's/^/ventanas con el app_id: /' || echo "ventanas con el app_id: 0 (no hay árbol)" cat "$SAL/log.txt" 2>/dev/null | sed 's/^/ /' echo "── log de la app (últimas 25) ─────────────────────────────" tail -25 "$SAL/app.log" 2>/dev/null | sed 's/^/ /' echo "── colores (1 color = sólo el fondo de swaybg ⇒ NADIE dibujó) ──" python3 "$(dirname "$0")/png-colores.py" "$SAL/antes.png" "$SAL/captura.png" 2>/dev/null || ls -l "$SAL"/*.png