Як мені викликати gnome-session-quit при відліку від Unity?


13

Для відключення за допомогою комбінації клавіш ми можемо призначити gnome-session-quit ---power-offспеціальний ярлик.

У Unity це призведе до наступного діалогу:

введіть тут опис зображення

Тоді нам потрібні ще принаймні два натискання клавіш, щоб остаточно вимкнути нашу систему. Це досить незручно, і я вважаю за краще старий діалогове вікно вимкнення, коли ви можете переключитися, натиснувши Returnабо давши йому чекати зворотного відліку за замовчуванням 60 секунд.

Під час дзвінка gnome-session-quit --poweroffз сеансу зворотного відтворення сеансу GNOME в тій же системі (14,04 LTS) повертається старе діалогове вікно, включаючи зворотний відлік:

введіть тут опис зображення

Тож ми знаємо, що десь живе.

Чи є можливість зателефонувати до цього старого діалогового вікна під час запуску сесії Unity?


Чи не є прихований таймер, тому він все одно вимикається через 60 секунд ??
Тім

askubuntu.com/questions/14794/… може допомогти
Тім

І те й інше: річ із нового діалогового вікна полягає в тому, що він, очевидно, чекає вибору користувача, що робити ...: /
Таккат

2
@Serg Вікно належить до менеджера сесій (я запустив фоновий скрипт, щоб записати властивості нового вікна у файл). Проблема в тому, що вона поводиться по-різному, залежно від менеджера вікон.
Яків Влійм

1
@JacobVlijm: так, це теж я міг бачити ... це, мабуть, опитує WM, а потім викликає ту чи іншу процедуру, але я не знайшов способу змусити це.
Таккат

Відповіді:


10

Ось сценарій для наслідування потрібної поведінки. Потрібно керувати як з 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, що зазвичай означає, що команда не виконана. Отже, трактуючи параметр скасування зенситу та час очікування як умову, яка дозволить відключити, ми використовуємо оператор АБО ( ||) для відключення лише у тому випадку, якщо користувач натискає кнопку скасування (позначена як "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 --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частину


Працює як принадність при запуску із судо або дозволяють користувачам, які не користуються коренем, відключення. Я б краще не робив цього. Дозвольте запропонувати наступні зміни, щоб увімкнути ваш сценарій смертним користувачем: 1. Використовуйте dbus для перебору ресурсів, як було запропоновано у цій відповіді. 2. Використовуйте zenity --timeoutвбудований таймер. Цим нам не доведеться скасовувати / перезавантажувати відключення пізніше.
Таккат

@Takkat додав ще один сценарій, який використовує ваші пропозиції. Перегляньте
Сергій Колодяжний

Це дійсно вимикання без пароля root, але кнопка OK / DOIT не вибрана за замовчуванням для негайного відключення за допомогою клавіші RETURN. Ми використовуємо аналогічний сценарій з if [[ $? -eq 1 ]] ; then exit \else dbus...умовою, яка це робить. Очевидно, схоже, немає способу викликати старого помічника виходу ...
Таккат

Додайте команди для встановлення yad;)
AB

Бажаю, щоб я міг розділити щедрість на обидві відповіді. Тут було важко зважитися після двох таких не менш чудових відповідей. Нарешті я дав це Якову, оскільки його відповідь виглядає дещо більш різнобічним. Але ваш сценарій чудово виконує свою роботу, і це так просто. Я відзначу це як прийняте замість того, щоб він відображався як головна відповідь. Я сподіваюся, що за цей час він отримає ще більше голосів.
Таккат

6

Не буквально те, про що ви просили, але, принаймні, (ефективно) порівнянне рішення було б помістити сценарій нижче під клавішу швидкого доступу.

Що це робить

Коли використовується клавіша швидкого доступу:

  • 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

Як користуватись

Я впевнений, що ви знаєте, як ним користуватися, але тут ми їдемо з привидів:

  1. Сценарій використовує xdotool

    sudo apt-get install xdotool
    
  2. Скопіюйте скрипт у порожній файл, збережіть його як run_close.py

  3. У головному розділі встановіть на екрані місце закриття у закритому вікні (моя перша здогадка була правильною):

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

    і час почекати перед тим, як вимкнути без нагляду:

    #--- set the time to wait before shutdown
    countdown = 30
    
  4. Перевірте його за допомогою команди:

    python3 /path/to/run_close.py
    

    Перевірте його з усіма можливими параметрами: натиснути Enterдля негайного вимкнення, без нагляду і відключити процедуру переміщенням миші

  5. Якщо все працює добре, додайте його до клавіші швидкого доступу: виберіть: Налаштування системи> "Клавіатура"> "Ярлики"> "Спеціальні ярлики". Клацніть "+" і додайте команду:

     python3 /path/to/run_close.py
    

EDIT

Нижче версії сценарію, яка не потребує додаткових налаштувань. Він обчислює координати кнопки виходу, незалежно від роздільної здатності екрана.

Налаштування майже однакові, але [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), встановлюється для відносно повільних систем, щоб переконатися в переміщенні миші після появи вікна закриття. У більш швидких системах він може бути коротшим, на повільних системах (наприклад, VM), можливо, знадобиться встановити довший.


@Takkat Виправлено, ця версія повинна працювати на будь-якій роздільній здатності.
Яків Влійм

Чудово! Це працює бездоганно і на моєму ВМ.
Таккат
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.