# Consignes de développement — Extension GNOME Shell (GNOME 48) : contrôle RGB clavier ASUS (asus-nb-wmi) ## 1) Contexte et objectif Machine cible : **ASUS TUF Gaming A16 FA608UH** sous **Debian GNU/Linux 13 (trixie)**, **GNOME 48** (capture fournie). Le rétroéclairage clavier est pilotable via l’interface noyau **asus-nb-wmi** : - Intensité : `/sys/class/leds/asus::kbd_backlight/brightness` (0..max) - Couleur (statique) : `/sys/class/leds/asus::kbd_backlight/kbd_rgb_mode` Format : `cmd mode R G B speed` (ex : `1 0 255 165 0 0`) But : créer une **extension GNOME Shell** qui ajoute un **icône dans la barre du haut**, et au clic affiche un **popover** permettant : - 4 boutons d’intensité (Off/Faible/Moyen/Fort) - 3 sliders **R**, **G**, **B** - 1 slider **Master** (offset global sur R/G/B, ou gain global — à préciser) - 6 couleurs prédéfinies (cases cliquables) - Application **en direct** sur l’aperçu + sur le clavier Le tout doit être **user-friendly** et robuste, avec gestion claire des **droits**. ## 2) Décision technique recommandée (à appliquer) ### Langage / framework - **GJS / JavaScript** (langage standard des extensions GNOME Shell) - UI via `PanelMenu.Button`, `PopupMenu`, `St` (et éventuellement `Slider` de GNOME Shell) - Compatible **GNOME Shell 48** ### Architecture recommandée Séparer en 3 blocs : 1. `ui.js` : construction du menu (widgets, layout, events) 2. `backend.js` : lecture/écriture sysfs + logique (clamp, master slider, presets) 3. `prefs/` : page de préférences (optionnel au MVP), + stockage presets (GSettings) ### Stockage (persistant) - `GSettings` (schema dédié) : RGB courant, intensité, 6 presets, step RGB, mode “master” - Appliquer au démarrage de session (extension enable) : relire settings et appliquer. ## 3) Gestion des droits — approche “propre” (prioritaire) L’extension tourne en user-space (non root). Écrire dans `/sys/...` nécessite des droits. **Approche recommandée (simple + stable) :** - créer une **règle udev** qui donne accès en écriture à un groupe dédié (ex `kbdled`) - ajouter l’utilisateur au groupe `kbdled` - l’extension teste l’accès en écriture et affiche un message si absent Exemple (à documenter dans README) : - `/etc/udev/rules.d/99-asus-kbd.rules` `SUBSYSTEM=="leds", KERNEL=="asus::kbd_backlight", GROUP="kbdled", MODE="0660"` - `sudo groupadd -f kbdled` - `sudo usermod -aG kbdled $USER` - `sudo udevadm control --reload-rules && sudo udevadm trigger` - logout/login **Alternative (non MVP, mais “enterprise grade”) :** - service systemd root + D-Bus + polkit. À proposer uniquement si l’utilisateur refuse udev. ## 4) Spécification UI (MVP) ### Icône - Icône type “keyboard backlight” (symbolic) dans le top bar. ### Menu déroulant (popover) - Ligne 1 : **4 boutons intensité** alignés (Off, 1, 2, 3) (style : toggle buttons, celui actif surligné) - Section sliders : - `R` slider 0..255 - `G` slider 0..255 - `B` slider 0..255 - `Master` slider (définir le comportement exact, voir Questions) - Ligne info (en bas) : - `RGB=(r,g,b)` + `HEX=#RRGGBB` + `Intensity=n/max` - Section presets : - 6 cases couleur cliquables (carrés), appliquent RGB instantanément - Un clic long (optionnel) ouvre un mini-dialog pour “enregistrer” la couleur courante dans ce preset ### UX exigée - Application **immédiate** lors des changements sliders (avec debouncing 50–100ms pour éviter spam sysfs) - Clamp et sécurité : jamais écrire hors 0..255 / 0..max_brightness - Si `brightness=0`, on peut conserver RGB en mémoire mais ne pas écrire `kbd_rgb_mode` (optionnel) ## 5) Logique “Master slider” Implémenter l’une des options suivantes (à trancher via Questions) : - **Option A (offset)** : master ajoute un delta (-128..+127) à R,G,B en même temps (clamp). - **Option B (gain)** : master agit comme “brightness RGB” 0..100% (multiplie R,G,B). - **Option C (HSV value)** : convert RGB->HSV, master modifie V, puis reconvertit. MVP : Option B (gain) est la plus intuitive pour un “tout monter/descendre”. ## 6) Implémentation backend (sysfs) ### Écriture - utiliser `Gio.File.new_for_path(path).replace_contents(...)` (sync ou async) - écrire : - `brightness`: entier (0..max) - `kbd_rgb_mode`: string `1 0 R G B 0\n` - lecture : - `max_brightness` - `brightness` - (si dispo) `kbd_rgb_state` pour init, sinon utiliser GSettings ### Debounce - sur sliders, ne pas écrire à chaque pixel : buffer + `GLib.timeout_add()`. ### Robustesse - si fichiers absents : afficher “Matériel non supporté” - si permission refusée : afficher un bloc “Fix permissions” avec étapes udev ## 7) Repo / Outillage (Gitea + VS Code) ### Repo Créer un repo Gitea (nom suggéré) : `gnome-asus-kbd-rgb` Arborescence : - `extension/` - `metadata.json` - `extension.js` - `ui.js` - `backend.js` - `stylesheet.css` (optionnel) - `schemas/org.gnome.shell.extensions.asuskbdrgb.gschema.xml` - `prefs/` (optionnel MVP) - `README.md` - `INSTALL.md` (permissions udev + installation) - `tools/` (scripts de dev, lint, packaging) ### Dev loop - activer en local via `~/.local/share/gnome-shell/extensions//` - recharger GNOME Shell : - X11 : `Alt+F2`, `r`, Enter - Wayland : logout/login - logs : - `journalctl -f -o cat /usr/bin/gnome-shell` ## 8) UUID et metadata UUID conseillé : `asus-kbd-rgb@gilles` (metadata.json doit déclarer `shell-version: ["48"]`) ## 9) Définition des presets (6) Par défaut (modifiable) : 1. Orange (255,165,0) 2. Rouge (255,0,0) 3. Vert (0,255,0) 4. Bleu (0,0,255) 5. Blanc (255,255,255) 6. Cyan (0,255,255) Stocker en GSettings sous forme `a{sv}` ou simples clés `preset1_r`, etc. ## 10) Tests fonctionnels à livrer - Intensité change correctement (0..max) - Sliders RGB appliquent instantanément - Master slider influence R/G/B conformément au mode choisi - Presets appliquent la couleur - Redémarrage session : la dernière config est restaurée - Cas “no permission” : message et guide udev affichés - Cas “hardware absent” : message clair ## 11) Livrables attendus de Claude Code 1. Code complet extension GNOME Shell 48 (MVP) 2. `README.md` (usage) + `INSTALL.md` (permissions + installation) 3. `gschema.xml` + compilation instructions (`glib-compile-schemas`) 4. Un script `tools/install-local.sh` (copie dans ~/.local/share/gnome-shell/extensions) 5. Optionnel : page Prefs GNOME (`prefs.js`) pour gérer presets et mode master ## 12) Questions à trancher AVANT de coder (si ambigu) Claude doit demander au début, puis implémenter par défaut si pas de réponse : 1. Master slider : **offset** ou **gain** ? (par défaut : gain 0..100%) 2. Pas (step) RGB : 1, 5, 10 ? (par défaut : 5, avec option prefs) 3. Au démarrage : lire sysfs si possible, sinon GSettings ? (par défaut : GSettings) 4. Sur `brightness=0` : garder couleur mémorisée sans l’écrire, ou écrire quand même ? (par défaut : mémoriser, n’écrire que si >0) 5. Presets : simple clic applique ; long-press pour enregistrer ? (par défaut : clic applique, bouton “Save to preset” option prefs) ## 13) Prompt d’exécution pour Claude Code Tu es **Claude Code** (mode dev). Tu dois produire un projet complet dans un repo Git. Contraintes : - GNOME Shell 48 (GJS) - Pas de dépendances externes - Code lisible, modulaire, commenté - Robustesse permissions + erreurs - UX immédiate et fluide Plan de travail exigé : 1. Générer l’arborescence complète 2. Implémenter backend sysfs + debounce 3. Implémenter UI popover (table + sliders + presets) 4. Implémenter GSettings + valeurs par défaut 5. Documenter installation + règle udev + troubleshooting 6. Tester et fournir checklist Fin.