如何使用 Unity 的倒计时调用 gnome-session-quit?

Tak*_*kat 14 shutdown unity gnome-classic

为了能够使用键盘快捷键关闭,我们可以分配gnome-session-quit ---power-off给自定义快捷键。

在 Unity 中,这将导致以下对话框:

在此处输入图片说明

然后我们需要另外至少两次击键才能最终关闭我们的系统。这是相当不方便的,我更喜欢旧的关闭对话框,当您只需按下Return或让它等待 60 秒的默认倒计时即可关闭电源时。

gnome-session-quit --poweroff从同一系统 (14.04 LTS) 上的GNOME 会话闪回会话调用时,包含倒计时的旧对话框返回:

在此处输入图片说明

所以我们知道它住在某处。

在运行 Unity 会话时,有没有办法调用这个旧对话框?

Ser*_*nyy 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
Run Code Online (Sandbox Code Playgroud)

更新:6 月 14 日

正如 Takkat 所建议的,这里有一个脚本,它利用 zenity 的 --timer 选项和 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
Run Code Online (Sandbox Code Playgroud)

这里的基本思想是 zenity 的超时选项以大于 0 的代码退出,这通常意味着命令失败。因此,通过将 zenity 的取消选项和超时视为允许关闭的条件,我们||仅在用户单击取消按钮(标记为“DOIT”)或对话框超时时才使用 OR 运算符 ( ) 关闭。

可以使用另一个改进用户体验的变体yad(需要先使用这些命令安装sudo apt-add-repository ppa:webupd8team/y-ppa-manager;sudo apt-get update; sudo apt-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
Run Code Online (Sandbox Code Playgroud)

另一个可能的版本确实考虑到如果您更改 Zenity 的 ok 按钮标签,默认情况下突出显示的按钮可能是也可能不是 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
Run Code Online (Sandbox Code Playgroud)

脚本在任何不为 0 的返回值时关闭系统。如果脚本超时,返回值 1 或 5 告诉脚本执行该else部分


Jac*_*ijm 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
Run Code Online (Sandbox Code Playgroud)

如何使用

我很确定你知道如何使用它,但我们出于习惯原因:

  1. 该脚本使用 xdotool

    sudo apt-get install xdotool
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将脚本复制到一个空文件中,另存为 run_close.py

  3. 在 head 部分,设置关闭窗口中关闭按钮的屏幕位置(我的第一个猜测是正确的):

    #--- set the location of the close button x, y
    q_loc = [1050, 525]
    
    Run Code Online (Sandbox Code Playgroud)

    以及无人值守关机前的等待时间:

    #--- set the time to wait before shutdown
    countdown = 30
    
    Run Code Online (Sandbox Code Playgroud)
  4. 通过以下命令测试运行它:

    python3 /path/to/run_close.py
    
    Run Code Online (Sandbox Code Playgroud)

    使用所有选项进行测试:按下Enter立即关机、无人值守关机和通过鼠标移动中断程序

  5. 如果一切正常,请将其添加到快捷键:选择:系统设置>“键盘”>“快捷方式”>“自定义快捷方式”。单击“+”并添加命令:

     python3 /path/to/run_close.py
    
    Run Code Online (Sandbox Code Playgroud)

编辑

下面是不需要任何额外设置的脚本版本。无论屏幕的分辨率如何,它都会计算退出按钮的坐标。

设置几乎相同,但[3.]可以跳过。

sudo apt-get install xdotool
Run Code Online (Sandbox Code Playgroud)

解释

用于关闭系统的会话管理器窗口的大小始终居中并具有固定(绝对)大小,与屏幕分辨率无关。因此,相对于屏幕中心的位置是一个常数因素。

然后我们需要做的就是读取屏幕的分辨率并从那里计算按钮的位置。

应用函数 ( get_qloc()) 计算左屏幕的分辨率,因为那是将出现对话的地方。

笔记

该行time.sleep(0.4)中设置的时间是为相对较慢的系统设置的,以确保在出现关闭窗口移动鼠标。在较快的系统上,它可以更短,在较慢的系统(可能是虚拟机)上,它可能需要设置得更长。