Forum Linux.gui exécution d'un programme en fin de session gnome (avant déconnexion)

Posté par  . Licence CC By‑SA.
Étiquettes :
2
23
août
2024

Bonjour à tou(te)s,

j'aimerais savoir s'il est possible de demander à Gnome d'exécuter un programme graphique (en l'occurrence un script zenity) juste avant la déconnexion de Gnome.
j'ai essayé un service systemd.

[Unit]
After=org.gnome.Shell.target

[Service]
Type=oneshot
RemainAfterExit=true
ExecStop=touch /home/hugotrip/Check

[Install]
WantedBy=default.target

il me créé bien un fichier Check dans mon répertoire perso à l'extinction, mais si je remplace mon ExecStop par mon script zenity, celui-ci ne s'affiche pas : je suppose donc qu'il s'exécute après la déconnexion.

Le Contexte :
Je possède une livebox4 avec laquelle je peux dialoguer à distance avec le programme sysbus.
C'est pratique car la livebox est dans un local technique (donc difficilement accessible), et je peux donc allumer le wifi au besoin depuis la télé (sur kodi) ou les ordinateurs (fichiers .desktop), sans y accéder physiquement.
Par défaut nos ordinateurs étant en connexions filaires et nos forfaits mobiles très simples, le wifi était déconnecté ; il était activé à la demande pour nos invités, principalement.
Mais ma grande vient d'avoir son premier smartphone, et si elle sait très bien allumer le wifi, il y a beaucoup trop de loupé sur son extinction. J'aimerai donc que mon ordinateur me demande à l'extinction si je désire couper ou non le wifi, lorsqu'il constate qu'il est encore allumé.
J'ai un script qui fonctionne, mais que je n'arrive donc pas à lancer au bon moment.
PS : dans l'attente, je passe par l'extension Executor qui m'affiche un petit message dans la barre supérieure quand le wifi est allumé.

  • # voir du côté de /etc/gdm3/PostSession/Default ou un fichier dans le même dossier ?

    Posté par  . Évalué à 3. Dernière modification le 23 août 2024 à 12:11.

    D'après la page man de gdm3 :

    When managing a display, gdm3 attempts to execute /etc/gdm3/Init/display, or /etc/gdm3/Init/Default if that does not exist. When a user logs in, gdm3 first attempts /etc/gdm3/PreSession/display (or /etc/gdm3/PreSession/Default), and then one of the sessions defined in /usr/share/xsessions. When the session has completed, gdm attempts to run /etc/gdm3/PostSession/display, or /etc/gdm3/PostSession/Default.

    J'ai essayé de trouver un peu plus d'infos à ce sujet, , mais je n'ai pas trouvé pour le moment (et je n'ai pas vraiment le temps de chercher de suite, désolé).

    Si tu utilises un autre gestionnaire de session, il faut voir la page man correspondant (voir par exemple dans ce fil de discussion)

    • [^] # Re: voir du côté de /etc/gdm3/PostSession/Default ou un fichier dans le même dossier ?

      Posté par  . Évalué à 1.

      Merci pour la piste, je l'avais vu, mais ne l'avais pas testé, car selon la doc de gdm3 :

      When a user terminates their session, GDM will run the PostSession script. Note that the Xserver will have been stopped by the time this script is run, so it should not be accessed.

      je viens quand même de tester, et si un touch me permet de confirmer l'exécution du script, zenity n'affiche pas d'invite graphique, de façon cohérente avec la doc.

      • [^] # Re: voir du côté de /etc/gdm3/PostSession/Default ou un fichier dans le même dossier ?

        Posté par  . Évalué à 2.

        Ok, je vois. Du coup je me demande si c'est n script shell dont tu as réellement besoin, ou si c'est pas plutôt une extension gnome shel .. Je regarde si j'ai le temps (ça m'intéresse de savoir).

        • [^] # Re: voir du côté de /etc/gdm3/PostSession/Default ou un fichier dans le même dossier ?

          Posté par  . Évalué à 1.

          Éventuellement, le but c'est que je puisse lancer quelque chose d'interactif au moment ou je me déconnecte.
          J'ai même essayé un script purement shell à base de

          read -p "Faut-il éteindre le wifi de la box ?" yn
          

          mais ça ne donne rien non plus. Ça n'est pas juste un problème de serveur graphique, il semblerait que globalement, que ce soit via systemd, ou via les gestionnaires de session, il ne soit plus possible d'interagir après déconnexion.

          Ça semble logique (l'utilisateur est déconnecté, donc il y a un souci sur qui interagit), et alors ma demande serait un moyen d'exécuter une action quand on demande à se déconnecter.

          • [^] # Re: voir du côté de /etc/gdm3/PostSession/Default ou un fichier dans le même dossier ?

            Posté par  . Évalué à 2.

            Ça semble logique (l'utilisateur est déconnecté, donc il y a un souci sur qui interagit), et alors ma demande serait un moyen d'exécuter une action quand on demande à se déconnecter.

            Oui, c'est ce que j'en ai déduit aussi : c'est pour ça que je verrais plutôt une extension gnome shell qui s'exécuterait à la fermeture de session. J'ai regardé un peu la documentation des extensions gnome shell, mais je n'ai pas encore vu s'il y a un moyen de créer un plugin qui demanderait d'éteindre le wifi de la box.

            • [^] # Re: voir du côté de /etc/gdm3/PostSession/Default ou un fichier dans le même dossier ?

              Posté par  . Évalué à 3. Dernière modification le 23 août 2024 à 16:47.

              J'ai demandé à chatGPT … C'est possible (voir le code plus bas). Pour créer une extension, voir https://doc.ubuntu-fr.org/utilisateurs/roschan/tutoriel/creer_une_extension_gnome par exemple, ou https://gjs.guide/extensions/development/creating.html (doc officielle)

              Pour info, GNOME Shell emet un signal 'end session' lorsqu'une session est sur le point de se terminer, c'est-à-dire lorsque l'utilisateur demande à se déconnecter, à redémarrer ou à éteindre l'ordinateur.

              global.display.connect('end-session', …) : Cette ligne de code connecte ce signal à une fonction de rappel (callback), qui est exécutée lorsque ce signal est émis.

              
              const { St, Main, Shell, Meta } = imports.gi;
              const Dialog = imports.ui.modalDialog;
              const ExtensionUtils = imports.misc.extensionUtils;
              
              let logoutSignal;
              
              function init() {
                  // Initialisation si nécessaire
              }
              
              function enable() {
                  logoutSignal = global.display.connect('end-session', (display, screen) => {
                      // Afficher la boîte de dialogue ici
                      let dialog = new Dialog.ModalDialog({
                          styleClass: 'prompt-dialog',
                          destroyOnClose: false
                      });
              
                      dialog.contentLayout.add(new St.Label({
                          text: 'Voulez-vous exécuter un script avant de fermer la session ?'
                      }));
              
                      dialog.setButtons([
                          {
                              label: 'Oui',
                              action: () => {
                                  // Exécuter un script shell ici
                                  Shell.util_spawn(['sh', '-c', '/chemin/vers/votre/script.sh']);
                                  dialog.close();
                                  display.end_session(true);  // Confirmer la déconnexion
                              }
                          },
                          {
                              label: 'Non',
                              action: () => {
                                  dialog.close();
                                  display.end_session(true); // Confirmer la déconnexion sans exécuter le script
                              },
                              key: Dialog.DEFAULT_CANCEL_ACTION
                          }
                      ]);
              
                      dialog.open();
                  });
              }
              
              function disable() {
                  // Nettoyage lors de la désactivation
                  if (logoutSignal) {
                      global.display.disconnect(logoutSignal);
                      logoutSignal = null;
                  }
              }
              
              
              • [^] # Re: voir du côté de /etc/gdm3/PostSession/Default ou un fichier dans le même dossier ?

                Posté par  (site web personnel) . Évalué à 3.

                Sans ChatGPT… il y a a priori beaucoup d'extensions qui touchent de près ou de loin au concept de session, cf. une recherche de session sur https://extensions.gnome.org/

                Installer/utiliser une extension ou réutiliser le code devrait être plutôt simple…

                Debian Consultant @ DEBAMAX

                • [^] # Re: voir du côté de /etc/gdm3/PostSession/Default ou un fichier dans le même dossier ?

                  Posté par  . Évalué à 1.

                  Merci à tous les deux pour la piste prometteuse des extensions Gnome Shell.
                  Malheureusement, n'étant pas programmeur à la base, elle va me demander un peu plus de boulot.

                  • La solution ChatGPT injectée dans une extension créée avec la commande gnome-extensions create --interactive ne marche pas directement sous Gnome 3.38 (je suis sous Debian oldstable). Ça ne me surprend guère, car Gnome change beaucoup et régulièrement le fonctionnement des extensions. Je testerai en VM dans une Fedora 40, pour vérifier que c'est bien une question de version.

                  • il me semble que parmi les extensions trouvées avec une recherche session sur https://extensions.gnome.org/, il n'y en a pas qui se déclenchent lorsque l'utilisateur se déconnecte.

                  Je vais essayer d'investiguer (test en version récente, debug pour adapter ensuite), et vous direz si je m'en sors.

                  Néanmoins sur la solution ChatGPT, il me semble qu'il affiche une boîte de dialogue inutile pour moi : 'Voulez-vous exécuter un script avant de fermer la session ?'
                  En conséquence, cela réduirait le code à assimiler et adapter à :

                  const { St, Main, Shell, Meta } = imports.gi;
                  const Dialog = imports.ui.modalDialog;
                  const ExtensionUtils = imports.misc.extensionUtils;
                  
                  let logoutSignal;
                  
                  function init() {
                      // Initialisation si nécessaire
                  }
                  
                  function enable() {
                      // Exécuter un script shell ici
                      logoutSignal = global.display.connect('end-session', (display, screen) => {
                          Shell.util_spawn(['sh', '-c', '/chemin/vers/votre/script.sh']);
                      });
                  }
                  
                  function disable() {
                      // Nettoyage lors de la désactivation
                      if (logoutSignal) {
                          global.display.disconnect(logoutSignal);
                          logoutSignal = null;
                      }
                  }

                  c'est ça ?

                  • [^] # Re: voir du côté de /etc/gdm3/PostSession/Default ou un fichier dans le même dossier ?

                    Posté par  . Évalué à 2.

                    la demande initiale :

                    J'aimerai donc que mon ordinateur me demande à l'extinction si je désire couper ou non le wifi, lorsqu'il constate qu'il est encore allumé.

                    Tu demandes à la fermeture de session "voulez-vous couper le wifi ?" et si la personne dit oui, tu exécute la commande (ou le script) de coupure wifi (sans poser de question), sinon tu sors sans couper.

                    L'interactivité se fait au niveau de l'extension, pas du script. Ca restte de mon point de vue plus logique.

                    • [^] # Re: voir du côté de /etc/gdm3/PostSession/Default ou un fichier dans le même dossier ?

                      Posté par  . Évalué à 1.

                      100% d'accord avec la logique, mais avec mes capacités limitées de programmation, le bash reste plus simple, car avant de me poser la question, il faut d'abord interroger la box pour savoir si le wifi est allumé (via le programme sysbus.py), ce que fait déjà mon script.

                      Sinon, j'ai testé ton code en VM sous Gnome 46 (Fedora 40), et Gnome 43 (Debian 12) et il plante aussi. J'avais systématiquement la même erreur, comme sous Gnome 3.38 :

                      Error: Requiring Main, version none: Typelib file for namespace 'Main' (any version) not found
                      

                      En farfouillant un peu, j'ai réussi à modifier le code pour le faire accepter par Gnome (au moins 3.38), mais l'erreur qu'il me sort désormais est plus inquiétante :

                      Error: No signal 'end-session' on object 'MetaDisplay'
                      

                      Il semblerait que ce signal end-session n'existe pas, au moins sur l'objet interrogé, et il ne se passe effectivement rien en fin de session.

                      • [^] # Re: voir du côté de /etc/gdm3/PostSession/Default ou un fichier dans le même dossier ?

                        Posté par  . Évalué à 2.

                        J'aurais bien aimé essayer, mais je n'ai pas vraiment le temps ce week-end ( j'ai du ménage et de l'exercice à rattrapper ce week-end … je me suis laissé un peu aller ces derniers jours). Je verrai si je trouve le temps de tester (chatgpt a peut-être racconté n'importe quoi, ou le signal en question n'est peut-être plus disponible).

                        • [^] # Re: voir du côté de /etc/gdm3/PostSession/Default ou un fichier dans le même dossier ?

                          Posté par  . Évalué à 1.

                          Merci déjà pour l'effort intellectuel, bonne chance pour l'effort physique. ;)

                          Si ça t'intéresse quand même, il n'y a aucune urgence, j'utilise une alternative, comme je le disais dans mon post initial :

                          PS : dans l'attente, je passe par l'extension Executor qui m'affiche un petit message dans la barre supérieure quand le wifi est allumé.

                          Et puis je crains que même s'il y a un signal à trouver, il ne soit envoyé lui aussi trop tard, quand un programme ne peut plus être interactif.

                      • [^] # Re: voir du côté de /etc/gdm3/PostSession/Default ou un fichier dans le même dossier ?

                        Posté par  . Évalué à 2.

                        100% d'accord avec la logique, mais avec mes capacités limitées de programmation, le bash reste plus simple, car avant de me poser la question, il faut d'abord interroger la box pour savoir si le wifi est allumé (via le programme sysbus.py), ce que fait déjà mon script.

                        Dans ce cas je ne suis pas sûr que cette approche fonctionne : il faudra peut-être lancer un terminal qui appelle ton script plutôt que de lancer le script directement (a moins que tu utilises un framework graphique dans ton script …).

                        .

                • [^] # Re: voir du côté de /etc/gdm3/PostSession/Default ou un fichier dans le même dossier ?

                  Posté par  . Évalué à 2.

                  J'ai cherché de ce côté mais je n'ai rien trouvé qui correspondant, et j'ai cherché dans la doc gnome shell extension, mais celle-ci est assez mal faite de mon point de vue. Normal vu qu'ils ne sont pas fichius de mettre de la stabilité dans leurs développements, donc pourquoi documenter un truc qui change tous les 4 matins ?

    • [^] # Re: voir du côté de /etc/gdm3/PostSession/Default ou un fichier dans le même dossier ?

      Posté par  . Évalué à 1.

      sinon pour info, tu m'as donné l'idée de tester avec d'autres gestionnaires de session, mais j'ai testé en VM lightDM et lxdm, qui échouent aussi lamentablement (touch OK, mais pas zenity)…

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.