Как мне вызвать gnome-session-quit с обратным отсчетом от Unity?
Для возможности выключения с помощью сочетания клавиш мы можем назначить gnome-session-quit ---power-off
на пользовательский ярлык.
В Unity это приведет к следующему диалогу:
Затем нам нужно еще как минимум два нажатия клавиш, чтобы наконец отключить нашу систему. Это довольно неудобно, и я бы предпочел старое диалоговое окно выключения, когда вы можете выключить питание, просто нажав Return или оставив его ждать по умолчанию обратный отсчет 60 секунд.
При звонке gnome-session-quit --poweroff
из сеанса ретроспективного сеанса GNOME в той же системе (14.04 LTS) возвращается старое диалоговое окно, включая обратный отсчет:
Итак, мы знаем, что это где-то обитает.
Есть ли способ вызвать этот старый диалог при запуске сеанса Unity?
2 ответа
Вот скрипт для эмуляции желаемого поведения. Должен быть запущен как с sudo
, Может быть привязан к сочетанию клавиш (с предварительным добавлением shutdown
команда для файла sudoers, чтобы разрешить запуск без пароля). Упрощенно, лаконично и выполняет свою работу.
#!/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
Обновление: 14 июня
Как предлагает Таккат, вот скрипт, который использует опцию --timer zenity и dbus для достижения того же поведения без необходимости доступа 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
Основная идея здесь заключается в том, что опция времени ожидания zenity завершается с кодом больше 0, что обычно означает, что команда не выполнена. Таким образом, рассматривая опцию отмены zenity и тайм-аут как условие, которое позволит завершить работу, мы используем оператор ИЛИ (||
) для отключения, только если пользователь нажимает кнопку отмены (помеченную как "DOIT") или время ожидания диалога
Еще один вариант улучшения пользовательского опыта может быть сделан с yad
(сначала нужно установить с помощью этих команд sudo apt-add-repository ppa:webupd8team/y-ppa-manager;sudo apt-get update; sudo apg-get install yad
). Этот вариант использует индикатор выполнения, чтобы сообщить пользователю, сколько времени осталось
#!/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
В другой возможной версии учитывается, что если вы измените метку кнопки ОК в zenity, кнопка, выделенная по умолчанию, может быть или не быть кнопкой ОК.
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
Сценарий завершает работу системы при любом возврате, который не равен 0. Если время ожидания сценария истекло, возвращаемое значение 1 или 5 указывает сценарию выполнить else
часть
Не буквально то, что вы просили, но по крайней мере (эффективно) сопоставимое решение состояло бы в том, чтобы поместить скрипт ниже под сочетанием клавиш.
Что оно делает
Когда используется сочетание клавиш:
gnome-session-quit --power-off
команда выполняетсямышь перемещается к соответствующей кнопке "закрыть", эффективно делая предварительно выбранную кнопку выключения:
Затем:
- Если пользователь нажимает Enter, система выключается
- Если пользователь ничего не делает, система ждет 30 секунд (или любой другой период времени, который вы хотите установить) и выключается.
- Если пользователь перемещает мышь в течение 30 секунд, процедура останавливается
Сценарий
#!/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
Как пользоваться
Я почти уверен, что вы знаете, как его использовать, но здесь мы пойдем по причинам привычки:
Скрипт использует
xdotool
sudo apt-get install xdotool
Скопируйте скрипт в пустой файл, сохраните его как
run_close.py
В разделе заголовка установите расположение экрана кнопки выключения в окне закрытия (мое первое предположение было правильным):
#--- set the location of the close button x, y q_loc = [1050, 525]
и время ожидания, прежде чем отключить без присмотра:
#--- set the time to wait before shutdown countdown = 30
Протестируйте его командой:
python3 /path/to/run_close.py
Протестируйте его с помощью всех опций: нажмите Enter для немедленного выключения, автоматического выключения и прекратите процедуру с помощью мыши
Если все работает нормально, добавьте его к сочетанию клавиш: выберите: "Системные настройки" > "Клавиатура" > "Ярлыки" > "Пользовательские ярлыки". Нажмите "+" и добавьте команду:
python3 /path/to/run_close.py
РЕДАКТИРОВАТЬ
Ниже приведена версия скрипта, которая не требует каких-либо дополнительных настроек. Он рассчитывает координаты кнопки выхода, независимо от разрешения экрана.
Настройка почти такая же, но [3.]
можно пропустить
#!/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
объяснение
Размер окна диспетчера сеансов для закрытия системы всегда центрирован и имеет фиксированный (абсолютный) размер, не зависящий от разрешения экрана. Поэтому положение относительно центра экрана является постоянным фактором.
Все, что нам нужно сделать, это прочитать разрешение экрана и рассчитать положение кнопки оттуда.
Применяемая функция (get_qloc()
) рассчитывает разрешение левого экрана, так как именно там появится диалог.
Заметка
Время, установленное в строке time.sleep(0.4)
устанавливается для относительно медленных систем, чтобы убедиться, что мышь перемещается после появления окна выключения. В более быстрых системах оно может быть короче, в более медленных системах (например, возможно, в ВМ) может потребоваться установить более продолжительное время.