Unityからカウントダウンしてgnome-session-quitを呼び出すにはどうすればよいですか?


13

キーボードショートカットでシャットダウンできるようにするにgnome-session-quit ---power-offは、カスタムショートカットに割り当てることができます。

Unityでは、これにより次のダイアログが表示されます。

ここに画像の説明を入力してください

次に、システムの電源を最終的にオフにするために、少なくとも2回のキーストロークが必要です。これはかなり不便Returnです。60秒のデフォルトのカウントダウンを押すか、待機させるだけで電源をオフにできる場合は、古いシャットダウンダイアログを使用します。

同じシステム(14.04 LTS)上のGNOMEセッションフラッシュバックセッションgnome-session-quit --poweroffから呼び出すと、カウントダウンを含む古いダイアログが戻ります:

ここに画像の説明を入力してください

だから私たちはそれがどこかに住むことを知っています。

Unityセッションを実行しているときにこの古いダイアログを呼び出す方法はありますか?


団結した人は隠されたタイマーを持っていないので、とにかく60秒後に電源が切れますか??
ティム14年


両方に:新しいダイアログの問題は、どうすればよいかをユーザーが選択するまで待機することです...:/
Takkat 14年

2
@SergウィンドウはSession Managerに属します(新しいウィンドウのプロパティをファイルに書き込むためにバックグラウンドスクリプトを実行しました)。問題は、ウィンドウマネージャによって動作が異なることです。
ジェイコブVlijm

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

更新: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

ここでの基本的な考え方は、zenityのタイムアウトオプションが0より大きいコードで終了するということです。これは通常、コマンドが失敗したことを意味します。そのため、zenityのキャンセルオプションとタイムアウトをシャットダウンを許可する条件として扱うこと||で、ユーザーがキャンセルボタン(「DOIT」というラベル)をクリックするか、ダイアログがタイムアウトした場合にのみOR演算子()を使用してシャットダウンします。

ユーザーエクスペリエンスを改善する別のバリ​​エーションを使用して行うことができます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の[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

スクリプトは、0以外の戻り時にシステムをシャットダウンします。スクリプトがタイムアウトした場合、1または5の戻り値はスクリプトにelseパーツを実行するよう指示します


sudoで実行したり、root以外のユーザーにシャットダウンを許可したりすると、チャームのように機能します。そんなことはしたくない。私は死を免れ、ユーザによって実行され、スクリプトを有効にするには、次のように編集を提案してみましょう:1.電源オフのために使用DBUSをなどして、この答えで提案 2.使用zenity --timeout作り付けのタイマー。これにより、後でシャットダウンをキャンセル/再起動する必要がなくなります。
タッカット

@Takkatは、あなたの提案を使用する別のスクリプトを追加しました。確認してください
セルギーKolodyazhnyy

ルートパスワードなしで実際にシャットダウンしますが、RETURNキーを使用した即時シャットダウンでは、OK / DOITボタンはデフォルトで選択されていません。それを行うif [[ $? -eq 1 ]] ; then exit \else dbus...条件で同様のスクリプトを使用します。明らかに、古いログアウトヘルパーを呼び出す方法がないように
見え

yadをインストールするコマンドを追加してください;)
AB

賞金を両方の答えに分割できるといいのですが。このように2つの同様にすばらしい答えをした後、ここで決めるのは非常に困難でした。最後に、ジェイコブに答えました。彼の答えはもう少し融通が利きそうだからです。しかし、スクリプトは見事に機能し、非常に簡単です。代わりに承認済みとしてマークし、トップアンサーとして表示します。これにより、さらに多くの票が得られることを願っています。
タックカット

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
    

編集

追加の設定を必要としないバージョンのスクリプトの下。画面の解像度に関係なく、終了ボタンの座標を計算します。

セットアップはほとんど同じですが、[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修正済み。このバージョンはどの解像度でも動作するはずです。
ジェイコブVlijm

すごい!私のVMでも問題なく動作します。
Takkat
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.