Objectifs
Il s'agit de créer une application graphique imitant l'outil language-selector-gnome disponible dans Ubuntu, qui soit lancé automatiquement dÚs la premiÚre session aprÚs une installation de antiX ou d'un de ses « respins » (nom donné par la communauté antiX aux versions dérivées, que l'on peut produire avec l'outil Snapshot, ou dans un live, avec l'outil remaster-antix.
Je suis une apprentie en matiĂšre de codage et mĂȘme de scripting, et Claude.ai, quand consultĂ©, attaque directement par une proposition de formation sur le tas. Je dois de toute façon, apprendre Ă scripter, alors, allons-y, c'est le moment ! 👌
Entrée en matiÚre
« Python + GTK3 reste ma recommandation, pour ces raisons adaptĂ©es Ă ta situation : »🐍
- La syntaxe est lisible, les erreurs sont explicites
- GTK3 en Python est trÚs bien documenté en français
- Le code ressemblera Ă ce que tu peux lire et comprendre progressivement
- Avec mon aide et celle des autres IA, on peut construire ça ensemble pas à pas, en commentant chaque bloc
(âŠ)
pour la programmation : tu vas voir que Python est vraiment le meilleur point d'entrĂ©e. La syntaxe est proche du langage naturel, et avec GTK3 on manipule des objets qui ont une logique trĂšs visuelle â une fenĂȘtre, un onglet, un bouton, une liste. Rien d'abstrait. â
â J'ai une question sur l'articulation entre Python et GTK3, comment cela se produit-il ?
Â
L'articulation entre Python et GTK3
Alors : Python est le langage, GTK3 est la boĂźte Ă outils graphique. L'articulation entre les deux se fait via python3-gi â le "gi" signifie "GObject Introspection". C'est le pont qui permet Ă Python de parler Ă GTK3.
ConcrĂštement :
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
Ces trois lignes disent : "je veux utiliser GTK version 3, et j'importe ses composants".
Ensuite tout ce que tu vois Ă l'Ă©cran â fenĂȘtre, onglet, bouton, liste â est un objet GTK que Python manipule. Par exemple :
bouton = Gtk.Button(label="Appliquer")
La logique est : Python décrit quoi afficher et quoi faire quand l'utilisateur clique, GTK3 se charge du dessin à l'écran.
C'est ça qui t'intĂ©resse comme articulation, ou tu voulais aller plus loin dans une direction prĂ©cise ? 🙂
â c'est bien ça. Et "GObject" tu peux m'en parler en dĂ©tails ?
Â
Bien sûr !
GObject est le systĂšme de base sur lequel repose toute la pile GTK. C'est une bibliothĂšque C qui apporte Ă un langage qui n'en a pas nativement â le C â un systĂšme orientĂ© objet : des classes, de l'hĂ©ritage, des signaux.
Pourquoi ça existe ? GTK a Ă©tĂ© Ă©crit en C pour ĂȘtre lĂ©ger et portable. Mais le C ne connaĂźt pas les objets. GObject est la solution inventĂ©e par les dĂ©veloppeurs GNOME pour combler ce manque â une sorte de "couche objet" construite au-dessus du C.
Ce que GObject apporte concrĂštement :
- Les classes et l'héritage : un Gtk.Button hérite de Gtk.Widget qui hérite de GObject.Object. Chaque niveau ajoute des capacités.
- Les signaux : le mĂ©canisme qui permet de dire "quand l'utilisateur clique sur ce bouton, appelle cette fonction". C'est le cĆur de toute interface graphique GTK.
- Les propriétés : chaque objet a des propriétés modifiables (taille, couleur, texte...).
- La gestion mémoire : GObject compte les références pour savoir quand libérer la mémoire.
Et "Introspection" dans python3-gi ? C'est ce qui permet à Python de "découvrir" automatiquement toutes les classes et fonctions GTK sans qu'il faille tout réécrire en Python. GObject expose ses propres métadonnées, et python3-gi les lit pour construire le pont.
Une analogie : GObject est le fabricant de piĂšces, GTK3 est l'assembleur, et python3-gi est le traducteur qui te permet de donner tes instructions en Python. 🙂
Des questions sur un point précis ?
â Oui une question, tu dis «Le C ne connaĂźt pas les objets» et «GObject est la solution inventĂ©e pour combler ce manque» : en quoi est-il Ă©crit ?
😄 Excellente question â et c'est lĂ que c'est malicieux !
GObject est écrit... en C. Il simule l'orienté objet en C en utilisant des structures (struct), des pointeurs de fonctions, et des conventions strictes de nommage et d'organisation du code.
C'est du C qui fait semblant d'ĂȘtre objet â de façon trĂšs disciplinĂ©e et trĂšs rigoureuse, mais du C quand mĂȘme. Les "classes" sont des structures, l'"hĂ©ritage" est simulĂ© en plaçant la structure parente en premier membre de la structure enfant, et les "mĂ©thodes" sont des fonctions dont le premier argument est toujours un pointeur vers l'objet.
C'est un tour de force d'ingĂ©nierie, et aussi la preuve que quand on n'a pas l'outil, on l'invente avec ce qu'on a. â🙂
Squelette Python GTK3 pour sélecteur de langue
Le workflow
- Au premier démarrage de session aprÚs installation, le programme se lance automatiquement
- Les démarrages suivants : le programme reste disponible dans les menus, section "Préférences", mais ne se lance plus automatiquement
Dans le détail :
- Un fichier locales-reconfiguration.desktop sous /usr/share/applications : point d'entrée permanent dans les menus
- Un lien symbolique de ce fichier vers /etc/xdg/autostart : pour le lancement automatique au premier démarrage
- Vérification de l'absence du répertoire /live : si le systÚme est en session live, le programme quitte silencieusement ; sinon il se lance
- Le script /usr/local/bin/locales-reconfiguration.py : le programme lui-mĂȘme
- Aux dĂ©marrages suivants : le lien symbolique n'existe plus â pas de lancement automatique ## Lors des tests vĂ©rifier si un symlink dans /etc/xdg/autostart suffit Ă lancer le programme au moment voulu
Nous nous inspirons du programme language-selector-gnome de Ubuntu dont la description suit.
Description de ce que fait language-selector-gnome
- Ouverture du programme sans droits particuliers
- Affichage de la fenĂȘtre principale avec deux onglets : Langue / Formats rĂ©gionaux
- L'utilisateur choisit sa langue dans l'onglet Langue
- L'utilisateur choisit ses formats régionaux dans l'onglet Formats régionaux
- Clic sur Appliquer Ă tout le systĂšme : une boĂźte de dialogue demande le mot de passe administrateur
- Le mot de passe est passé à sudo -S via subprocess
- Modification de /etc/locale.gen : seule la locale choisie reste décommentée
- Appel Ă /usr/sbin/locale-gen
- Mise Ă jour de /etc/default/locale avec les variables LC_*
- Fermeture du programme
Description de ce que fait le programme
- Lecture de ~/.config/locale pour détecter la langue configurée par l'utilisateur
- Fallback vers /etc/default/locale si ~/.config/locale est absent ou vide
- Extraction des codes locales présents (LANG, LC_*)
- Affichage d'une confirmation à l'utilisateur : langue détectée, demande de mot de passe
- Remplacement du contenu de /usr/share/i18n/SUPPORTED par le template depuis /usr/share/bento/locale.gen.template, via sudo -S via subprocess (locale.gen.template est le fichier locale.gen et /usr/share/i18n/SUPPORTED mais entiÚrement commenté)
- On décommente les lignes correspondantes aux locales détectées dans /etc/locale.gen (lequel est un lien symbolique qui pointe vers /usr/share/i18n/SUPPORTED )
- Appel Ă /usr/sbin/locale-gen via sudo -S via subprocess
- Information Ă l'utilisateur : pour configurer plusieurs langues, utiliser sudo dpkg-reconfigure locales
Workflow du lancement du programme
Premier démarrage de session aprÚs installation
- Un fichier locales-reconfiguration.desktop est présent sous /etc/xdg/autostart : il déclenche automatiquement le lancement à la premiÚre ouverture de session
- Ce fichier .desktop appelle un script bash /usr/local/bin/start-locales-reconfigurator.sh
- Le script bash vérifie que l'on n'est pas en session live (absence du répertoire /live), puis lance le programme Python GTK3 /usr/local/bin/locales-reconfiguration.py
- Python crée un fichier /tmp/locales-reconf.started pour signaler qu'il est bien démarré
- Le script bash détecte l'apparition de ce fichier locales-reconf.started, puis supprime /etc/xdg/autostart/locales-reconfiguration.desktop
- Le programme Python GTK3 se présente à l'utilisateur
Le script start-locales-reconfigurator.sh
Pour détecter l'apparition du fichier PID, on pourrait utiliser un simple if :
    rm /etc/xdg/autostart/locales-reconfiguration.desktop
fi
Mais avec if, si Python dĂ©marre lentement, le test s'exĂ©cute avant que le fichier locales-reconf.started soit créé â et rien ne se passe. Le lanceur n'est pas supprimĂ©.
On utilise donc while Ă la place : il boucle et attend patiemment l'apparition du fichier, en retestant toutes les 0,5 secondes. DĂšs que Python crĂ©e le fichier locales-reconf.started, la boucle s'arrĂȘte et le lanceur est supprimĂ©.
# Vérification : si on est dans une session live le programme quitte en silence
if [ -d "/live" ]; then
   exit 0
fi
# Lancement du programme Python GTK3 en arriĂšre-plan
/usr/local/bin/locales-reconfiguration.py &
# Attente de l'apparition du fichier PID
# (signale que Python est bien démarré)
while [ ! -f "/tmp/locales-reconf.started" ]; do
    sleep 0.5
done
# Python est lancé : on supprime le lanceur automatique
rm /etc/xdg/autostart/locales-reconfiguration.desktop
Le & aprÚs la commande de lancement de Python est indispensable : sans lui, bash resterait bloqué à attendre que Python se termine et n'atteindrait jamais la boucle while. Premier plan est le comportement par défaut de bash, le signe & en fin de ligne change ce comportement en lançant la commande en arriÚre-plan.
Le ! devant -f signifie "tant que le fichier n'existe PAS" : la boucle tourne jusqu'Ă ce que Python signale son dĂ©marrage. exit 0 dans le bloc if [ -d "/live" ] arrĂȘte immĂ©diatement le script avec un code de retour 0 : la convention Unix pour pas d'erreur, rien Ă faire ici.
Démarrages suivants
Le fichier /etc/xdg/autostart/locales-reconfiguration.desktop n'existe plus â le programme ne se lance plus automatiquement. Il reste accessible depuis les menus, section PrĂ©fĂ©rences, via /usr/share/applications/locales-reconfiguration.desktop.
Avant une reconstruction d'image ISO
Le script de nettoyage pré-snapshot restaure le fichier /etc/xdg/autostart/locales-reconfiguration.desktop afin que le mécanisme soit intact pour le prochain utilisateur.
Préparer le squelette du script Python
L'on vérifie la présence des paquets nécessaires :  $ apt policy python3-gi python3-gi-cairo gir1.2-gtk-3.0. Cela doit retourner installé, candidat, avec les numéros de versions.