# mirada-compositor — el compositor Wayland teselante de mirada (sobre smithay). Es el Cuerpo que # maneja DRM/GBM/EGL/libseat/libinput directo y dentro del cual corre `mirada-greeter` como cliente. # Cierra la cadena de sesión gráfica de tawasuyu. # # Receta Cargo (patrón arje-zero/mirada-greeter): monorepo tawasuyu al commit fijado 9a17fefc (reusa # el árbol vendoreado). `-p mirada-compositor`, link DINÁMICO (smithay enlaza libdrm/gbm/seat/input # + dlopen de EGL/wayland/xkbcommon). # # Sin la fase custom del greeter: mirada-compositor NO usa llimphi-ui ⇒ no arrastra accesskit/atspi # (nada de LOCKSTEP_XML_PATH). auth-core → PAM sí (linux-pam). `foreign-av` NO enlaza ffmpeg: spawnea # el BINARIO ffmpeg en runtime (sólo si wallpaper=video), así que no hace falta construir ffmpeg. # # Build-deps que smithay (default features) enlaza por -sys/pkg-config: drm-sys→libdrm, gbm-sys→mesa, # libseat-sys→seatd, input-sys→libinput, libudev-sys→libudev-zero. wayland-server.pc → libffi/expat. name = "mirada-compositor" version = "0.0.1" license = "MIT" [source] repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git" commit = "de491e951687ef7a02e19d2592f8cc2c4b60fd66" # tawasuyu COMMITEA su propio `vendor/` (smithay 0.7.0 parcheado por `[patch.crates-io]` POR # RUTA: 159 líneas en 4 ficheros —flip async DRM, y dos de layer-shell—). El `cargo vendor` de # takana vendorea por default a `vendor/`, que convierte ESE dir en reemplazo de fuente, donde # cada crate debe traer `.cargo-checksum.json` — que el patch nunca tuvo (`git ls-tree`: no # existió nunca). El pin viejo (9a17fefc, 14-jul) es ANTERIOR a que ese `vendor/` naciera # (a37815634, 21-jul), por eso esta receta no lo traía: salta al mover el pin. No entra en # `hash_inputs`. cargo_vendor_dir = ".hammer-cargo-vendor" [build] compiler = "zig-cc" target = "x86_64-linux-musl" link = "dynamic" flags = ["-p", "mirada-compositor"] [deps] # libxkbcommon (smithay lo enlaza, no sólo dlopen) + pixman (composición CPU de smithay). build = ["mesa", "wayland", "wayland-protocols", "libdrm", "seatd", "linux-pam", "libinput", "libudev-zero", "libevdev", "mtdev", "libxkbcommon", "pixman", "expat", "zlib", "zstd", "libffi", "pkgconf"] # ── LA CARD QUE ARRANCA EL ESCRITORIO (`[[service]]`, 2026-10-15) ───────────────────────────────── # Hasta hoy esta receta no declaraba servicio, y la consecuencia estaba MEDIDA y no escrita: la Card # que lanza el compositor en la máquina del operador existe porque un script de parche # (`tawasuyu:scripts/declarar-mirada-en-la-semilla.sh`) la inyectó en la semilla a mano. O sea que # **una instalación de cero arranca el sistema y no arranca el escritorio**, y nada lo avisa: el # génesis no se queja de lo que nadie le declaró. Los otros cuatro escritorios ya pasan por # `takana service-cards` (lo usan `servidor-image.sh` y los `*-image.sh` de gnome/kde/cosmic); # mirada se armaba con un `/sbin/init` escrito a mano por `mirada-usb.sh`, que sirve para un medio # live y no deja nada en el disco. # # La declaración es metadato —fuera de `hash_inputs`, como `[[setuid]]`, `[[user]]` y `license`— así # que entra en una receta YA SELLADA sin mover un solo `ArtifactHash`. # # ⚠ **`seatd` va en la MISMA receta y no en la suya**, por el invariante de `validate_all`: dos # recetas no pueden reclamar lo mismo, y acá lo que se declara es el ORDEN de arranque de un # escritorio —seatd primero, el compositor después— que es una propiedad de mirada y no de seatd. # Sin seatd vivo el compositor no obtiene el seat y muere con el DRM ocupado. [[service]] label = "seatd" id = "01M4ZQ2GXTPZ8RVZRBVZCBE94G" exec = "/usr/bin/seatd" scope = "system" restart = { initial_ms = 500, max_ms = 20000 } [[service]] label = "mirada" id = "01M4ZQ2GXTQJ26NFQGXEE1D7BX" exec = "/usr/bin/mirada-compositor --drm --greeter" scope = "system" # El backoff lo hace arje: la versión a mano de esta Card llevaba un `sh -c` de quince líneas que # contaba intentos en `/run/mirada-intentos` y se quedaba quieto al tercero. Eso es exactamente lo # que `restart` hace, con el tope arriba — un compositor que no abre y reintenta cada 100 ms deja la # máquina inservible, y el techo de 30 s es lo que la vuelve diagnosticable. restart = { initial_ms = 1000, max_ms = 30000 } # ⚠ Un Ente NO hereda el PATH de ningún shell, y el compositor LANZA hijos (el greeter, el riel, la # terminal del menú). El PATH de esta Card es el que hereda la sesión entera, y hasta el 2026-10-14 # decía `/usr/bin:/bin:/usr/sbin:/sbin` — sin `/usr/local/bin`, que es donde vive todo lo instalado # a mano. El operador tenía `claude` instalado y la máquina contestaba `claude: not found`. # # Los bin del hogar NO van acá a propósito: los agrega el propio compositor para el usuario que # inicia sesión (`utilidades::path_de_usuario`), y clavarlos en la Card los dejaría apuntando al # hogar de UNA persona en una imagen que instala cualquiera. envp = [ ["PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"], ["HOME", "/root"], ["XDG_RUNTIME_DIR", "/run/arje"], ["XDG_SEAT", "seat0"], ["XDG_SESSION_TYPE", "wayland"], # El layout por defecto; el instalador pregunta el teclado y lo puede reescribir en la Card. ["XKB_DEFAULT_LAYOUT", "us"], # Sin esto libxkbcommon no encuentra las reglas y el teclado no responde una tecla. Lo aporta # `xkeyboard-config`, declarado en el perfil el mismo día que esto. ["XKB_CONFIG_ROOT", "/usr/share/X11/xkb"], ["MIRADA_GREETER_BIN", "/usr/bin/mirada-greeter"], ["RUST_LOG", "info"], ]