# cosmic-applets — los applets del panel: reloj, audio, red, batería, workspaces, botón de apps… # # ── POR QUÉ APARECE RECIÉN AHORA, Y CÓMO SE SUPO ──────────────────────────────────────────────── # `cosmic-panel` selló y arrancó **perfecto** —lee su config, crea su `wl_output`, dice «Spawning # applets», «Done spawning applets»— y la pantalla no cambió ni un color. La respuesta estaba en esa # misma línea: el panel spawnea TRECE clientes por AppID (`CosmicAppletTime`, `CosmicAppletAudio`, # `CosmicPanelAppButton`…) y **ninguno existía**. Un panel sin applets no es un panel vacío: es un # panel que no tiene nada que medir, así que no se dibuja. # # La lección, que ya apareció en GNOME con los typelibs: **un componente puede arrancar sin errores y # no pintar porque lo que le falta es un HIJO, no una librería.** El log del padre se lee sano. # # ── UN BINARIO, VEINTE NOMBRES ────────────────────────────────────────────────────────────────── # El diseño de upstream es un multiplexor: se compila UN `cosmic-applets` y cada applet es un # **symlink** con el nombre que el panel invoca (`just _link_applet` = `ln -sf`); el binario despacha # por `argv[0]`. Por eso el install de abajo son veinte symlinks y no veinte copias — y por eso una # sola receta cubre todo el panel. # # `cosmic-panel-button` es el segundo miembro por defecto del workspace: es el que provee los tres # botones (apps, launcher, workspaces), que no son applets sino otra cosa con el mismo mecanismo. name = "cosmic-applets" version = "1.5.0" license = "GPL-3.0" [source] tarball = "https://github.com/pop-os/cosmic-applets/archive/epoch-1.5.0/cosmic-applets-epoch-1.5.0.tar.gz" sha256 = "ac9328e58f5e9cb9c7561a2ce4af212d4916d97c820741f0959366c7e1a0e3ba" # ⚠ EL PARCHE ARREGLA UNA URL, Y LA URL RARA ES INTENCIONAL RÍO ARRIBA. # El manifiesto apunta a `https://github.com/pop-os/cosmic-protocols//` — con DOS barras al final. No # es un dedazo: es el truco con el que upstream hace que cargo trate esa fuente como DISTINTA de la # URL normal, para que el `[patch."…/cosmic-protocols"]` de al lado no se apunte a sí mismo (cargo # rechaza un patch que reemplaza una fuente por ella misma). Pero GitHub **devuelve 404** a # `/pop-os/cosmic-protocols//info/refs`, así que `cargo vendor` no puede clonar y el build muere en el # fetch, antes de compilar una línea. # # La barra se MUEVE al medio: `https://github.com/pop-os//cosmic-protocols`. Es exactamente la forma # que usa `cosmic-comp` —que por eso construyó sin parche—, y GitHub sí la tolera. Se toca # `Cargo.toml` **y** `Cargo.lock` juntos: cambiar sólo uno rompe el `--locked` del build hermético. # # El primer intento fue `.git` en vez de `//`, y **falló por la razón que hace que el truco exista**: # cargo NORMALIZA el `.git`, así que el patch pasaba a apuntar a la misma fuente que reemplaza y # cortó con «patches must point to different sources». O sea que la barra de más no es reemplazable # por cualquier variante cosmética: tiene que ser una que cargo considere OTRA fuente y que el # servidor sepa servir. Sólo la del medio cumple las dos. patches = ["cosmic-applets-protocols-url.patch"] [build] compiler = "zig-cc" target = "x86_64-linux-musl" link = "dynamic" [build.phases] # Fase compile CUSTOM, y por un motivo concreto: hay que construir DOS binarios (`cosmic-applets` y # `cosmic-panel-button`, los `default-members` del workspace) y `cargo rustc --` sólo admite uno. Se # usa `cargo build`, replicando a mano el setup del lab —el wrapper zig-cc que sanea el triple de # Alpine y el `-crt-static`— porque `resolve_phases` no autogenera la fase si la receta la trae. # # `-C target-feature=-crt-static` va en RUSTFLAGS y no tras `--`: acá es SEGURO al revés que en # helix, porque lo que rompe los proc-macros es forzar `+crt-static` (un proc-macro es un dylib PIC); # desactivarlo es justo lo que ya necesitan. compile = ''' printf '%s\n' '#!/bin/sh' 'for a do' 'case "$a" in --target=*) a=--target=x86_64-linux-musl ;; esac' 'set -- "$@" "$a"' 'shift' 'done' 'exec zig cc -mcpu=baseline "$@"' > "$PWD/.hammer-zig-cc" chmod +x "$PWD/.hammer-zig-cc" RF="-C linker=$PWD/.hammer-zig-cc -C target-feature=-crt-static" rustc -vV | grep -q 'host: .*-alpine-' || RF="$RF -C link-self-contained=no" CC="$PWD/.hammer-zig-cc" RUSTFLAGS="$RF" cargo build --release --locked --offline ''' # El `just install` traducido. Los `.desktop` los genera el build en `target/xdgen/`; se copian si # están (`|| true`) en vez de exigirlos, porque su ausencia no impide que el panel spawnee al applet # —lo invoca por nombre de binario— y sí haría fallar el sellado por un fichero decorativo. install = ''' mkdir -p /out/usr/bin /out/usr/share/applications /out/usr/share/icons \ /out/usr/share/dbus-1/services /out/usr/share/dbus-1/system.d cp target/release/cosmic-applets /out/usr/bin/cosmic-applets cp target/release/cosmic-panel-button /out/usr/bin/cosmic-panel-button chmod 755 /out/usr/bin/cosmic-applets /out/usr/bin/cosmic-panel-button for a in cosmic-app-list cosmic-applet-a11y cosmic-applet-audio cosmic-applet-input-sources \ cosmic-applet-battery cosmic-applet-bluetooth cosmic-applet-minimize \ cosmic-applet-network cosmic-applet-notifications cosmic-applet-power \ cosmic-applet-status-area cosmic-applet-tiling cosmic-applet-time \ cosmic-applet-workspaces cosmic-panel-button; do ln -sf cosmic-applets /out/usr/bin/$a done # El panel invoca los tres botones por su propio nombre, no por el del multiplexor. for b in cosmic-panel-app-button cosmic-panel-launcher-button cosmic-panel-workspaces-button; do ln -sf cosmic-panel-button /out/usr/bin/$b done [ -d target/xdgen ] && cp target/xdgen/*.desktop /out/usr/share/applications/ 2>/dev/null || true for d in */data/icons; do [ -d "$d" ] && cp -r "$d"/. /out/usr/share/icons/ 2>/dev/null || true; done [ -d cosmic-app-list/data/default_schema ] && mkdir -p /out/usr/share/cosmic && cp -r cosmic-app-list/data/default_schema/. /out/usr/share/cosmic/ 2>/dev/null || true cp cosmic-applet-network/data/dbus-1/system.d/*.conf /out/usr/share/dbus-1/system.d/ 2>/dev/null || true ''' [deps] # `dbus-shared` se suma a las cuatro de todo cliente: los applets de red, bluetooth y status-area # hablan D-Bus por `libdbus-sys` (FFI a la C), no por zbus como el resto de la suite. Su `build.rs` # no da error legible — hace `panic!` a secas en la línea 25—, así que el mensaje útil es el nombre # del crate y no lo que dice. # # ⚠ Y tiene que ser la variante COMPARTIDA, no el `dbus` del corpus. Declarar `dbus` alcanza para que # `build.rs` pase (le basta el `.pc`, y el paquete del daemon lo trae) y el error aparece **una hora # después, en el enlace final**: `unable to find dynamic system library 'dbus-1'`. El corpus sólo # empaqueta `libdbus-1.a` ahí; el `.so` vive en `dbus-shared`. Que el build.rs esté contento no dice # nada sobre si el linker va a encontrar la biblioteca — son dos preguntas distintas y las contesta # pkg-config una y el linker la otra. El resto de la cola ya lo hacía bien (settings-daemon, pipewire); # ésta era la única receta de incoming-cosmic que pedía `dbus` a secas. build = ["libxkbcommon", "pkgconf", "libudev-zero", "libinput", "dbus-shared"]