Como eu chamo gnome-session-quit com a contagem regressiva da Unity?

13

Para podermos desligarmos com um atalho de teclado , podemos atribuir gnome-session-quit ---power-off para um atalho personalizado.

No Unity, isso levará ao seguinte diálogo:

Entãoprecisamosdepelomenosdoistoquesnotecladoparafinalmentedesligarnossosistema.IssoébastanteinconvenienteeeuprefeririaacaixadediálogodedesligamentoantigoquandovocêpudessedesligarapenaspressionandoReturnoudeixandoacontagemregressivapadrãode60segundos.

Aochamargnome-session-quit--poweroffdeumasessãodesessãodeflashbackdoGNOMEnomesmosistema(14.04LTS),acaixadediálogoantiga,incluindoacontagemregressiva,retorna:

Então sabemos que ele mora em algum lugar.

Existe alguma maneira de chamar essa caixa de diálogo antiga ao executar uma sessão do Unity?

    
por Takkat 29.11.2014 / 13:11

2 respostas

10

Aqui está um script para emular o comportamento desejado. Deve ser executado como com sudo . Pode ser ligado a um atalho de teclado (com adição preliminar do comando shutdown ao arquivo sudoers para permitir a execução sem senha ). Simplista, conciso e faz o trabalho.

#!/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

Atualização: 14 de junho

Como sugerido por Takkat, aqui está um script que utiliza a opção --timer do zenity e dbus para obter o mesmo comportamento sem necessidade de acesso ao 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

A ideia básica aqui é que a opção de tempo limite do zenity sai com um código maior que 0, o que normalmente significa que o comando falhou. Portanto, ao tratar a opção de cancelamento e o tempo limite do zenity como a condição que permitirá o encerramento, usamos o operador OR ( || ) para desligar apenas se o usuário clicar no botão cancelar (rotulado como "DOIT") ou o tempo limite da caixa de diálogo.

Outra variação para melhorar a experiência do usuário pode ser feita com yad (precisa ser instalado primeiro com esses comandos sudo apt-add-repository ppa:webupd8team/y-ppa-manager;sudo apt-get update; sudo apg-get install yad ). Esta variação usa a barra de progresso para permitir que o usuário saiba quanto tempo resta

    #!/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

Outra versão possível, leva em consideração que, se você alterar o rótulo do botão ok do zenity, o botão destacado por padrão pode ou não ser o botão 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

O script desliga o sistema em qualquer retorno que não seja 0. Se o tempo limite do script expirar, o valor de retorno de 1 ou 5 informará ao script para executar a else part

    
por Sergiy Kolodyazhnyy 11.06.2015 / 00:27
6

Não literalmente o que você pediu, mas pelo menos uma solução (efetivamente) comparável seria colocar o script abaixo sob uma tecla de atalho.

O que faz

Quando a tecla de atalho é usada:

  • o comando gnome-session-quit --power-off é executado
  • o mouse é movido para o botão "fechar" correspondente, efetivamente fazendo o botão de desligamento pré-selecionado:

Então:

  • SeousuáriopressionarEnter,osistemaserádesligado
  • Seousuárionãofizernada,osistemaaguardará30segundos(ouqualqueroutroperíododetempoquevocêqueiradefinir)eseráencerrado.
  • Seousuáriomoveromouseduranteos30segundos,oprocedimentoseráinterrompido

Oscript

#!/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

Como usar

Tenho certeza que você sabe como usá-lo, mas aqui vamos por razões de habbits:

  1. O script usa xdotool

    sudo apt-get install xdotool
    
  2. Copie o script em um arquivo vazio, salve-o como run_close.py

  3. Na seção head, defina a localização da tela do botão de desligamento na janela de fechamento (meu primeiro palpite estava correto):

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

    e o tempo a aguardar antes de encerrar de forma autônoma:

    #--- set the time to wait before shutdown
    countdown = 30
    
  4. Teste-o pelo comando:

    python3 /path/to/run_close.py
    

    Teste com toda a opção: pressionando Enter para desligamento imediato, desligamento automático e quebra do procedimento por movimento do mouse

  5. Se tudo funcionar bem, adicione-o a uma tecla de atalho: escolha: Configurações do sistema > "Teclado" > "Atalhos" > "Atalhos personalizados". Clique no botão "+" e adicione o comando:

     python3 /path/to/run_close.py
    

EDITAR

Abaixo de uma versão do script que não precisa de nenhuma configuração adicional. Calcula as coordenadas do botão quit, não importa qual seja a resolução da tela.

A configuração é praticamente a mesma, mas [3.] pode ser ignorado.

#!/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

Explicação

O tamanho da janela do Session Manager para fechar o sistema é sempre centralizado e de tamanho fixo (absoluto), independente da resolução da tela. Portanto, a posição relativa ao centro da tela é um fator constante.

Tudo o que precisamos fazer é ler a resolução da tela e calcular a posição do botão a partir dali.

A função aplicada ( get_qloc() ) calcula a resolução da tela esquerda , já que é aquela em que o diálogo aparecerá.

Nota

A hora, definida na linha time.sleep(0.4) , é definida para sistemas relativamente lentos, para garantir que o mouse seja movido após a janela de desligamento aparecer. Em sistemas mais rápidos, pode ser mais curto, em sistemas mais lentos (como, possivelmente, uma VM), pode ser necessário definir para mais tempo.

    
por Jacob Vlijm 10.06.2015 / 23:36