Files
takana/scripts/cosmic/atuq-en-cosmic.sh
T
Sergio 756ed9c6a6 atuq: el compositor NO era la causa — con cosmic-comp nesteado el navegador pinta
El §6.10.ter dejó dos variables cambiando a la vez (compositor y arranque real) y ninguna medición
que las separe. `scripts/cosmic/atuq-en-cosmic.sh` saca la primera de encima en ~2 min por vuelta,
sin QEMU y sin imagen: sway headless de andamio, cosmic-comp nesteado encima por winit, atuq adentro,
y `grim` capturando del lado de sway. El `--control` corre EL MISMO binario de atuq —el del cierre
hidratado para la imagen— directo sobre sway.

Las dos capturas coinciden al píxel en la región de la página (586331 px magenta, mismo bbox), y no
es que el navegador se escape a sway: antes de lanzarlo, la ventana de cosmic-comp ocupa 1276x637 en
ese mismo rectángulo, y el MOZ_LOG del widget ve `mode output size 1276 x 637` con cosmic contra
`1280 x 720` en el control. Las dos corridas enteras difieren en 1130 píxeles, todos en las barras
de título.

⇒ cosmic-comp no es el que impide la ventana. Queda como variable el arranque de verdad: kms/DRM
sobre virtio-gpu en vez de winit, el PID1 de arje, el seat.

De paso queda anotado el camino de buffers cuando SÍ funciona —`WaylandBufferSHM`, memoria
compartida y no dmabuf—, que es la línea de base contra la que comparar la traza de la imagen.

Y `scripts/cosmic/atuq-en-imagen.py` para medir allá: arranca la imagen, maneja el serial, lanza el
navegador con el mismo MOZ_LOG y pide capturas por QMP. La corrida del §6.10.ter fue a mano y no
dejó un solo log que se pueda releer.
2026-09-14 14:11:49 +00:00

173 lines
8.8 KiB
Bash
Executable File

#!/bin/sh
# atuq-en-cosmic.sh — ¿el navegador PINTA SU VENTANA bajo `cosmic-comp`? (SDD 26 §6.10.ter)
#
# scripts/cosmic/atuq-en-cosmic.sh # atuq dentro de cosmic-comp
# scripts/cosmic/atuq-en-cosmic.sh --control # el MISMO atuq, pero directo sobre sway
#
# ── POR QUÉ EXISTE ────────────────────────────────────────────────────────────────────────────
# El 2026-09-14 se arrancó por primera vez una IMAGEN DE DISCO con COSMIC y `atuq` adentro: el
# navegador arranca, sus extensiones corren, WebRender inicializa… y la ventana no aparece nunca.
# Bajo `sway` headless el mismo artefacto pinta perfecto. Entre los dos casos cambian DOS cosas a la
# vez —el compositor (cosmic-comp+llvmpipe contra sway+pixman) y el arranque real contra `bwrap`—,
# así que ninguna medición de las que había separa una de la otra.
#
# Este arnés cambia UNA sola: el compositor. Todo lo demás —el mismo cierre `escritorio-cosmic`
# hidratado, el mismo binario de `atuq`, la misma jaula— queda fijo, y `--control` corre ese mismo
# `atuq` sobre sway sin tocar nada más. Cuesta ~2 min por vuelta en vez de armar una imagen de 12 G
# y arrancarla en QEMU sin KVM.
#
# ── LA CADENA ─────────────────────────────────────────────────────────────────────────────────
# sway (headless, pixman) → cosmic-comp (winit, cliente de sway) → atuq
# `grim` captura del lado de SWAY, o sea que fotografía la ventana de cosmic-comp con lo que haya
# dentro. sway es andamio: no lo prueba nada, sólo le da a cosmic-comp una pantalla donde vivir.
#
# ── LA EVIDENCIA ES UN DIFF DE PÍXELES, Y ADEMÁS SE MIRA EL ÁRBOL ─────────────────────────────
# Se captura ANTES de lanzar el navegador y DESPUÉS. Un log en verde es compatible con una pantalla
# vacía —es exactamente lo que pasó en la imagen— así que el veredicto es cuántos píxeles cambiaron.
# Y se guarda el `MOZ_LOG` del widget: si la ventana se crea pero nunca recibe su `configure`, eso
# sólo se ve ahí.
#
# env: RFS_COSMIC (def /mnt/cosecha/cosmic-rootfs) cierre de escritorio-cosmic
# RFS_SWAY (def /mnt/cosecha/escritorios/sway-rootfs) el andamio
# MESA (def el artefacto vigente de mesa-llvmpipe) GL por software para cosmic-comp
# ESPERA (def 60) segundos para que el navegador pinte
# OUT (def un temporal) dónde quedan capturas y logs
set -eu
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
RFS_COSMIC="${RFS_COSMIC:-/mnt/cosecha/cosmic-rootfs}"
RFS_SWAY="${RFS_SWAY:-/mnt/cosecha/escritorios/sway-rootfs}"
ALPINE="$ROOT/.dev-fs/alpine"
ESPERA="${ESPERA:-60}"
CONTROL=0
for a in "$@"; do
case "$a" in
--control) CONTROL=1 ;;
*) echo "✗ opción desconocida: $a" >&2; exit 1 ;;
esac
done
# mesa-llvmpipe por HASH VIGENTE, no por el más reciente del store (con dos artefactos del mismo
# paquete conviviendo, la fecha miente). Es el mismo criterio de cosmic-nested.sh.
if [ -z "${MESA+x}" ]; then
MH=$(./target/release/takana --store /mnt/cosecha/store hash recipes/mesa-llvmpipe.toml 2>/dev/null | tr -d '\n' | sed 's/b3://')
MESA=$(ls -d /mnt/cosecha/store/"$MH"-mesa-llvmpipe 2>/dev/null || true)
fi
[ -d "$RFS_COSMIC" ] || { echo "✗ falta el cierre de cosmic en $RFS_COSMIC" >&2
echo " scripts/hydrate-profile.py escritorio-cosmic --store /mnt/cosecha/store --into $RFS_COSMIC" >&2; exit 1; }
[ -d "$RFS_SWAY" ] || { echo "✗ falta el rootfs de sway en $RFS_SWAY" >&2; exit 1; }
[ -x "$RFS_COSMIC/usr/bin/atuq" ] || { echo "✗ el cierre no trae /usr/bin/atuq" >&2; exit 1; }
[ -n "${MESA:-}" ] || echo " ⚠ sin mesa-llvmpipe sellado: cosmic-comp no va a poder iniciar EGL" >&2
OUT="${OUT:-$(mktemp -d)}"; mkdir -p "$OUT"
echo "== salida: $OUT"
# Una página de UN SOLO COLOR imposible de confundir con nada del escritorio: si aparece, apareció
# la ventana del navegador y no un repintado de cosmic.
cat > "$OUT/pagina.html" <<'HTML'
<!doctype html><meta charset="utf-8"><title>atuq en cosmic</title>
<body style="margin:0;background:#ff00ff">
<h1 style="color:#000;font:40px monospace;padding:40px">ATUQ PINTA</h1>
<script>if (window.dump) { dump("ATUQ-PAGINA cargada\n");
setInterval(() => dump("ATUQ-PAGINA viva\n"), 10000); }</script>
HTML
mkdir -p "$OUT/perfil"
cat > "$OUT/perfil/user.js" <<'JS'
user_pref("browser.dom.window.dump.enabled", true);
user_pref("browser.shell.checkDefaultBrowser", false);
JS
cat > "$OUT/dentro.sh" <<'ADENTRO'
#!/bin/sh
export XDG_RUNTIME_DIR=/run/user/0 HOME=/root LANG=C XDG_DATA_DIRS=/usr/share
export XDG_CURRENT_DESKTOP=COSMIC XDG_SESSION_TYPE=wayland RUST_BACKTRACE=1
export LIBGL_ALWAYS_SOFTWARE=1 LIBGL_DRIVERS_PATH=/usr/lib/dri
mkdir -p "$XDG_RUNTIME_DIR" /root /dev/shm /etc; chmod 700 "$XDG_RUNTIME_DIR"
[ -s /etc/passwd ] || echo "root:x:0:0:root:/root:/bin/sh" > /etc/passwd
[ -s /etc/machine-id ] || tr -d - < /proc/sys/kernel/random/uuid > /etc/machine-id
lanzar_atuq() { # $1 = WAYLAND_DISPLAY donde tiene que pintar
WAYLAND_DISPLAY="$1" \
MOZ_ENABLE_WAYLAND=1 GDK_BACKEND=wayland \
MOZ_DISABLE_CONTENT_SANDBOX=1 MOZ_DISABLE_RDD_SANDBOX=1 MOZ_DISABLE_UTILITY_SANDBOX=1 \
MOZ_DISABLE_GMP_SANDBOX=1 MOZ_DISABLE_SOCKET_PROCESS_SANDBOX=1 \
MOZ_LOG='Widget:5,WidgetWayland:5,WaylandBackend:5,timestamp' \
MOZ_LOG_FILE=/salida/moz \
/usr/bin/atuq --no-remote --profile /salida/perfil file:///salida/pagina.html \
> /salida/atuq.log 2>&1 &
echo "@@ atuq lanzado (pid $!) contra $1"
}
(
i=0
while [ ! -S /run/user/0/wayland-1 ] && [ $i -lt 60 ]; do sleep 1; i=$((i+1)); done
[ -S /run/user/0/wayland-1 ] || { echo "@@ sin socket de sway"; exit 1; }
export WAYLAND_DISPLAY=wayland-1
/usr/bin/swaybg -c '#1a4b8c' >/dev/null 2>&1 &
sleep 2
export DBUS_SESSION_BUS_ADDRESS=$(/usr/bin/dbus-daemon --session --fork --print-address 2>/dev/null)
echo "@@ dbus=${DBUS_SESSION_BUS_ADDRESS:-VACIO}"
if [ "${CONTROL:-0}" = "1" ]; then
echo "@@ CONTROL: el navegador va directo sobre sway (sin cosmic-comp)"
DEST=wayland-1
else
echo "@@ arrancando cosmic-comp nesteado sobre sway…"
cosmic-comp >/salida/cosmic.log 2>&1 &
CC=$!
i=0; WD=""
while [ $i -lt 60 ]; do
WD=$(ls /run/user/0/wayland-* 2>/dev/null | grep -v lock | grep -v 'wayland-1$' | head -1)
[ -n "$WD" ] && break
kill -0 $CC 2>/dev/null || { echo "@@ cosmic-comp murió antes del socket:"; tail -25 /salida/cosmic.log; exit 1; }
i=$((i+1)); sleep 1
done
[ -n "$WD" ] || { echo "@@ cosmic-comp sin socket en 60 s:"; tail -25 /salida/cosmic.log; exit 1; }
DEST=$(basename "$WD")
echo "@@ cosmic-comp OK ($DEST)"
sleep 5
fi
/usr/bin/grim /salida/antes.png && echo "@@ captura ANTES"
lanzar_atuq "$DEST"
sleep "${ESPERA:-60}"
/usr/bin/grim /salida/despues.png && echo "@@ captura DESPUES"
echo "@@ procesos atuq: $(ps -o comm= 2>/dev/null | grep -c atuq)"
sleep 1
/usr/bin/swaymsg exit 2>/dev/null
) &
export WLR_BACKENDS=headless WLR_HEADLESS_OUTPUTS=1 WLR_RENDERER=pixman
exec /usr/bin/sway -d 2>&1
ADENTRO
# El ORDEN de los overlays manda: alpine trae la libc, sway el andamio, el cierre de cosmic pisa lo
# que comparta con él, y mesa-llvmpipe va ÚLTIMO porque el cierre trae la mesa de Intel real
# (iris_dri) y en una máquina sin GPU eso no inicia EGL.
TIEMPO=$((ESPERA + 180))
timeout "$TIEMPO" bwrap \
--overlay-src "$ALPINE" --overlay-src "$RFS_SWAY" --overlay-src "$RFS_COSMIC" \
${MESA:+--overlay-src "$MESA"} --tmp-overlay / \
--bind "$OUT" /salida --dev /dev --proc /proc --tmpfs /run --tmpfs /tmp \
--dev-bind-try /dev/dri /dev/dri \
--unshare-pid --unshare-uts --hostname atuq-en-cosmic \
--uid 0 --gid 0 --die-with-parent \
--setenv PATH /usr/bin:/bin:/usr/sbin:/sbin \
--setenv CONTROL "$CONTROL" --setenv ESPERA "$ESPERA" \
/bin/sh /salida/dentro.sh > "$OUT/log.txt" 2>&1 || true
grep -a '@@' "$OUT/log.txt" || true
[ -f "$OUT/antes.png" ] && [ -f "$OUT/despues.png" ] || {
echo "✗ no hubo capturas — mirá $OUT/log.txt" >&2; tail -20 "$OUT/log.txt" >&2; exit 1; }
python3 - "$OUT/antes.png" "$OUT/despues.png" <<'PY'
import sys
from PIL import Image, ImageChops
a, b = (Image.open(p).convert("RGB") for p in sys.argv[1:3])
d = ImageChops.difference(a, b).convert("L")
cambiados = d.width * d.height - d.histogram()[0]
magenta = sum(n for n, c in b.getcolors(maxcolors=1 << 24) if c == (255, 0, 255))
print(f" píxeles cambiados: {cambiados} magenta de la página: {magenta}")
PY
echo " capturas: $OUT/antes.png $OUT/despues.png"
echo " logs: $OUT/atuq.log $OUT/cosmic.log $OUT/moz.*"