cursores: cosmic y sway corrían con el puntero INVISIBLE — receta propia, y el vigía medía mal
`vigia-imagen.py` daba ✗ en cursores en DOS de los cuatro escritorios. No es cosmético: con el cursor por software —obligatorio en virtio-gpu y en todo render por CPU— el compositor dibuja la imagen que le da el TEMA, y sin tema el ratón se mueve invisible. cosmic llegó a 43/43 y sway a 173/173 así, porque un tema de cursor no es dep de build de nadie: sólo entra si se DECLARA. `adwaita-cursors` (corpus, 48.1, data-only): del mismo tarball que `adwaita-icon-theme` pero SÓLO `Adwaita/cursors/` — 39 ficheros y 14 MB, sin un icono. Promover el tema entero habría regalado a sway y a cosmic los iconos de GNOME, que está anotado como decisión pendiente y no como olvido. Las dos cosas que el tarball no trae y la receta fabrica: · los nombres X11 heredados (`left_ptr`, `xterm`, `watch`, `hand2`…) son enlaces que genera el `meson.build` de upstream. El mapa se PARSEA de ahí, no se copia: copiado envejece en silencio. Si el origen de un enlace no existe, la fase falla — upstream pone un `files()` como aserción. · `/usr/share/icons/default/index.theme` con `Inherits=Adwaita`. Sin `XCURSOR_THEME` en el entorno, libXcursor y wlroots buscan el tema llamado literalmente `default`; sin él no hay puntero AUNQUE Adwaita esté instalado. Es el eslabón que hace que ande sin configuración. ⚠ no declarar esta receta junto a `adwaita-icon-theme`: chocan en `Adwaita/cursors/*`. Y el vigía estaba midiendo el invariante de al lado: exigía `index.theme` en el directorio para contar un tema, que es correcto para ICONOS —la búsqueda XDG recorre `Directories=`— y falso para CURSORES, porque libXcursor abre `<tema>/cursors/<nombre>` directo y el índice sólo hace falta para seguir un `Inherits=`. Con la receta instalada seguía diciendo «NINGÚN tema de cursor». De paso queda anotado en `targets.toml` que el comentario de cosmic decía «sin ellos arranca sin puntero» sobre `cosmic-icons`, que no trae cursores: describía una protección que no existía. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CGyBj4QyeCZiwLMkP9GJp6
This commit is contained in:
@@ -1,23 +1,23 @@
|
||||
{
|
||||
"schema": "hammer-build-state/1",
|
||||
"totals": {
|
||||
"recipes": 856,
|
||||
"nodes": 858,
|
||||
"sealed": 856,
|
||||
"recipes": 857,
|
||||
"nodes": 859,
|
||||
"sealed": 857,
|
||||
"ajeno": 2
|
||||
},
|
||||
"by_class": {
|
||||
"ajeno": 2,
|
||||
"c": 203,
|
||||
"go": 362,
|
||||
"gui": 35,
|
||||
"gui": 36,
|
||||
"kernel": 6,
|
||||
"rust": 250
|
||||
},
|
||||
"debt_by_class": {},
|
||||
"by_queue": {
|
||||
"corpus": {
|
||||
"sealed": 819,
|
||||
"sealed": 820,
|
||||
"ajeno": 2
|
||||
},
|
||||
"incoming-cosmic": {
|
||||
@@ -36,9 +36,9 @@
|
||||
"sealed": 75
|
||||
},
|
||||
"escritorio-cosmic": {
|
||||
"raices": 39,
|
||||
"clausura": 133,
|
||||
"sealed": 133
|
||||
"raices": 40,
|
||||
"clausura": 134,
|
||||
"sealed": 134
|
||||
},
|
||||
"escritorio-mirada": {
|
||||
"raices": 14,
|
||||
@@ -104,6 +104,25 @@
|
||||
"perfiles": [],
|
||||
"dependientes_total": 0
|
||||
},
|
||||
"adwaita-cursors": {
|
||||
"iname": "adwaita-cursors",
|
||||
"version": "48.1",
|
||||
"link": "dynamic",
|
||||
"compiler": "zig-cc",
|
||||
"deps": [],
|
||||
"cls": "gui",
|
||||
"queue": "corpus",
|
||||
"foreign": false,
|
||||
"hash": "b3:22ae0ff6369e6f15cb6810ddd979d95ebe38307e8da668c1210d9434ef9b5b05",
|
||||
"state": "sealed",
|
||||
"blocked_by": [],
|
||||
"unblocks": 0,
|
||||
"perfiles": [
|
||||
"escritorio-cosmic",
|
||||
"escritorio-sway"
|
||||
],
|
||||
"dependientes_total": 0
|
||||
},
|
||||
"adwaita-hello": {
|
||||
"iname": "adwaita-hello",
|
||||
"version": "1.7.6",
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
{
|
||||
"schema": "hammer-build-state/1",
|
||||
"totals": {
|
||||
"recipes": 834,
|
||||
"nodes": 836,
|
||||
"sealed": 834,
|
||||
"recipes": 835,
|
||||
"nodes": 837,
|
||||
"sealed": 835,
|
||||
"ajeno": 2
|
||||
},
|
||||
"by_class": {
|
||||
"ajeno": 2,
|
||||
"c": 202,
|
||||
"go": 362,
|
||||
"gui": 35,
|
||||
"gui": 36,
|
||||
"kernel": 6,
|
||||
"rust": 229
|
||||
},
|
||||
"debt_by_class": {},
|
||||
"by_queue": {
|
||||
"corpus": {
|
||||
"sealed": 820,
|
||||
"sealed": 821,
|
||||
"ajeno": 2
|
||||
},
|
||||
"incoming-wlr": {
|
||||
@@ -41,9 +41,9 @@
|
||||
"sealed": 33
|
||||
},
|
||||
"escritorio-sway": {
|
||||
"raices": 70,
|
||||
"clausura": 173,
|
||||
"sealed": 173
|
||||
"raices": 71,
|
||||
"clausura": 174,
|
||||
"sealed": 174
|
||||
}
|
||||
},
|
||||
"sin_perfil": 645,
|
||||
@@ -104,6 +104,25 @@
|
||||
"perfiles": [],
|
||||
"dependientes_total": 0
|
||||
},
|
||||
"adwaita-cursors": {
|
||||
"iname": "adwaita-cursors",
|
||||
"version": "48.1",
|
||||
"link": "dynamic",
|
||||
"compiler": "zig-cc",
|
||||
"deps": [],
|
||||
"cls": "gui",
|
||||
"queue": "corpus",
|
||||
"foreign": false,
|
||||
"hash": "b3:22ae0ff6369e6f15cb6810ddd979d95ebe38307e8da668c1210d9434ef9b5b05",
|
||||
"state": "sealed",
|
||||
"blocked_by": [],
|
||||
"unblocks": 0,
|
||||
"perfiles": [
|
||||
"escritorio-cosmic",
|
||||
"escritorio-sway"
|
||||
],
|
||||
"dependientes_total": 0
|
||||
},
|
||||
"adwaita-hello": {
|
||||
"iname": "adwaita-hello",
|
||||
"version": "1.7.6",
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
{
|
||||
"schema": "hammer-build-state/1",
|
||||
"totals": {
|
||||
"recipes": 821,
|
||||
"nodes": 823,
|
||||
"sealed": 821,
|
||||
"recipes": 822,
|
||||
"nodes": 824,
|
||||
"sealed": 822,
|
||||
"ajeno": 2
|
||||
},
|
||||
"by_class": {
|
||||
"ajeno": 2,
|
||||
"c": 189,
|
||||
"go": 362,
|
||||
"gui": 35,
|
||||
"gui": 36,
|
||||
"kernel": 6,
|
||||
"rust": 229
|
||||
},
|
||||
"debt_by_class": {},
|
||||
"by_queue": {
|
||||
"corpus": {
|
||||
"sealed": 821,
|
||||
"sealed": 822,
|
||||
"ajeno": 2
|
||||
}
|
||||
},
|
||||
@@ -96,6 +96,25 @@
|
||||
"perfiles": [],
|
||||
"dependientes_total": 0
|
||||
},
|
||||
"adwaita-cursors": {
|
||||
"iname": "adwaita-cursors",
|
||||
"version": "48.1",
|
||||
"link": "dynamic",
|
||||
"compiler": "zig-cc",
|
||||
"deps": [],
|
||||
"cls": "gui",
|
||||
"queue": "corpus",
|
||||
"foreign": false,
|
||||
"hash": "b3:22ae0ff6369e6f15cb6810ddd979d95ebe38307e8da668c1210d9434ef9b5b05",
|
||||
"state": "sealed",
|
||||
"blocked_by": [],
|
||||
"unblocks": 0,
|
||||
"perfiles": [
|
||||
"escritorio-cosmic",
|
||||
"escritorio-sway"
|
||||
],
|
||||
"dependientes_total": 0
|
||||
},
|
||||
"adwaita-hello": {
|
||||
"iname": "adwaita-hello",
|
||||
"version": "1.7.6",
|
||||
|
||||
@@ -407,6 +407,10 @@ paquetes = [
|
||||
# tipografía. Ninguno es dep de build de nadie y sin ellos el escritorio arranca roto — sin puntero,
|
||||
# sin teclado o con tofu.
|
||||
"cosmic-icons", "hicolor-icon-theme", "xkeyboard-config", "dejavu-fonts",
|
||||
# ⚠ «sin puntero» lo decía este comentario desde que se escribió y NO era cierto: `cosmic-icons`
|
||||
# instala iconos de aplicación, no cursores, así que este perfil llegó a 43/43 con el puntero
|
||||
# INVISIBLE. Lo cazó `vigia-imagen.py` el 2026-09-04. Los cursores son su propia raíz.
|
||||
"adwaita-cursors",
|
||||
# `dejavu-fonts-nerd` es la MISMA DejaVu Sans Mono parcheada con Nerd Fonts (~10.000 glifos de
|
||||
# iconos: Powerline, Font Awesome, Devicons…) que usan starship, lsd, eza, neovim y las
|
||||
# statuslines; sin ellos dibujan cuadraditos. Se AÑADE, no reemplaza: la licencia de Bitstream
|
||||
@@ -520,6 +524,11 @@ paquetes = [
|
||||
"dejavu-fonts-nerd",
|
||||
"xkeyboard-config", # sin datos XKB: «xkbcommon: ERROR: failed to add default include path
|
||||
# /usr/share/X11/xkb», y sway no completa el seat
|
||||
# Cursores. Mismo caso que las fuentes y el XKB, y con el mismo modo de fallo silencioso: con el
|
||||
# cursor por software el compositor dibuja lo que le da el TEMA, y sin tema el puntero se mueve
|
||||
# invisible. Este perfil llegó a 173/173 sin uno. Trae además `/usr/share/icons/default`, que es
|
||||
# lo que buscan libXcursor y wlroots cuando nadie fijó `XCURSOR_THEME` — o sea, siempre acá.
|
||||
"adwaita-cursors",
|
||||
# ── LAS TRES `.so` QUE sway PIDE Y EL CORPUS SÓLO PRODUCE COMO `.a` ─────────────────────────
|
||||
# `sway` es `link = "dynamic"` a propósito (dlopea los drivers DRI de mesa) y sale con
|
||||
# `NEEDED libz.so.1 / libexpat.so.1 / libffi.so.8`. Las canónicas son `--disable-shared`, así que
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
# adwaita-cursors 48.1 — SÓLO los cursores de Adwaita, en el CORPUS.
|
||||
#
|
||||
# ══ EL HUECO QUE TAPA ══════════════════════════════════════════════════════════════════════════
|
||||
# `vigia-imagen.py` mide un invariante que ninguna métrica de clausura ve: **≥1 tema de cursor con
|
||||
# `cursors/` poblado**. El 2026-09-04 daba ✗ en DOS de los cuatro escritorios —`escritorio-cosmic`
|
||||
# y `escritorio-sway`—, y eso no es cosmético: con el cursor por software (obligatorio en
|
||||
# virtio-gpu y en cualquier render por CPU) el compositor dibuja la imagen que le da el tema, así
|
||||
# que sin tema **el puntero se mueve invisible**. Es la misma figura que las fuentes de GNOME y que
|
||||
# los iconos de KDE: sellado ≠ usable, y el agujero no es dep de build de nadie.
|
||||
#
|
||||
# ══ POR QUÉ UNA RECETA NUEVA Y NO PROMOVER `adwaita-icon-theme` ════════════════════════════════
|
||||
# Los cursores viven DENTRO de `adwaita-icon-theme` (recipes/incoming-gnome/), que son ~5000
|
||||
# ficheros de tema de ICONOS. Promoverla al corpus para conseguir un puntero le regalaría a sway y
|
||||
# a cosmic el tema de iconos de GNOME — y eso está declarado como una DECISIÓN pendiente, no como
|
||||
# un olvido (`vigia-imagen.py` lo marca ⊘ en sway a propósito). Esta receta corta por lo sano:
|
||||
# mismo tarball, misma versión, **sólo `Adwaita/cursors/`** (~1 MB), sin un solo icono.
|
||||
#
|
||||
# ⚠ **NO declarar esta receta y `adwaita-icon-theme` en el MISMO perfil**: las dos instalan
|
||||
# `/usr/share/icons/Adwaita/cursors/*` y chocarían fichero a fichero — la misma colisión por la que
|
||||
# zathura no entra en `escritorio-kde` (dos poppler). `escritorio-gnome` ya tiene sus cursores por
|
||||
# el tema completo y NO lleva ésta.
|
||||
#
|
||||
# ══ LAS DOS COSAS QUE EL TARBALL NO TRAE Y HAY QUE FABRICAR ════════════════════════════════════
|
||||
# 1. **Los nombres X11 heredados.** El tarball trae los nombres CSS (`default`, `pointer`, `text`…);
|
||||
# `left_ptr`, `hand2`, `xterm`, `watch` y compañía son ENLACES que genera el `meson.build`
|
||||
# (`cursor_symlinks`). Una app que pida `left_ptr` —y las viejas piden eso— no encontraría nada.
|
||||
# El mapa se PARSEA de `meson.build`, no se copia a mano: la lista autoritativa es upstream, y
|
||||
# copiada envejece en silencio. Si el origen del enlace no existe, la fase FALLA: upstream pone
|
||||
# ahí un `files()` justamente como aserción, y perderla convertiría un cambio de upstream en un
|
||||
# enlace roto que nadie ve.
|
||||
# 2. **El tema `default`.** Sin `XCURSOR_THEME` en el entorno, libXcursor y wlroots buscan el tema
|
||||
# literalmente llamado `default`; si no existe, no hay puntero AUNQUE `Adwaita` esté instalado.
|
||||
# Por eso se escribe `/usr/share/icons/default/index.theme` con `Inherits=Adwaita`. Es el
|
||||
# eslabón que hace que esto funcione en una imagen SIN configuración, que es el caso real.
|
||||
#
|
||||
# Los `.cur` son los cursores de Windows: upstream los excluye en la instalación de Linux
|
||||
# (`exclude_files: win32_cursors`) y acá también, por el mismo motivo.
|
||||
#
|
||||
# Data-only: no hay un compilador involucrado.
|
||||
name = "adwaita-cursors"
|
||||
version = "48.1"
|
||||
license = "LGPL-3.0-or-later OR CC-BY-SA-3.0"
|
||||
|
||||
[source]
|
||||
tarball = "https://download.gnome.org/sources/adwaita-icon-theme/48/adwaita-icon-theme-48.1.tar.xz"
|
||||
sha256 = "cbfe9b86ebcd14b03ba838c49829f7e86a7b132873803b90ac10be7d318a6e12"
|
||||
|
||||
[build]
|
||||
compiler = "zig-cc"
|
||||
target = "x86_64-linux-musl"
|
||||
link = "dynamic"
|
||||
|
||||
[build.phases]
|
||||
configure = "true"
|
||||
compile = "true"
|
||||
install = '''
|
||||
set -e
|
||||
CUR=/out/usr/share/icons/Adwaita/cursors
|
||||
mkdir -p "$CUR"
|
||||
|
||||
# los cursores propiamente dichos, sin los .cur de Windows
|
||||
find Adwaita/cursors -maxdepth 1 -type f ! -name '*.cur' -exec install -Dm0644 {} "$CUR"/ \;
|
||||
# MEDIDO, no supuesto: 48.1 trae 37 cursores reales (nombres CSS) + 31 `.cur` de Windows. El
|
||||
# primer intento puso el piso en 50 «por si acaso» y la fase falló contra el tarball CORRECTO —
|
||||
# un guardián calibrado por encima de la escala real no protege: bloquea.
|
||||
N=$(ls -1 "$CUR" | wc -l)
|
||||
[ "$N" -ge 30 ] || { echo "sólo $N cursores: el tarball cambió de forma" >&2; exit 1; }
|
||||
|
||||
# los nombres X11 heredados, leídos del meson.build de upstream (no copiados a mano)
|
||||
sed -n '/cursor_symlinks = {/,/^ }/p' meson.build \
|
||||
| sed -n "s/^ *'\([^']*\)': *\[\([^]]*\)\].*/\1 \2/p" \
|
||||
| while read -r SRC RESTO; do
|
||||
[ -e "$CUR/$SRC" ] || { echo "el mapa nombra un cursor ausente: $SRC" >&2; exit 1; }
|
||||
echo "$RESTO" | tr ',' '\n' | tr -d " '" | while read -r DST; do
|
||||
[ -n "$DST" ] && ln -sf "$SRC" "$CUR/$DST"
|
||||
done
|
||||
done
|
||||
|
||||
# el tema `default`: sin esto, una imagen sin XCURSOR_THEME no encuentra NINGÚN cursor
|
||||
mkdir -p /out/usr/share/icons/default
|
||||
cat > /out/usr/share/icons/default/index.theme <<'EOF'
|
||||
[Icon Theme]
|
||||
Name=Default
|
||||
Comment=Alias al tema de cursores real
|
||||
Inherits=Adwaita
|
||||
EOF
|
||||
|
||||
# la comprobación que no se puede cumplir por accidente: el nombre que pide TODA app vieja
|
||||
[ -e "$CUR/left_ptr" ] || { echo "sin left_ptr: el mapa de enlaces no se aplicó" >&2; exit 1; }
|
||||
[ -e "$CUR/default" ] || { echo "sin el cursor 'default': el tema no sirve" >&2; exit 1; }
|
||||
'''
|
||||
|
||||
[deps]
|
||||
build = []
|
||||
+12
-5
@@ -30,7 +30,8 @@
|
||||
# FALLBACK obligatorio del estándar y no trae iconos propios: es el contrato, no el
|
||||
# contenido.
|
||||
# cursores ≥1 tema con `cursors/` poblado. Con el cursor por software —obligatorio en virtio-gpu—
|
||||
# sin tema el puntero se mueve INVISIBLE.
|
||||
# sin tema el puntero se mueve INVISIBLE. A diferencia de los iconos, acá NO se exige
|
||||
# `index.theme`: libXcursor abre `<tema>/cursors/<nombre>` directo.
|
||||
# fuentes ≥1 `.ttf/.otf/.ttc/.pfb`. fontconfig es el motor que BUSCA fuentes, no una fuente.
|
||||
# terminal ≥1 `.desktop` con `TerminalEmulator` en Categories. Un escritorio sin terminal no es
|
||||
# uno incompleto: es uno del que no se puede salir cuando algo falla.
|
||||
@@ -118,8 +119,14 @@ def escanear(nodos):
|
||||
if os.path.isdir(base):
|
||||
for t in sorted(os.listdir(base)):
|
||||
td = os.path.join(base, t)
|
||||
if not os.path.exists(os.path.join(td, "index.theme")):
|
||||
continue # un directorio sin index.theme NO es un tema
|
||||
# ⚠ ICONOS y CURSORES no se buscan igual, y medirlos con la misma regla dio un ✗
|
||||
# falso el 2026-09-04: `adwaita-cursors` instalaba `Adwaita/cursors/` poblado y este
|
||||
# vigía seguía diciendo «NINGÚN tema de cursor» porque el directorio no traía
|
||||
# `index.theme`. Para un tema de ICONOS ese requisito es correcto —la búsqueda XDG
|
||||
# recorre `Directories=` y sin el índice el tema no existe—, pero libXcursor y
|
||||
# wlroots abren `<tema>/cursors/<nombre>` DIRECTO; `index.theme` sólo hace falta
|
||||
# para seguir un `Inherits=`. Exigirlo también acá medía el invariante de al lado.
|
||||
tiene_indice = os.path.exists(os.path.join(td, "index.theme"))
|
||||
n_ico = n_cur = 0
|
||||
for dp, _, fn in os.walk(td):
|
||||
for f in fn:
|
||||
@@ -127,11 +134,11 @@ def escanear(nodos):
|
||||
n_ico += 1
|
||||
elif os.path.basename(dp) == "cursors":
|
||||
n_cur += 1
|
||||
if n_ico:
|
||||
if n_ico and tiene_indice:
|
||||
temas.setdefault(t, (nombre, n_ico))
|
||||
if n_cur:
|
||||
cursores.setdefault(t, (nombre, n_cur))
|
||||
if t == "hicolor":
|
||||
if t == "hicolor" and tiene_indice:
|
||||
temas.setdefault("hicolor", (nombre, n_ico))
|
||||
# ── el resto, en UNA pasada por el árbol ────────────────────────────────────────────────
|
||||
for dp, _, fn in os.walk(d):
|
||||
|
||||
Reference in New Issue
Block a user