web-dev-qa-db-fra.com

Comment appeler gnome-session-quit avec un compte à rebours de Unity?

Pour pouvoir fermer avec un raccourci clavier nous pouvons assigner gnome-session-quit ---power-off à un raccourci personnalisé.

Dans Unity, cela ouvrira la boîte de dialogue suivante:

enter image description here

Ensuite, nous avons besoin d'au moins deux autres frappes pour éteindre enfin notre système. C’est plutôt gênant et je préférerais l’ancien dialogue de fermeture lorsque vous pouviez éteindre en appuyant simplement sur Return ou le laisser attendre le compte à rebours par défaut de 60 secondes.

Lorsque vous appelez gnome-session-quit --poweroff à partir d'une session de GNOME sur le même système (14.04 LTS), l'ancien dialogue, y compris le compte à rebours, revient:

enter image description here

Nous savons donc que cela habite quelque part.

Est-il possible d'appeler cet ancien dialogue lors de l'exécution d'une session Unity?

13
Takkat

Voici un script pour émuler le comportement souhaité. Doit être exécuté comme avec Sudo. Peut être lié à un raccourci clavier (avec l'ajout préalable de la commande shutdown au fichier sudoers en autoriser l'exécution sans mot de passe ). Simpliste, concis et fait le travail.

#!/bin/bash
# Date: June 11,2015
# Author: Serg Kolo
# Description: a script to emulate
# behavior of GNOME session flashback
# shutdown dialog

# Tell ubuntu to shutdown in 1 min
shutdown -P +1 &
# Show the dialog
zenity --question --text="Shutdown now ? Automatic shutdown in 60 seconds" --ok-label="DOIT" 
# If user clicks DOIT, then cancel the old 
# shutdown call that has countdown,
# (because only one shutdown command can be run at a time), and
# tell ubuntu to shutdown immediately
# otherwise - cancel it
if [ $? -eq 0 ];then
        shutdown -c
        shutdown -P now
else
        shutdown -c
fi

Mise à jour: 14 juin

Comme suggéré par Takkat, voici un script qui utilise l'option --timer et dbus de zenity pour obtenir le même comportement sans avoir besoin d'un accès Sudo:

#!/bin/bash
# Date: June 14,2015
# Author: Serg Kolo
# Description: a script to emulate
# behavior of GNOME session flashback
# shutdown dialog
# version #2

zenity --question --text="Shutdown now ? Autoshutdown in 60 seconds" \
    --cancel-label="DOIT" --ok-label="NOPE" --timeout=60 ||  
  dbus-send --system --print-reply --dest=org.freedesktop.login1 \
    /org/freedesktop/login1 "org.freedesktop.login1.Manager.PowerOff" boolean:true

L'idée de base est que l'option de délai d'expiration de zenity se ferme avec un code supérieur à 0, ce qui signifie généralement que la commande a échoué. Donc, en considérant l'option d'annulation et le délai d'expiration de zenity comme la condition permettant l'arrêt, nous utilisons l'opérateur OR (||) uniquement si l'utilisateur clique sur le bouton d'annulation (appelé "DOIT"). ou le dialogue expire.

Une autre variante pour améliorer l'expérience utilisateur peut être réalisée avec yad (il faut d'abord l'installer avec ces commandes Sudo apt-add-repository ppa:webupd8team/y-ppa-manager;Sudo apt-get update; Sudo apg-get install yad). Cette variante utilise une barre de progression pour indiquer à l'utilisateur combien de temps il reste

    #!/bin/bash
    yad --auto-close --sticky --on-top --skip-taskbar --center \
  --text 'Shutdown now ? Autoshutdown in 60 seconds.' \
  --button="gtk-ok:1" --button="gtk-close:0" --image=dialog-question \ 
--title 'Shutdown' --timeout=60 --timeout-indicator=top || 
dbus-send --system --print-reply --dest=org.freedesktop.login1 \
/org/freedesktop/login1 "org.freedesktop.login1.Manager.PowerOff" boolean:true

Une autre version possible prend en compte le fait que si vous modifiez l’étiquette du bouton ok de zenity, le bouton mis en surbrillance par défaut peut ou non être le bouton ok.

zenity --question --timeout 10 --text="Automatic shutdown in 10 seconds"
if [[ $? -eq 1 ]] ; then
    # user clicked Cancel
    exit 
else
    dbus-send --system --print-reply --dest=org.freedesktop.login1 /org/freedesktop/login1 "org.freedesktop.login1.Manager.PowerOff" boolean:true
fi

Le script arrête le système lors de tout retour différent de 0. Si le délai d'expiration du script est dépassé, la valeur renvoyée, 1 ou 5, indique au script d'exécuter la partie else

10

Pas littéralement ce que vous avez demandé, mais au moins une solution comparable (effectivement) consisterait à placer le script ci-dessous sous une touche de raccourci.

Ce qu'il fait

Lorsque la touche de raccourci est utilisée:

  • la commande gnome-session-quit --power-off est exécutée
  • la souris est déplacée vers le bouton "fermer" correspondant, effectivement rendant le bouton d'arrêt présélectionné:

    enter image description here

Ensuite:

  • Si l'utilisateur appuie sur Enter, le système s'arrête
  • Si l'utilisateur ne fait rien, le système attend 30 secondes (ou toute autre période de temps que vous souhaitez définir) et s'arrête.
  • Si l'utilisateur déplace la souris pendant 30 secondes, la procédure est arrêtée

Le scénario

#!/usr/bin/env python3
import subprocess
import time

#--- set the location of the close button x, y
q_loc = [1050, 525]
#--- set the time to wait before shutdown
countdown = 30

subprocess.Popen(["gnome-session-quit", "--power-off"])
# for slower systems, set a longer break, on faster systems, can be shorter:
time.sleep(0.4)
subprocess.Popen(["xdotool", "mousemove", str(q_loc[0]), str(q_loc[1])])

coords1 = q_loc
t = 0

while True:
    time.sleep(1)
    cmd = "xdotool", "getmouselocation"
    currloc = subprocess.check_output(cmd).decode("utf-8").split()[:2]
    coords2 = [int(n.split(":")[1]) for n in currloc]
    if coords2 != coords1:
        break
    else:
        if t >= countdown:
            subprocess.Popen(["xdotool", "key", "KP_Enter"])
            break
    t += 1

Comment utiliser

Je suis presque sûr que vous savez comment l'utiliser, mais nous y allons pour des raisons d'habbit:

  1. Le script utilise xdotool

    Sudo apt-get install xdotool
    
  2. Copiez le script dans un fichier vide, enregistrez-le sous le nom run_close.py

  3. Dans la section principale, définissez l'emplacement du bouton d'arrêt dans la fenêtre de fermeture à l'écran (ma première hypothèse était exacte):

    #--- set the location of the close button x, y
    q_loc = [1050, 525]
    

    et le temps d'attendre avant la fermeture sans surveillance:

    #--- set the time to wait before shutdown
    countdown = 30
    
  4. Testez-le avec la commande:

    python3 /path/to/run_close.py
    

    Testez-le avec toutes les options: en appuyant sur Enter pour un arrêt immédiat, un arrêt sans surveillance et interrompre la procédure en déplaçant la souris

  5. Si tout fonctionne correctement, ajoutez-le à une touche de raccourci: choisissez: Paramètres système> "Clavier"> "Raccourcis"> "Raccourcis personnalisés". Cliquez sur le "+" et ajoutez la commande:

     python3 /path/to/run_close.py
    

MODIFIER

Ci-dessous une version du script qui ne nécessite aucun paramètre supplémentaire. Il calcule les coordonnées du bouton Quitter, quelle que soit la résolution de l'écran.

La configuration est à peu près la même, mais [3.] peut être ignoré.

#!/usr/bin/env python3
import subprocess
import time

#--- set the time to wait before shutdown
countdown = 30

def get_qloc():
    xr = subprocess.check_output(["xrandr"]).decode("utf-8").split()
    scrs = [s.split("+") for s in xr if all([s.count("x") == 1, s.count("+") == 2])]
    center = [int(int(s)/2) for s in [scr[0] for scr in scrs if scr[1] == "0"][0].split("x")]
    return [center[0] + 250, center[1]]

q_loc = get_qloc()

subprocess.Popen(["gnome-session-quit", "--power-off"])
# for slower systems, set a longer break, on faster systems, can be shorter:
time.sleep(0.4)
subprocess.Popen(["xdotool", "mousemove", str(q_loc[0]), str(q_loc[1])])

coords1 = q_loc
t = 0

while True:
    time.sleep(1)
    cmd = "xdotool", "getmouselocation"
    currloc = subprocess.check_output(cmd).decode("utf-8").split()[:2]
    coords2 = [int(n.split(":")[1]) for n in currloc]
    if coords2 != coords1:
        break
    else:
        if t >= countdown:
            subprocess.Popen(["xdotool", "key", "KP_Enter"])
            break
    t += 1

Explication

La taille de la fenêtre du gestionnaire de session permettant de fermer le système est toujours centrée et d'une taille fixe (absolue), indépendante de la résolution de l'écran. Par conséquent, la position par rapport au centre de l'écran est un facteur constant.

Il suffit alors de lire la résolution de l'écran et de calculer la position du bouton à partir de là.

La fonction appliquée (get_qloc()) calcule la résolution de écran de gauche, puisque c'est celle où le dialogue apparaîtra.

Remarque

L'heure, définie dans la ligne time.sleep(0.4) est définie pour les systèmes relativement lents, afin de s'assurer que la souris est déplacée après, la fenêtre de fermeture apparaît. Sur des systèmes plus rapides, il peut être plus court, sur des systèmes plus lents (comme éventuellement une machine virtuelle), il peut être nécessaire de définir une valeur plus longue.

6
Jacob Vlijm