🎥 cosmic: pipewire ARRANCA, y el portal ya figura como cliente suyo

El bloqueo decisivo de ScreenCast no era una receta que faltara: `/usr/bin/pipewire`
estaba en la imagen desde que entró como dep de `cosmic-settings-daemon`, pero NADIE
lo lanzaba. En una distro con systemd de usuario eso lo hace `pipewire.socket`; acá
no hay tal cosa, así que es tarea de `cosmic-start` — el mismo patrón que el bus de
sistema y que login1.

Va justo después de asegurar XDG_RUNTIME_DIR y NO junto al bus de sesión, a
propósito: pipewire no necesita D-Bus para arrancar, sólo el runtime dir donde abre
su socket. Ahí sirve para los dos modos (bare y session) sin duplicar el bloque. Y se
espera EL SOCKET, no el pid: un demonio que muere al instante deja el pid existiendo
un rato, y esperar por él da un OK falso.

Medido dentro de la VM, cada paso una pregunta distinta:

  pipewire OK (socket pipewire-0, pid 189)      ¿abre socket?
  pw-cli info 0  → Core/4, 1.2.7, core.daemon   ¿SIRVE a un cliente?
  pw-cli ls Factory → "client-node"             ¿tiene lo que ScreenCast usa?
  pw-cli ls Client  → "xdg-desktop-portal"      ¡el portal YA está conectado!

La última línea es el veredicto: el frontend del portal aparece como cliente del
demonio, una conexión que antes no podía existir y que es justo la que `Start`
necesita para negociar el nodo. `client-node` es la factory con que el backend lo crea.

Sin regresión, con la cadena entera: `cosmic-screenshot` levanta la UI INTERACTIVA
del portal (región/ventana/pantalla + Capture + Save to Pictures) y el click deja un
PNG de 53.590 bytes. Esa UI no estaba documentada — el registro anterior sólo probaba
la ruta no-interactiva. Escritorio completo: 2414 colores (el panel mutilado da 130).

Lo que sigue faltando son DOS cosas distintas, y ninguna es un one-liner:
  · el handshake de punta a punta pide un cliente `ashpd` PERSISTENTE — el portal
    asocia la sesión al *sender*, así que CreateSession con un dbus-send y
    SelectSources con otro se rechazan por venir de nombres únicos distintos;
  · wireplumber, que separa "hay stream de video" de "hay audio". Ni construido está.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-05 09:46:21 -04:00
co-authored by Claude Opus 5
parent 2e26a45060
commit e43ce95786
4 changed files with 94 additions and 9 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

+55 -3
View File
@@ -966,6 +966,57 @@ aunque se escribiera el cliente `ashpd`, `Start` no tendría con quién negociar
Arreglo: lanzarlo desde `cosmic-start`. (Para AUDIO además falta `wireplumber`, que ni siquiera está
construido — ver la decisión de audio del proyecto.)
### ✅ HECHO: el demonio arranca y el portal se conecta a él (2026-08-05)
`cosmic-start` lanza `/usr/bin/pipewire` justo después de asegurar `XDG_RUNTIME_DIR`, y espera **el
socket, no el pid** — la misma disciplina que el compositor, y por el mismo motivo: un demonio que
muere al instante deja el pid «existiendo» un rato y esperar por él da un OK falso.
Va en ese punto del script a propósito: pipewire **no necesita D-Bus** para arrancar, sólo el
runtime dir donde abre su socket. Ponerlo ahí lo hace válido para los dos modos —`bare` y
`session`— sin duplicar el bloque.
Lo medido dentro de la VM, en este orden, porque cada paso responde una pregunta distinta:
```
== cosmic-qemu :: pipewire OK (socket pipewire-0, pid 189) ← ¿abre socket?
$ pw-cli info 0
type: PipeWire:Interface:Core/4 version: "1.2.7" ← ¿SIRVE a un cliente?
core.daemon = "true" core.name = "pipewire-0"
$ pw-cli ls Factory | grep factory.name
… "client-node" … ← ¿tiene lo que ScreenCast usa?
$ pw-cli ls Client | grep application.name
application.name = "pw-cli"
application.name = "xdg-desktop-portal" ← ¡EL PORTAL YA ESTÁ CONECTADO!
```
La última línea es el veredicto. **El frontend del portal aparece como cliente del demonio de
pipewire** — una conexión que antes no podía existir, y que es exactamente la que `Start` necesita
para negociar el nodo del stream. `client-node` es la factory con la que el backend lo crea.
**Y sin regresión, medido con la cadena entera**: `cosmic-screenshot` desde `cosmic-term` levanta la
**UI interactiva del portal** —un toolbar con los tres modos (región, ventana, pantalla), `Capture` y
`Save to Pictures`—, y el click en `Capture` deja un PNG de 53.590 bytes en
`/root/Pictures/Screenshots/`. Evidencia: `docs/evidencia/cosmic-portal-ui-captura-2026-08-05.png`.
Esa UI no estaba documentada: el registro anterior sólo probaba la ruta no-interactiva.
El escritorio completo con pipewire corriendo:
`docs/evidencia/cosmic-escritorio-con-pipewire-2026-08-05.png` (2414 colores distintos — el panel
mutilado da 130).
**Lo que sigue faltando, y son dos cosas separadas:**
- **El handshake de ScreenCast de punta a punta** necesita un cliente `ashpd` **persistente**, y no
hay atajo: el portal asocia la sesión al *sender* de D-Bus, así que `CreateSession` con un
`dbus-send` y `SelectSources` con otro se rechazan por venir de nombres únicos distintos. Un
cliente de prueba es una receta nueva, no un one-liner.
- **`wireplumber`**, que es lo que separa «hay stream de video» de «hay audio». Sin gestor de sesión
pipewire arranca y sirve, pero no descubre tarjetas ni enruta. Para ScreenCast alcanza; para sonido
no. Ni siquiera está construido.
**Y de paso se corrigió un comentario desactualizado de `cosmic-start`** que decía que
`cosmic-settings-daemon` «todavía no se puede construir acá (arrastra pipewire)». Es falso hace
tiempo: ese daemon está sellado y corre. Un comentario viejo manda a buscar un bloqueo que ya no
@@ -973,9 +1024,10 @@ existe, y eso cuesta igual que un bug.
## Lo que falta, en orden
1. **Arrancar el demonio de pipewire desde `cosmic-start`**, que es lo que destraba ScreenCast de
verdad; después, un cliente `ashpd` para ejercer el handshake y, de paso, capturar la URI del
`FileChooser` que `dbus-send` no puede ver.
1. ~~Arrancar el demonio de pipewire desde `cosmic-start`~~ **✅ hecho (2026-08-05)**, y el portal ya
figura como cliente suyo. Queda el **cliente `ashpd` persistente** para ejercer el handshake de
ScreenCast y, de paso, capturar la URI del `FileChooser` que `dbus-send` no puede ver — es una
receta, no un one-liner, por lo del *sender* de D-Bus explicado arriba. Y `wireplumber` para audio.
2. **Decidir `gvfs`** (ver la corrección de arriba: las piezas ya están selladas, lo que falta es la
decisión sobre la segunda glib). Destrabaría los montajes remotos de cosmic-files y su applet.
3. **Enchufar la tienda a `.swm`**: servir `org.freedesktop.PackageKit` y encender la feature