Sube el pin de portal-probe a a5c959b (persist_mode + --wait + flush línea a línea).
MEDIDO en la OptiPlex 3060 (UHD 630, iris por hardware), handshake completo de 4 pasos:
[3/4] Start → streams: node id 75, position (0,0), size (1920,1080), source_type 1
restore_token "d2b5b24f-2f2c-44e2-9a41-014f965b389b"
[4/4] OpenPipeWireRemote → fd = 5 → socket:[84493]
== portal-probe screencast: OK ==
Y PipeWire tiene el nodo `cosmic-screencast` como Video/Source con puertos capture_0/1.
El muro no era la GPU. La hipótesis del EGL por software queda falsificada: en metal, con
iris real, el síntoma era idéntico hasta que se mandó `persist_mode`. Era un strlen(NULL)
en xdg-desktop-portal 1.18.4 (ver el commit anterior), que mataba al portal justo antes de
emitir el Response.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
87 lines
5.3 KiB
TOML
87 lines
5.3 KiB
TOML
# portal-probe — la SONDA del portal XDG. La única receta de la campaña cuyo producto no es una
|
|
# pieza del escritorio sino un INSTRUMENTO para medirlo.
|
|
#
|
|
# ── QUÉ MIDE, Y POR QUÉ NINGUNA HERRAMIENTA EXISTENTE SIRVE ─────────────────────────────────────
|
|
# Los portales no son RPC: son un protocolo asíncrono en dos tiempos. Cada método devuelve al
|
|
# instante un object path de `Request`, y el resultado de verdad llega DESPUÉS como señal
|
|
# `org.freedesktop.portal.Request.Response` sobre ese path. `dbus-send` ya salió para entonces ⇒
|
|
# devuelve el path y nunca el resultado. Eso es lo que impidió capturar la URI del `FileChooser`.
|
|
#
|
|
# Y hay un segundo muro, más duro: **el portal ata la sesión al SENDER**. `CreateSession` con un
|
|
# `dbus-send` y `SelectSources` con otro llegan desde nombres únicos DISTINTOS y el portal rechaza
|
|
# el segundo. No hay forma de encadenar el handshake desde el shell; hace falta UNA conexión que
|
|
# viva todo el intercambio. Por eso esto es un binario y no un script.
|
|
#
|
|
# ── POR QUÉ EN C Y NO CON `ashpd` ───────────────────────────────────────────────────────────────
|
|
# `ashpd` es el cliente de portales del ecosistema Rust —es lo que usan `cosmic-screenshot` y
|
|
# `cosmic-files`— y era el camino obvio. Pero el árbol fuente de esta receta es el repo del PROPIO
|
|
# hammer (no hay modo `path` en `[source]`: sólo git y tarball), así que usar ashpd significaría
|
|
# sumar ~150 crates al `Cargo.lock` de la herramienta de build por una sonda de diagnóstico.
|
|
#
|
|
# `libdbus` ya está en el corpus, cuesta cero deps nuevas, y `dbus` provee `libdbus-1.a` ⇒ la sonda
|
|
# sale **estática, sin un solo NEEDED**, que es justo lo que uno quiere de un instrumento: que no
|
|
# dependa de nada de aquello que va a medir. Y sobre todo: en C el protocolo SE VE. Una sonda cuyo
|
|
# valor es documentar un handshake no debería esconderlo tras una biblioteca que lo abstrae.
|
|
#
|
|
# ── EL VENDOREO QUE SE PAGA IGUAL ───────────────────────────────────────────────────────────────
|
|
# El árbol fuente es el repo hammer entero, cuya raíz tiene `Cargo.toml` ⇒ `detect_build_system`
|
|
# dice Cargo y el fetch vendorea el workspace. No se puede apagar (`cargo_vendor` sólo FUERZA, no
|
|
# desactiva). Es un costo de tiempo en el fetch, no de corrección: la fase `compile` de acá abajo
|
|
# ignora cargo por completo y llama a `zig cc` sobre un único `.c`. Mismo peaje que paga `hammerd`.
|
|
name = "portal-probe"
|
|
version = "0.1.0"
|
|
|
|
[source]
|
|
# El repo del propio hammer. El `commit` es el identificador inmutable (la URL es sólo locator y no
|
|
# entra al hash). Subir el commit cuando la sonda avance — y sólo entonces: fijar el commit es lo
|
|
# que hace que un instrumento de medición sea él mismo reproducible.
|
|
repo = "ssh://gitea@git.gioser.net:2345/sergio/hammer.git"
|
|
commit = "a5c959b6186acef13260cf6b42aa1cbfc1d56f34"
|
|
|
|
[build]
|
|
compiler = "zig-cc"
|
|
target = "x86_64-linux-musl"
|
|
# Estático de verdad, y acá SÍ es la decisión correcta en vez de la coherencia con la suite: el
|
|
# resto de los clientes van dinámicos porque `wayland-client` hace `dlopen` (ver el runbook). Esta
|
|
# sonda no toca wayland, y un instrumento que arrastra NEEDED puede fallar por una razón que no es
|
|
# la que está midiendo.
|
|
link = "static"
|
|
|
|
[build.phases]
|
|
# Sin configure: es un fichero.
|
|
configure = "true"
|
|
|
|
# `zig cc` directo. Los flags de dbus salen de su `.pc`, que vive en el artefacto del store y el
|
|
# sandbox proyecta en /usr — de ahí el PKG_CONFIG_PATH. Los dos `-I` de dbus son SIEMPRE dos y no
|
|
# uno: `dbus-arch-deps.h` es generado y vive bajo `lib/dbus-1.0/include`, no junto al resto de los
|
|
# headers. Un `-I` solo compila hasta que algo incluye `dbus.h` de verdad.
|
|
#
|
|
# ⚠ EL `-L/usr/lib` HAY QUE PONERLO A MANO, y el motivo es un choque de supuestos entre dos
|
|
# herramientas: **pkg-config OMITE los `-L` de directorios que considera estándar del sistema**
|
|
# (`/usr/lib` lo es), asumiendo que el linker ya los busca. Cierto para un `cc` nativo; FALSO para
|
|
# `zig cc` cruzando a `x86_64-linux-musl`, que trae sus propias rutas y no da nada por sentado.
|
|
# Resultado: `--libs --static` devuelve `-ldbus-1` pelado y zig responde
|
|
# `unable to find static system library 'dbus-1' … searched paths: none` — un error que suena a
|
|
# «falta la librería» cuando la librería está ahí y lo que falta es la ruta.
|
|
compile = '''
|
|
export PKG_CONFIG_PATH=/usr/lib/pkgconfig:/usr/share/pkgconfig
|
|
CF=$(pkg-config --cflags dbus-1)
|
|
LF=$(pkg-config --libs --static dbus-1)
|
|
echo "cflags: $CF"
|
|
echo "libs : $LF"
|
|
zig cc -target x86_64-linux-musl -static -O2 -Wall -Wextra \
|
|
-o portal-probe tools/portal-probe/portal-probe.c $CF -L/usr/lib $LF
|
|
'''
|
|
|
|
install = '''
|
|
mkdir -p /out/usr/bin
|
|
cp portal-probe /out/usr/bin/portal-probe
|
|
chmod 755 /out/usr/bin/portal-probe
|
|
'''
|
|
|
|
[deps]
|
|
# `dbus` por la librería y los headers; `pkgconf` para que el `.pc` se pueda leer. Nada más: la
|
|
# sonda no dibuja, no abre ventana y no habla wayland — igual que `cosmic-screenshot`, que también
|
|
# es un cliente puro de portal.
|
|
build = ["dbus", "pkgconf"]
|