gnome: dash-to-panel, appindicator y gnome-tweaks — y la lista de activas sale de las recetas
GNOME deja de ser la cáscara: tres extensiones y la app que el proyecto no instala y todo el mundo
termina instalando. El perfil queda 190/190 con 28 raíces, deuda 0.
dash-to-panel v73 junta dash, ventanas y bandeja en una sola barra (lo que más cambia el uso)
appindicator v64 devuelve los ICONOS DE BANDEJA que GNOME quitó; sin ella las apps que usan
StatusNotifierItem corren y no tienen dónde mostrarse
blur-my-shell v72 (ya estaba; se le saca el override, ver abajo)
gnome-tweaks 46.1 tema, iconos, cursor, tipografías, los botones de minimizar/maximizar que
GNOME esconde, y el interruptor de las extensiones
⚠ LA LISTA DE ACTIVAS SE MUEVE A UN SOLO SITIO, y esto era una bomba de relojería. `enabled-extensions`
es un ARRAY: un override de GSettings lo escribe ENTERO. Con la primera extensión el override vivía
en su receta y funcionaba; con la segunda NO se habrían sumado — ganaría la que compile última
(orden alfabético) y las otras quedarían instaladas y MUERTAS, sin un solo error. Ahora la arma
`scripts/gnome/gnome-start-qemu.sh`, que ya compilaba los esquemas al arrancar, enumerando los uuid
presentes en /usr/share/gnome-shell/extensions. La política es «lo que la imagen instala, se
activa»; el dconf del usuario gana sobre el default.
Una receta NO puede ser ese sitio: hammer exige `[source]` en toda receta («missing field `source`»),
así que no hay forma de escribir una receta de pura política. Se probó el bloque contra un árbol de
juguete: lista las dos extensiones, salta un directorio sin metadata.json, el override compila con
stderr vacío y `gsettings get` devuelve las dos. Y si la lista cambia borra `gschemas.compiled` para
forzar recompilación — sin eso, una imagen ya arrancada ignoraría la extensión nueva en silencio.
⚠ EL HALLAZGO CARO: `msgfmt` de gettext-tiny REVIENTA con las formas plurales del árabe. SIGILL,
exit 132, «index 6 out of bounds for type 'size_t[6]'», y deja un .mo de 0 bytes. Reproducido FUERA
de la receta con el binario sellado. No es el idioma sino el mensaje: blur-my-shell compila su
ar.po sin problema porque no tiene NINGÚN plural (msgstr[5] = 0); el de tweaks tiene exactamente
uno. Acá se saca `ar` del LINGUAS y se pierde la traducción de UNA app, con el diagnóstico escrito
en la receta. ARREGLARLO ES OTRA UNIDAD DE TRABAJO: gettext-tiny la usan 108 recetas.
Cada receta usa el mecanismo de SU upstream, que no es el mismo en las tres:
blur-my-shell `make build` llama a `gnome-extensions pack` —el CLI que nuestro shell apaga— así
que se copia el árbol a mano, con el layout LEÍDO del zip de EGO y comparado
contra él (idéntico, sin sobras ni faltantes)
dash-to-panel su Makefile tiene un `install` que honra DESTDIR y hace lo de un paquete de
distro: gschema y locale a los directorios GLOBALES. ⚠ `VERSION=73` se pasa a
mano porque sin ella el Makefile hace `git describe` y el árbol viene por
`git archive`, sin `.git` ⇒ metadata quedaría con el marcador "version": 9999
appindicator meson. ⚠ `-Dlocal_install=disabled` explícito: en `auto` decide mirando si el uid
es 0, o sea que hoy acierta POR ACCIDENTE — y si el lab dejara de correr como
root instalaría en $HOME/.local y el artefacto sellaría vacío. Y `jq` va en deps
aunque sea JavaScript puro: su meson saca el uuid del metadata.json con jq
⚠ gnome-tweaks NO costó ninguna receta nueva, y eso hubo que medirlo: su meson declara siete deps
mínimas de runtime y las siete ya estaban selladas. La que parecía traer una cadena de Python
entera —`pygobject-3.0`— la provee `py3-gobject`, que YA ESTABA en el corpus con otro nombre y
publica `pygobject-3.0.pc`. El nombre no es el hecho, otra vez.
Sí costó dos deps que el configure reclamó y que son el patrón `.pc Requires` → `[deps].build`:
`appstream` (la pide `libadwaita-1.pc` y el error culpa a libadwaita, que está bien instalada) y
`desktop-file-utils` (meson la busca como PROGRAMA para `update-desktop-database`).
Sus deps de RUNTIME —python3 y py3-gobject— van declaradas: es una app de Python, si no están en la
imagen se instala y no arranca, y ningún build lo delata.
Las cuatro licencias, verificadas en la fuente pineada y NINGUNA leída del COPYING —cuyo apéndice
«How to Apply» trae siempre la frase «or any later version»—: blur-my-shell del README del commit,
dash-to-panel y appindicator de la cabecera de sus fuentes, gnome-tweaks de su etiqueta SPDX.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
Semántico sayk'uy
Mana ima sutichaypas t'ikrakurqanchu: qillqalla, yachachiylla utaq willaylla t'ikrakurqan.
8 qillqakuna · +481 −80
- docs/state/build-state-gnome.json +186 −61
- docs/state/drenaje.json +1 −1
- docs/state/targets.toml +15 −0
- recipes/incoming-gnome/gnome-shell-extension-appindicator.toml +65 −0
- recipes/incoming-gnome/gnome-shell-extension-blur-my-shell.toml +9 −18
- recipes/incoming-gnome/gnome-shell-extension-dash-to-panel.toml +69 −0
- recipes/incoming-gnome/gnome-tweaks.toml +97 −0
- scripts/gnome/gnome-start-qemu.sh +39 −0
diff --git a/docs/state/build-state-gnome.json b/docs/state/build-state-gnome.json
index 83e02025..73246257 100644
--- a/docs/state/build-state-gnome.json
+++ b/docs/state/build-state-gnome.json
@@ -1,16 +1,16 @@
{
"schema": "hammer-build-state/1",
"totals": {
- "recipes": 921,
- "nodes": 923,
- "sealed": 921,
+ "recipes": 924,
+ "nodes": 926,
+ "sealed": 924,
"ajeno": 2
},
"by_class": {
"ajeno": 2,
"c": 272,
"go": 362,
- "gui": 48,
+ "gui": 51,
"kernel": 6,
"rust": 233
},
@@ -21,7 +21,7 @@
"ajeno": 2
},
"incoming-gnome": {
- "sealed": 64
+ "sealed": 67
}
},
"by_profile": {
@@ -36,9 +36,9 @@
"sealed": 80
},
"escritorio-gnome": {
- "raices": 25,
- "clausura": 183,
- "sealed": 183
+ "raices": 28,
+ "clausura": 190,
+ "sealed": 190
},
"escritorio-mirada": {
"raices": 17,
@@ -46,7 +46,7 @@
"sealed": 41
}
},
- "sin_perfil": 661,
+ "sin_perfil": 660,
"orphan_deps": [],
"topo_ok": true,
"nodes": {
@@ -500,7 +500,7 @@
"perfiles": [
"escritorio-gnome"
],
- "dependientes_total": 6
+ "dependientes_total": 7
},
"argo-rollouts": {
"iname": "argo-rollouts",
@@ -1356,6 +1356,7 @@
"unblocks": 0,
"perfiles": [
"cli",
+ "escritorio-gnome",
"escritorio-sway"
],
"dependientes_total": 4
@@ -1530,7 +1531,7 @@
"perfiles": [
"escritorio-gnome"
],
- "dependientes_total": 9
+ "dependientes_total": 10
},
"caligula": {
"iname": "caligula",
@@ -3102,7 +3103,7 @@
"escritorio-kde",
"escritorio-sway"
],
- "dependientes_total": 10
+ "dependientes_total": 11
},
"curlie": {
"iname": "curlie",
@@ -3391,7 +3392,7 @@
"escritorio-kde",
"escritorio-sway"
],
- "dependientes_total": 0
+ "dependientes_total": 1
},
"devspace": {
"iname": "devspace",
@@ -4236,7 +4237,7 @@
"escritorio-mirada",
"escritorio-sway"
],
- "dependientes_total": 66
+ "dependientes_total": 67
},
"expat-shared": {
"iname": "expat-shared",
@@ -4809,7 +4810,7 @@
"escritorio-kde",
"escritorio-sway"
],
- "dependientes_total": 22
+ "dependientes_total": 23
},
"foot": {
"iname": "foot",
@@ -4935,7 +4936,7 @@
"escritorio-kde",
"escritorio-sway"
],
- "dependientes_total": 26
+ "dependientes_total": 27
},
"freeze": {
"iname": "freeze",
@@ -4979,7 +4980,7 @@
"escritorio-kde",
"escritorio-sway"
],
- "dependientes_total": 31
+ "dependientes_total": 32
},
"fselect": {
"iname": "fselect",
@@ -5206,7 +5207,7 @@
"perfiles": [
"escritorio-gnome"
],
- "dependientes_total": 8
+ "dependientes_total": 9
},
"gdk-pixbuf-shared": {
"iname": "gdk-pixbuf-shared",
@@ -5360,7 +5361,7 @@
"escritorio-kde",
"escritorio-sway"
],
- "dependientes_total": 104
+ "dependientes_total": 107
},
"gh": {
"iname": "gh",
@@ -5450,7 +5451,7 @@
"perfiles": [
"escritorio-gnome"
],
- "dependientes_total": 25
+ "dependientes_total": 26
},
"gi-foreign-typelibs": {
"iname": "gi-foreign-typelibs",
@@ -5992,7 +5993,7 @@
"perfiles": [
"escritorio-gnome"
],
- "dependientes_total": 43
+ "dependientes_total": 46
},
"glib-introspected": {
"iname": "glib-introspected",
@@ -6021,7 +6022,7 @@
"perfiles": [
"escritorio-gnome"
],
- "dependientes_total": 29
+ "dependientes_total": 30
},
"glib-shared": {
"iname": "glib-shared",
@@ -6245,6 +6246,35 @@
],
"dependientes_total": 0
},
+ "gnome-shell-extension-appindicator": {
+ "iname": "gnome-shell-extension-appindicator",
+ "version": "64",
+ "link": "dynamic",
+ "compiler": "zig-cc",
+ "deps": [
+ "gettext-tiny",
+ "glib",
+ "jq",
+ "libffi",
+ "meson",
+ "pcre2",
+ "pkgconf",
+ "python3",
+ "samurai",
+ "zlib"
+ ],
+ "cls": "gui",
+ "queue": "incoming-gnome",
+ "foreign": false,
+ "hash": "b3:624995cae88d2a8997a3ea601569b83d3c255bf5dabfba34d8662bd1d8769683",
+ "state": "sealed",
+ "blocked_by": [],
+ "unblocks": 0,
+ "perfiles": [
+ "escritorio-gnome"
+ ],
+ "dependientes_total": 0
+ },
"gnome-shell-extension-blur-my-shell": {
"iname": "gnome-shell-extension-blur-my-shell",
"version": "72",
@@ -6260,7 +6290,98 @@
"cls": "gui",
"queue": "incoming-gnome",
"foreign": false,
- "hash": "b3:6b39a579c1d58e333c9c1d27875ba015705a340b883638afcde166fd6e6ac9d9",
+ "hash": "b3:c6fc6933317d86357e01d2cb056873f1713be64a349775d366ca6f5ac90d80ce",
+ "state": "sealed",
+ "blocked_by": [],
+ "unblocks": 0,
+ "perfiles": [
+ "escritorio-gnome"
+ ],
+ "dependientes_total": 0
+ },
+ "gnome-shell-extension-dash-to-panel": {
+ "iname": "gnome-shell-extension-dash-to-panel",
+ "version": "73",
+ "link": "dynamic",
+ "compiler": "zig-cc",
+ "deps": [
+ "gettext-tiny",
+ "glib",
+ "libffi",
+ "make",
+ "pcre2",
+ "zlib"
+ ],
+ "cls": "gui",
+ "queue": "incoming-gnome",
+ "foreign": false,
+ "hash": "b3:620ee7a11e13f0da06358aaa0eaf524145f91d0e8c8a9debd74cc923a41a6aff",
+ "state": "sealed",
+ "blocked_by": [],
+ "unblocks": 0,
+ "perfiles": [
+ "escritorio-gnome"
+ ],
+ "dependientes_total": 0
+ },
+ "gnome-tweaks": {
+ "iname": "gnome-tweaks",
+ "version": "46.1",
+ "link": "dynamic",
+ "compiler": "zig-cc",
+ "deps": [
+ "appstream",
+ "cairo-shared",
+ "curl",
+ "desktop-file-utils",
+ "expat",
+ "fontconfig-shared",
+ "freetype-shared",
+ "fribidi",
+ "gdk-pixbuf",
+ "gettext-tiny",
+ "gi-foreign-girs",
+ "glib",
+ "glib-introspected",
+ "gobject-introspection",
+ "graphene",
+ "gsettings-desktop-schemas",
+ "gtk4",
+ "harfbuzz",
+ "iso-codes",
+ "libadwaita",
+ "libdrm",
+ "libepoxy",
+ "libffi",
+ "libgudev",
+ "libjpeg-turbo-shared",
+ "libpng-shared",
+ "libseccomp",
+ "libtiff-shared",
+ "libudev-zero",
+ "libxml2-shared",
+ "libxmlb",
+ "libyaml-shared",
+ "mesa",
+ "meson",
+ "openssl",
+ "pango",
+ "pcre2",
+ "pixman",
+ "pkgconf",
+ "py3-gobject",
+ "python3",
+ "samurai",
+ "wayland",
+ "wayland-protocols",
+ "xkeyboard-config",
+ "zlib-shared",
+ "zstd"
+ ],
+ "cls": "gui",
+ "queue": "incoming-gnome",
+ "foreign": false,
+ "hash": "b3:ef9a900ea574f6d0129716b5ae3bc4b34b73450297adae3aeb2f21a3adb4e840",
"state": "sealed",
"blocked_by": [],
"unblocks": 0,
@@ -6491,7 +6612,7 @@
"perfiles": [
"escritorio-gnome"
],
- "dependientes_total": 31
+ "dependientes_total": 32
},
"gobuster": {
"iname": "gobuster",
@@ -7154,7 +7275,7 @@
"perfiles": [
"escritorio-gnome"
],
- "dependientes_total": 6
+ "dependientes_total": 7
},
"grcov": {
"iname": "grcov",
@@ -7330,7 +7451,7 @@
"perfiles": [
"escritorio-gnome"
],
- "dependientes_total": 4
+ "dependientes_total": 5
},
"gtk3": {
"iname": "gtk3",
@@ -7429,7 +7550,7 @@
"perfiles": [
"escritorio-gnome"
],
- "dependientes_total": 5
+ "dependientes_total": 6
},
"gtk4-hello": {
"iname": "gtk4-hello",
@@ -7710,7 +7831,7 @@
"perfiles": [
"escritorio-gnome"
],
- "dependientes_total": 8
+ "dependientes_total": 9
},
"harfbuzz-shared": {
"iname": "harfbuzz-shared",
@@ -8444,7 +8565,7 @@
"perfiles": [
"escritorio-gnome"
],
- "dependientes_total": 5
+ "dependientes_total": 6
},
"istioctl": {
"iname": "istioctl",
@@ -8614,9 +8735,10 @@
"unblocks": 0,
"perfiles": [
"cli",
+ "escritorio-gnome",
"escritorio-sway"
],
- "dependientes_total": 0
+ "dependientes_total": 1
},
"jql": {
"iname": "jql",
@@ -9788,7 +9910,7 @@
"perfiles": [
"escritorio-gnome"
],
- "dependientes_total": 1
+ "dependientes_total": 2
},
"libarchive": {
"iname": "libarchive",
@@ -9945,7 +10067,7 @@
"escritorio-mirada",
"escritorio-sway"
],
- "dependientes_total": 149
+ "dependientes_total": 150
},
"libei": {
"iname": "libei",
@@ -10022,7 +10144,7 @@
"escritorio-kde",
"escritorio-sway"
],
- "dependientes_total": 21
+ "dependientes_total": 22
},
"libevdev": {
"iname": "libevdev",
@@ -10089,7 +10211,7 @@
"escritorio-mirada",
"escritorio-sway"
],
- "dependientes_total": 110
+ "dependientes_total": 113
},
"libffi-shared": {
"iname": "libffi-shared",
@@ -10289,7 +10411,7 @@
"perfiles": [
"escritorio-gnome"
],
- "dependientes_total": 5
+ "dependientes_total": 6
},
"libgusb": {
"iname": "libgusb",
@@ -10467,7 +10589,7 @@
"escritorio-kde",
"escritorio-sway"
],
- "dependientes_total": 20
+ "dependientes_total": 21
},
"libksba": {
"iname": "libksba",
@@ -10644,7 +10766,7 @@
"escritorio-kde",
"escritorio-sway"
],
- "dependientes_total": 33
+ "dependientes_total": 34
},
"libpsl": {
"iname": "libpsl",
@@ -10747,7 +10869,7 @@
"perfiles": [
"escritorio-gnome"
],
- "dependientes_total": 4
+ "dependientes_total": 5
},
"libsecret": {
"iname": "libsecret",
@@ -10930,7 +11052,7 @@
"escritorio-kde",
"escritorio-sway"
],
- "dependientes_total": 7
+ "dependientes_total": 8
},
"libudev-zero": {
"iname": "libudev-zero",
@@ -10957,7 +11079,7 @@
"escritorio-mirada",
"escritorio-sway"
],
- "dependientes_total": 45
+ "dependientes_total": 46
},
"libunibreak": {
"iname": "libunibreak",
@@ -11190,7 +11312,7 @@
"escritorio-kde",
"escritorio-sway"
],
- "dependientes_total": 10
+ "dependientes_total": 11
},
"libxmlb": {
"iname": "libxmlb",
@@ -11218,7 +11340,7 @@
"perfiles": [
"escritorio-gnome"
],
- "dependientes_total": 7
+ "dependientes_total": 8
},
"libyaml": {
"iname": "libyaml",
@@ -11260,7 +11382,7 @@
"perfiles": [
"escritorio-gnome"
],
- "dependientes_total": 2
+ "dependientes_total": 3
},
"linux": {
"iname": "linux",
@@ -11665,7 +11787,7 @@
"escritorio-mirada",
"escritorio-sway"
],
- "dependientes_total": 118
+ "dependientes_total": 119
},
"mako": {
"iname": "mako",
@@ -11987,7 +12109,7 @@
"escritorio-mirada",
"escritorio-sway"
],
- "dependientes_total": 146
+ "dependientes_total": 147
},
"mesa-llvmpipe": {
"iname": "mesa-llvmpipe",
@@ -12083,7 +12205,7 @@
"escritorio-mirada",
"escritorio-sway"
],
- "dependientes_total": 123
+ "dependientes_total": 125
},
"micro": {
"iname": "micro",
@@ -13312,6 +13434,7 @@
"unblocks": 0,
"perfiles": [
"cli",
+ "escritorio-gnome",
"escritorio-sway"
],
"dependientes_total": 1
@@ -13399,7 +13522,7 @@
"escritorio-kde",
"escritorio-sway"
],
- "dependientes_total": 28
+ "dependientes_total": 29
},
"openssl-threads": {
"iname": "openssl-threads",
@@ -13666,7 +13789,7 @@
"perfiles": [
"escritorio-gnome"
],
- "dependientes_total": 7
+ "dependientes_total": 8
},
"pango-shared": {
"iname": "pango-shared",
@@ -13848,7 +13971,7 @@
"escritorio-kde",
"escritorio-sway"
],
- "dependientes_total": 82
+ "dependientes_total": 85
},
"pcre2-shared": {
"iname": "pcre2-shared",
@@ -14086,7 +14209,7 @@
"escritorio-mirada",
"escritorio-sway"
],
- "dependientes_total": 45
+ "dependientes_total": 46
},
"pkgconf": {
"iname": "pkgconf",
@@ -14110,7 +14233,7 @@
"escritorio-mirada",
"escritorio-sway"
],
- "dependientes_total": 395
+ "dependientes_total": 397
},
"plow": {
"iname": "plow",
@@ -14560,8 +14683,10 @@
"state": "sealed",
"blocked_by": [],
"unblocks": 0,
- "perfiles": [],
- "dependientes_total": 1
+ "perfiles": [
+ "escritorio-gnome"
+ ],
+ "dependientes_total": 2
},
"py3-jinja2": {
"iname": "py3-jinja2",
@@ -14654,7 +14779,7 @@
"escritorio-mirada",
"escritorio-sway"
],
- "dependientes_total": 314
+ "dependientes_total": 316
},
"qrcp": {
"iname": "qrcp",
@@ -15269,7 +15394,7 @@
"escritorio-mirada",
"escritorio-sway"
],
- "dependientes_total": 266
+ "dependientes_total": 268
},
"sassc": {
"iname": "sassc",
@@ -18043,7 +18168,7 @@
"escritorio-mirada",
"escritorio-sway"
],
- "dependientes_total": 160
+ "dependientes_total": 161
},
"wayland-protocols": {
"iname": "wayland-protocols",
@@ -18071,7 +18196,7 @@
"escritorio-mirada",
"escritorio-sway"
],
- "dependientes_total": 57
+ "dependientes_total": 58
},
"websocketd": {
"iname": "websocketd",
@@ -18552,7 +18677,7 @@
"escritorio-kde",
"escritorio-sway"
],
- "dependientes_total": 6
+ "dependientes_total": 7
},
"xorriso": {
"iname": "xorriso",
@@ -18991,7 +19116,7 @@
"escritorio-mirada",
"escritorio-sway"
],
- "dependientes_total": 113
+ "dependientes_total": 115
},
"zlib-ng": {
"iname": "zlib-ng",
@@ -19033,7 +19158,7 @@
"escritorio-mirada",
"escritorio-sway"
],
- "dependientes_total": 85
+ "dependientes_total": 86
},
"zola": {
"iname": "zola",
@@ -19092,7 +19217,7 @@
"escritorio-mirada",
"escritorio-sway"
],
- "dependientes_total": 32
+ "dependientes_total": 33
}
}
}
diff --git a/docs/state/drenaje.json b/docs/state/drenaje.json
index da2cb9ac..6ba8f2ce 100644
--- a/docs/state/drenaje.json
+++ b/docs/state/drenaje.json
@@ -31,7 +31,7 @@
},
"escritorio-gnome": {
"grafo": "docs/state/build-state-gnome.json",
- "nodos": 183,
+ "nodos": 190,
"en_deuda": 0,
"ondas": 0,
"profundidad": 0,
diff --git a/docs/state/targets.toml b/docs/state/targets.toml
index 08451521..bf141439 100644
--- a/docs/state/targets.toml
+++ b/docs/state/targets.toml
@@ -442,7 +442,22 @@ paquetes = [
# con `tar -x` y GNU tar no lee zip, y además el zip es un artefacto que construye EGO a partir
# de ese mismo repo. El layout instalado se verificó CONTRA ese zip: idéntico, sin sobras ni
# faltantes.
+ # ⚠ La LISTA de activas no vive en ninguna receta: `enabled-extensions` es un ARRAY y un override
+ # de GSettings lo escribe entero, así que dos recetas con el suyo no se suman — ganaría la última
+ # y las otras quedarían instaladas y MUERTAS, sin error. La arma `scripts/gnome/gnome-start-qemu.sh`
+ # enumerando los uuid presentes en /usr/share/gnome-shell/extensions antes de compilar los
+ # esquemas. Una receta no puede ser ese sitio: hammer exige `[source]` en toda receta.
"gnome-shell-extension-blur-my-shell",
+ # `dash-to-panel` es la que más cambia el uso diario: junta dash, ventanas y bandeja en una barra.
+ # `appindicator` devuelve los ICONOS DE BANDEJA que GNOME quitó — sin ella, las apps que usan
+ # StatusNotifierItem corren y no tienen dónde mostrarse.
+ "gnome-shell-extension-dash-to-panel", "gnome-shell-extension-appindicator",
+ # ── Y LA APP QUE GNOME NO INSTALA Y TODO EL MUNDO NECESITA ───────────────────────────────────
+ # `gnome-tweaks`: tema, iconos, cursor, tipografías, los botones de minimizar/maximizar que GNOME
+ # esconde, y el interruptor de las extensiones. Es una app de PYTHON, así que su receta declara
+ # `python3` y `py3-gobject` como deps de RUNTIME: sin ellas en la imagen se instala y no arranca,
+ # y ningún build puede delatarlo.
+ "gnome-tweaks",
]
[perfil.escritorio-cosmic]
diff --git a/recipes/incoming-gnome/gnome-shell-extension-appindicator.toml b/recipes/incoming-gnome/gnome-shell-extension-appindicator.toml
new file mode 100644
index 00000000..572c941a
--- /dev/null
+++ b/recipes/incoming-gnome/gnome-shell-extension-appindicator.toml
@@ -0,0 +1,65 @@
+# appindicator 64 — los ICONOS DE BANDEJA que GNOME quitó del shell. Es la extensión que hace que
+# aparezcan en el panel las apps que usan `StatusNotifierItem` / `org.kde.StatusNotifierItem` (y las
+# `libappindicator` viejas): clientes de chat, sincronizadores, gestores de portapapeles. Sin ella,
+# esas apps corren y no tienen dónde mostrarse.
+#
+# Tercera extensión del catálogo. El patrón y el porqué de usar el REPO y no el zip de
+# extensions.gnome.org están en la cabecera de `gnome-shell-extension-blur-my-shell`.
+# El tag `v64` es el que EGO sirve para shell 48, preguntado a su API — ⚠ y acá la pregunta SÍ
+# importó: el repo ya tiene `v65`, que es la que se habría tomado por reflejo.
+#
+# ══ ÉSTA SE CONSTRUYE CON MESON, NO CON UN MAKEFILE ════════════════════════════════════════════
+# Las otras dos son un `pack` y un `make install`; ésta trae `meson.build` con los módulos `gnome`
+# e `i18n`, y hace lo mismo que un paquete de distro cuando el prefix NO es local:
+# · el árbol va a <prefix>/share/gnome-shell/extensions/<uuid>/
+# · el gschema al directorio GLOBAL <prefix>/share/glib-2.0/schemas
+# · los .mo a <prefix>/share/locale
+# ⚠ `-Dlocal_install=disabled` explícito: la opción viene en `auto`, y en `auto` decide mirando si
+# el prefix es /usr/local Y si el uid es 0. Nuestro sandbox corre como root con prefix /usr, así que
+# hoy resolvería bien por accidente — pero «funciona por accidente se ve igual que funciona por
+# diseño», y si mañana el lab dejara de ser root la instalación se iría a $HOME/.local y el artefacto
+# sellaría vacío.
+#
+# ⚠ `jq` VA EN [deps] AUNQUE LA EXTENSIÓN SEA JAVASCRIPT PURO: `meson.build:22` saca el uuid del
+# `metadata.json` con `run_command(jq, '-r', '.uuid', …)` — es una herramienta del sandbox, no una
+# librería que se enlace. Sin ella meson corta en el configure.
+name = "gnome-shell-extension-appindicator"
+version = "64"
+# licencia: el `meson.build` declara `license: 'GPL2'` y las cabeceras de los fuentes (extension.js,
+# appIndicator.js…) dan la concesión completa: «either version 2 of the License, or (at your option)
+# any later version». ⚠ No se dedujo del LICENSE: su apéndice «How to Apply» contiene esa frase
+# siempre, así que buscarla ahí da positivo aunque el proyecto sea -only.
+license = "GPL-2.0-or-later"
+
+[source]
+repo = "https://github.com/ubuntu/gnome-shell-extension-appindicator"
+commit = "c934adc6c97363b8e6bb161ca8d1ac62d1da3d63" # tag v64 (ADR 0006: commit fijo, nunca HEAD)
+
+[build]
+compiler = "zig-cc"
+target = "x86_64-linux-musl"
+link = "dynamic"
+
+[build.phases]
+configure = "PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release --wrap-mode=nodownload -Dlocal_install=disabled"
+compile = "PYTHONPATH=/usr/lib/python3.12/site-packages ninja -C output"
+install = '''
+set -e
+UUID="appindicatorsupport@rgcjonas.gmail.com"
+PYTHONPATH=/usr/lib/python3.12/site-packages DESTDIR=/out meson install -C output --no-rebuild
+D="/out/usr/share/gnome-shell/extensions/$UUID"
+
+# Guardián: se comprueba el RESULTADO, no la intención. Si `local_install` hubiera resuelto a
+# «local», esto habría instalado en $HOME/.local y el artefacto sellaría igual, vacío (regla 3 de
+# CLAUDE.md — un vacío llega hasta el final diciendo que todo fue bien).
+test -s "$D/metadata.json"
+test -s "$D/extension.js"
+grep -q '"48"' "$D/metadata.json" # falla ruidoso si un bump deja de soportar shell 48
+# El gschema tiene que haber ido al directorio GLOBAL, que es el que compila el lanzador al arrancar.
+test -s /out/usr/share/glib-2.0/schemas/org.gnome.shell.extensions.appindicator.gschema.xml
+'''
+
+[deps]
+# `jq` es del configure (saca el uuid del metadata.json); `glib` trae glib-compile-schemas para el
+# módulo `gnome` de meson y `gettext-tiny` el msgfmt para el módulo `i18n`.
+build = ["meson", "samurai", "python3", "pkgconf", "jq", "glib", "pcre2", "libffi", "zlib", "gettext-tiny"]
diff --git a/recipes/incoming-gnome/gnome-shell-extension-blur-my-shell.toml b/recipes/incoming-gnome/gnome-shell-extension-blur-my-shell.toml
index ae429b33..6657540c 100644
--- a/recipes/incoming-gnome/gnome-shell-extension-blur-my-shell.toml
+++ b/recipes/incoming-gnome/gnome-shell-extension-blur-my-shell.toml
@@ -81,23 +81,15 @@ for po in po/*.po; do
msgfmt -o "$D/locale/$lang/LC_MESSAGES/$UUID.mo" "$po"
done
-# 4. INSTALADA ≠ ACTIVA. El shell sólo carga las extensiones que estén en la clave
-# `org.gnome.shell enabled-extensions`, así que sin esto el artefacto sella, el fichero está en
-# la imagen y NO PASA NADA al arrancar — el mismo cuadro de «sellado ≠ instalado» que este repo
-# ya se comió con foot, mpv y libnotify, un escalón más abajo.
-# Se hace con un override de GSettings, que cambia el DEFAULT sin tocar la config del usuario
-# (quien no la quiera la apaga y su dconf gana). El `gnome-start-qemu.sh` corre
-# `glib-compile-schemas` sobre este directorio en el primer arranque, así que el override entra.
-#
-# ⚠ TRAMPA PARA LA SEGUNDA EXTENSIÓN: `enabled-extensions` es un ARRAY y esto lo escribe ENTERO.
-# Si mañana otra receta instala su propio override para la misma clave, no se suman: gana el
-# fichero que compile último (orden alfabético) y la otra extensión queda instalada y muerta,
-# sin error. Cuando llegue la segunda, la lista pasa a un solo sitio que las liste a todas.
-mkdir -p /out/usr/share/glib-2.0/schemas
-cat > /out/usr/share/glib-2.0/schemas/60_hammer-extensiones.gschema.override <<OVR
-[org.gnome.shell]
-enabled-extensions=['$UUID']
-OVR
+# 4. ⚠ INSTALADA ≠ ACTIVA, y eso NO se resuelve acá. El shell sólo carga lo que esté en
+# `org.gnome.shell enabled-extensions`, que es un ARRAY: un override de GSettings lo escribe
+# ENTERO. Si cada receta trajera el suyo no se sumarían — ganaría el que compile último y las
+# demás quedarían instaladas y MUERTAS, sin un solo error. Por eso la lista se arma en UN sitio,
+# `scripts/gnome/gnome-start-qemu.sh`, que ya compila los esquemas al arrancar y ahora enumera
+# los uuid presentes en /usr/share/gnome-shell/extensions. La política es «lo que la imagen
+# instala, se activa»; quien no quiera una la apaga desde su dconf, que gana sobre el default.
+# (Una receta no puede ser ese sitio: hammer exige `[source]` en toda receta — «missing field
+# `source`» —, así que no hay forma de escribir una receta de pura política.)
# 5. Guardián barato: si el árbol quedara vacío o sin metadata, el artefacto sellaría igual y el
# fallo aparecería recién al arrancar el escritorio (regla 3 de CLAUDE.md — un vacío llega hasta
@@ -106,7 +98,6 @@ test -s "$D/metadata.json"
test -s "$D/extension.js"
test -s "$D/schemas/gschemas.compiled"
grep -q '"48"' "$D/metadata.json" # falla ruidoso si un bump de versión deja de soportar shell 48
-grep -q "$UUID" /out/usr/share/glib-2.0/schemas/60_hammer-extensiones.gschema.override
'''
[deps]
diff --git a/recipes/incoming-gnome/gnome-shell-extension-dash-to-panel.toml b/recipes/incoming-gnome/gnome-shell-extension-dash-to-panel.toml
new file mode 100644
index 00000000..4d92e500
--- /dev/null
+++ b/recipes/incoming-gnome/gnome-shell-extension-dash-to-panel.toml
@@ -0,0 +1,69 @@
+# dash-to-panel 73 — la barra de tareas: mueve el dash al panel superior y junta lanzadores,
+# ventanas abiertas y bandeja en una sola barra, al estilo Plasma/Windows 7+. Es, con diferencia, la
+# extensión que más cambia el uso diario de GNOME.
+#
+# Segunda extensión del catálogo; el patrón lo fijó `gnome-shell-extension-blur-my-shell` y su
+# cabecera explica por qué la fuente es el REPO y no el zip de extensions.gnome.org.
+# El tag `v73` es el que EGO sirve para shell 48 (preguntado a su API, no supuesto) y el
+# `metadata.json` del repo declara shell-version ["46","47","48","49","50"].
+#
+# ══ ACÁ SÍ SE USA EL `make install` DE UPSTREAM ════════════════════════════════════════════════
+# A diferencia de blur-my-shell —cuyo `make build` llama a `gnome-extensions pack`, el CLI que
+# nuestra receta del shell apaga— el Makefile de dash-to-panel tiene un `install` que HONRA
+# `DESTDIR` y hace exactamente lo que hace un paquete de distro:
+# · el árbol de la extensión va a $DESTDIR/usr/share/gnome-shell/extensions/<uuid>/
+# · y en modo «system» SACA de ahí `schemas/` y `locale/` para ponerlos en los directorios
+# GLOBALES: /usr/share/glib-2.0/schemas y /usr/share/locale.
+# Se usa su install en vez de copiar a mano: es upstream quien decide qué entra y qué no.
+#
+# ⚠ Que el gschema termine en el directorio GLOBAL no es un detalle: lo compila el mismo
+# `glib-compile-schemas` que corre el lanzador al arrancar, junto con los del shell. Por eso esta
+# receta NO necesita compilarlo ella (y el Makefile igual lo compila para el `_build`).
+#
+# ⚠ `VERSION=73` SE PASA A MANO, y no es cosmético. Sin ella el Makefile hace
+# `git describe --tags HEAD` para deducirla, y el árbol se materializa con `git archive`, SIN `.git`
+# ⇒ la orden falla y `metadata.json` queda con el `"version": 9999` de marcador que trae el repo.
+# Es la misma razón por la que la receta de `tzdata` pasa `VERSION=2026b`.
+name = "gnome-shell-extension-dash-to-panel"
+version = "73"
+# licencia: el fichero COPYING del commit pineado es el texto del GPL v2, y el `metadata.json` de
+# EGO no declara licencia. ⚠ La concesión está en la CABECERA de los fuentes (src/extension.js y
+# compañía): «either version 2 of the License, or (at your option) any later version» ⇒ -or-later.
+# No se dedujo del COPYING: su apéndice «How to Apply» contiene esa frase SIEMPRE, así que buscarla
+# ahí da positivo aunque el proyecto sea -only (la trampa que ya está documentada en el repo).
+license = "GPL-2.0-or-later"
+
+[source]
+repo = "https://github.com/home-sweet-gnome/dash-to-panel"
+commit = "b31cbe1f3c9fa997b954b71199563fbedc2f3446" # tag v73 (ADR 0006: commit fijo, nunca HEAD)
+
+[build]
+compiler = "zig-cc"
+target = "x86_64-linux-musl"
+link = "dynamic"
+
+[build.phases]
+# Nada que compilar en el sentido de C: `make all` sólo compila el gschema y los catálogos .po.
+configure = "true"
+compile = 'make VERSION=73'
+install = '''
+set -e
+UUID="dash-to-panel@jderose9.github.com"
+make install DESTDIR=/out VERSION=73
+D="/out/usr/share/gnome-shell/extensions/$UUID"
+
+# Guardián: el `install` de upstream mueve cosas de sitio según DESTDIR, así que se comprueba el
+# resultado y no la intención. Un artefacto a medias sella igual y el fallo sale recién al arrancar
+# el escritorio (regla 3 de CLAUDE.md).
+test -s "$D/metadata.json"
+test -s "$D/extension.js"
+grep -q '"version": 73' "$D/metadata.json" # falla si el sed de VERSION no corrió (quedaría 9999)
+grep -q '"48"' "$D/metadata.json" # falla si un bump deja de soportar shell 48
+# El gschema tiene que haber ido al directorio GLOBAL, que es lo que compila el lanzador.
+test -s /out/usr/share/glib-2.0/schemas/org.gnome.shell.extensions.dash-to-panel.gschema.xml
+'''
+
+[deps]
+# `make` para el Makefile, `glib` por glib-compile-schemas y `gettext-tiny` por msgfmt. Ninguna es
+# una librería que la extensión enlace: no enlaza nada, es JavaScript.
+build = ["make", "glib", "pcre2", "libffi", "zlib", "gettext-tiny"]
diff --git a/recipes/incoming-gnome/gnome-tweaks.toml b/recipes/incoming-gnome/gnome-tweaks.toml
new file mode 100644
index 00000000..3ef6fd9d
--- /dev/null
+++ b/recipes/incoming-gnome/gnome-tweaks.toml
@@ -0,0 +1,97 @@
+# gnome-tweaks 46.1 — el «tenés que instalarte esto» clásico de GNOME. Es la app que expone lo que
+# el shell no deja tocar desde Configuración: tema, iconos, cursor, tipografías, botones de la barra
+# de título (minimizar/maximizar, que GNOME esconde), comportamiento del touchpad, aplicaciones al
+# inicio y el interruptor de las extensiones.
+#
+# ⚠ POR QUÉ 46.1 Y NO LA ÚLTIMA. gnome-tweaks NO tiene release 47 ni 48: la lista de
+# download.gnome.org salta de 46.1 a 49.rc/49.0. Nuestro shell es el 48, así que la que corresponde
+# es la ÚLTIMA anterior — la 49 apunta a la serie 49 de libadwaita/GTK y no hay motivo para
+# arriesgar APIs nuevas contra un escritorio 48. Comprobado en el `cache.json` del propio servidor,
+# no en una lista de memoria.
+#
+# ══ NO CUESTA NINGUNA RECETA NUEVA, y eso hubo que medirlo ═════════════════════════════════════
+# Su `meson.build:22-28` declara las versiones mínimas de runtime en un bloque explícito «to make
+# packaging more obvious», y las siete se cumplen con lo que ya está sellado:
+# glib >= 2.78 ✓ 2.88 gobject-introspection >= 1.78 ✓ 1.84
+# gtk4 >= 4.10 ✓ libadwaita-1 >= 1.4 ✓ 1.7.6
+# pygobject-3.0 >= 3.46 ✓ 3.50 gudev-1.0 >= 238 ✓ 238
+# gsettings-desktop-schemas >= 46 ✓ 48.0
+#
+# ⚠ El `pygobject-3.0` de esa lista lo provee `py3-gobject`, que YA ESTABA en el corpus con otro
+# nombre —la escribió el frente GNOME para el build de libgweather— y publica `pygobject-3.0.pc`
+# (verificado en su artefacto). Sin mirar eso, esta receta parecía arrastrar una cadena de Python
+# entera. El nombre no es el hecho, otra vez.
+#
+# ⚠ Y NO necesita pycairo, que es la parte que `py3-gobject` construye con `-Dpycairo=disabled`:
+# ningún fichero de `gtweak/` importa `cairo` (verificado sobre el tarball).
+#
+# ══ ES UNA APP DE PYTHON: SUS DEPS DE RUNTIME NO SON LAS DE BUILD ══════════════════════════════
+# No se enlaza nada — `gnome-tweaks` es un script que importa `gi.repository`. Si `python3` y
+# `py3-gobject` no están EN LA IMAGEN, la app se instala y no arranca, y el build no puede
+# delatarlo. Por eso van en `[deps] runtime`, que es exactamente el caso de `xkbcomp` en xwayland.
+name = "gnome-tweaks"
+version = "46.1"
+# licencia: no hace falta interpretar nada — los fuentes llevan etiqueta SPDX explícita.
+# `gtweak/tweakmodel.py:2`: «SPDX-License-Identifier: GPL-3.0+», que es la forma vieja de
+# `GPL-3.0-or-later`. El tarball no trae COPYING sino un directorio `LICENSES/`.
+license = "GPL-3.0-or-later"
+
+[source]
+tarball = "https://download.gnome.org/sources/gnome-tweaks/46/gnome-tweaks-46.1.tar.xz"
+sha256 = "2f192a7085fbd6843ecf825716d9da21ec9272029149ea35f3e159e0ac309b80"
+
+[build]
+compiler = "zig-cc"
+target = "x86_64-linux-musl"
+link = "dynamic"
+
+[build.phases]
+# ⚠ SE SACA EL ÁRABE, y NO es una decisión sobre el idioma: es un BUG del `msgfmt` de
+# `gettext-tiny`, el único que hay en el corpus. Revienta con SIGILL —«index 6 out of bounds for
+# type 'size_t[6]'», exit 132— al compilar un mensaje con SEIS formas plurales, que es justo lo que
+# tiene el árabe. Reproducido FUERA de la receta, con el binario sellado:
+# msgfmt -o /tmp/x.mo po/ar.po → panic, exit 132, y deja un .mo de 0 bytes
+# No es el idioma: `blur-my-shell` compila su `ar.po` sin problema porque no tiene NINGÚN mensaje
+# plural (msgstr[5] = 0 apariciones); el de tweaks tiene exactamente uno (msgstr[5] = 1).
+# ⚠ ARREGLARLO DE VERDAD ES OTRA UNIDAD DE TRABAJO: `gettext-tiny` la usan 108 recetas, así que
+# tocarla re-hashea el corpus entero. Acá se pierde la traducción al árabe de UNA app y se deja el
+# diagnóstico escrito; lo que NO se hace es callarlo.
+configure = "sed -i '/^ar$/d' po/LINGUAS && PKG_CONFIG_PATH=/usr/lib/pkgconfig PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release --wrap-mode=nodownload"
+compile = "PYTHONPATH=/usr/lib/python3.12/site-packages ninja -C output"
+install = '''
+set -e
+PYTHONPATH=/usr/lib/python3.12/site-packages DESTDIR=/out meson install -C output --no-rebuild
+
+# Guardián: `gnome.post_install()` de meson se SALTA sus pasos cuando DESTDIR está seteado (lo dice
+# en el log: «Skipping custom install script because DESTDIR is set»), así que lo que hay que
+# comprobar es lo que SÍ tiene que quedar en el árbol. El gschema va al directorio GLOBAL, que es el
+# que compila el lanzador al arrancar — igual que el de las extensiones.
+test -s /out/usr/bin/gnome-tweaks
+test -s /out/usr/share/glib-2.0/schemas/org.gnome.tweaks.gschema.xml
+test -s /out/usr/share/applications/org.gnome.tweaks.desktop
+# El módulo Python tiene que estar donde el intérprete lo busque, no en cualquier lado.
+test -d /out/usr/lib/python3.12/site-packages/gtweak
+'''
+
+[deps]
+# ⚠ RUNTIME, no build: es una app de Python que importa gi.repository. Sin estas dos en la imagen se
+# instala y no arranca, y ningún build lo delata.
+runtime = ["python3", "py3-gobject"]
+# La clausura ENTERA, que las deps de hammer no son transitivas. Copiada de la que ya usa
+# xdg-desktop-portal-gnome, que es el otro consumidor de gtk4+libadwaita de esta cola.
+build = ["meson", "samurai", "python3", "pkgconf", "gettext-tiny", "gobject-introspection",
+ "py3-gobject", "gsettings-desktop-schemas", "gtk4", "libadwaita", "glib", "glib-introspected",
+ "gi-foreign-girs", "libgudev", "libudev-zero",
+ "cairo-shared", "pango", "graphene", "libepoxy", "wayland", "wayland-protocols", "libdrm",
+ "harfbuzz", "fribidi", "libpng-shared", "pixman", "freetype-shared", "expat", "libffi", "pcre2",
+ "zlib-shared", "gdk-pixbuf", "libjpeg-turbo-shared", "libtiff-shared", "mesa",
+ "fontconfig-shared", "xkeyboard-config", "iso-codes", "libseccomp",
+ # ⚠ `appstream` y su cola NO son un capricho: `libadwaita-1.pc` la lleva en `Requires`, así que
+ # pkg-config la resuelve TRANSITIVAMENTE y sin ella el configure corta con «Package 'appstream',
+ # required by 'libadwaita-1', not found» — culpando a libadwaita, que está perfectamente
+ # instalada. Es el patrón `.pc Requires` → `[deps].build` que el corpus ya tiene documentado.
+ "appstream", "libxmlb", "curl", "openssl", "libxml2-shared", "libyaml-shared", "zstd",
+ # `desktop-file-utils` por `update-desktop-database`: su `gnome.post_install()` lo pide como
+ # PROGRAMA y meson corta en el configure si no está (no es una librería que se enlace). La receta
+ # ya existe y encima está en el perfil desde el 2026-09-09.
+ "desktop-file-utils"]
diff --git a/scripts/gnome/gnome-start-qemu.sh b/scripts/gnome/gnome-start-qemu.sh
index bc4de733..a019ec1f 100755
--- a/scripts/gnome/gnome-start-qemu.sh
+++ b/scripts/gnome/gnome-start-qemu.sh
@@ -104,6 +104,45 @@ chmod 700 "$XDG_RUNTIME_DIR"
[ -s /etc/machine-id ] || cat /proc/sys/kernel/random/uuid 2>/dev/null | tr -d - > /etc/machine-id
cp -f /etc/machine-id /var/lib/dbus/machine-id 2>/dev/null || true
+# ── ACTIVAR LAS EXTENSIONES QUE LA IMAGEN TRAE ────────────────────────────────────────────────
+# Una extensión INSTALADA no hace nada: el shell sólo carga las que estén en
+# `org.gnome.shell enabled-extensions`. Sin esto, empaquetarlas sella artefactos que la imagen
+# lleva y nadie ejecuta — «sellado ≠ instalado», un escalón más abajo.
+#
+# ⚠ POR QUÉ LA LISTA SE ARMA ACÁ Y NO EN CADA RECETA. `enabled-extensions` es un ARRAY: un override
+# lo escribe ENTERO. Si cada receta trajera el suyo, no se sumarían — ganaría el fichero que
+# compile último (orden alfabético) y las demás quedarían instaladas y MUERTAS, sin un solo error.
+# La lista tiene que existir en un único sitio, y una receta no puede ser ese sitio: hammer exige
+# `[source]` en toda receta (comprobado: «missing field `source`»), así que no hay forma de escribir
+# una receta de pura política sin inventarle una fuente. Acá, donde ya se compilan los esquemas, sí.
+#
+# La política es «lo que la imagen instala, se activa»: el catálogo sólo empaqueta extensiones que
+# queremos encendidas. Quien no quiera una la apaga desde su dconf, que gana sobre el default.
+EXT_DIR=/usr/share/gnome-shell/extensions
+OVR="$GSETTINGS_SCHEMA_DIR/60_hammer-extensiones.gschema.override"
+if [ -d "$EXT_DIR" ]; then
+ uuids=""
+ for d in "$EXT_DIR"/*/; do
+ [ -s "$d/metadata.json" ] || continue
+ u="$(basename "$d")"
+ uuids="$uuids${uuids:+, }'$u'"
+ done
+ if [ -n "$uuids" ]; then
+ nuevo_ovr="[org.gnome.shell]
+enabled-extensions=[$uuids]"
+ # Si la lista cambió respecto de la compilada, hay que RECOMPILAR: el bloque de abajo sólo
+ # compila cuando falta `gschemas.compiled`, así que un override nuevo sobre una imagen ya
+ # arrancada quedaría ignorado en silencio.
+ if [ ! -f "$OVR" ] || [ "$(cat "$OVR")" != "$nuevo_ovr" ]; then
+ printf '%s\n' "$nuevo_ovr" > "$OVR"
+ rm -f "$GSETTINGS_SCHEMA_DIR/gschemas.compiled"
+ fi
+ say "extensiones a activar: $uuids"
+ else
+ say "no hay extensiones instaladas en $EXT_DIR"
+ fi
+fi
+
# gschemas.compiled: meson NO lo genera cuando DESTDIR está seteado (lo dice en el log del build:
# "Skipping custom install script because DESTDIR is set"). Sin él, GSettings aborta al primer
# g_settings_new() y el shell no llega ni a abrir el DRM. Se compila acá, en el primer arranque.