キーボードとマウスのアクティビティおよび全画面ウィンドウによってトリガーされ、一定時間非アクティブになった後にコマンドを実行するにはどうすればよいでしょうか。

キーボードとマウスのアクティビティおよび全画面ウィンドウによってトリガーされ、一定時間非アクティブになった後にコマンドを実行するにはどうすればよいでしょうか。

私のマシンは5分間操作がないとサスペンドしますが、4分30秒操作がないとコマンドを実行したいです。4分30秒後にコマンドを実行する方法はありますか?いいえフルスクリーンウィンドウとキーボードとマウスの操作がない?

私はUbuntu GNOME 15.10とGNOME 3.18を使用しています。この質問ただし、xprintidleフルスクリーン ウィンドウではトリガーされず、キーボードとマウスの操作によってのみトリガーされます。

答え1

アイドル時間後にコマンドを実行する。フルスクリーンの両方でトリガーされる。そしてマウス/キーボードのアクティビティ

こんにちは、Paranoid Panda さん。以下のスクリプトは、説明どおりに動作するはずです。

問題は、(任意の) ウィンドウをフルスクリーンにしたり、マウスやキーボードの操作を行ったりすると、「実際の」アイドル時間がリセットされるはずだったことです。xprintidleコマンド ラインからはリセットできないため、フルスクリーン ウィンドウの場合はアイドル時間を減算することで解決しました。

  • ループ内でスクリプトは現在のアイドル時間を調べます
  • xrandrいずれかのウィンドウが最大化されている場合(との両方を使用して、いずれかのウィンドウが画面の解像度と同じ大きさであるかどうかを確認しますwmctrl -lG)、現在アイドル時間はアイドル時間から減算され、ウィンドウがフルスクリーンでなくなった場合でも、正しい「実際の」アイドル時間が得られます。

スクリプト

#!/usr/bin/env python3
import subprocess
import time
import sys

idletime = int(sys.argv[1])
command = sys.argv[2]

get = lambda cmd: subprocess.check_output(cmd).decode("utf-8").strip()

def get_res():
    xr = [s for s in get(["xrandr"]).split() \
          if "+0+0" in s][0].split("x"); xr[1] = xr[1].split("+")[0]
    return xr

res = get_res()

def check():
    front = [l for l in get(["xprop", "-root"]).splitlines() \
             if "_NET_ACTIVE_WINDOW(WINDOW):" in l][0].split("#")[-1].strip()
    front = front[:2]+(10-len(front))*"0"+front[2:]
    try:
        wdata = subprocess.check_output(
            ["wmctrl", "-lG"]
            ).decode("utf-8").splitlines()
        match = [l for l in wdata if front in l][0].split()[4:6]
        if match == res:
            return True
        else:
            return False
    except subprocess.CalledProcessError:
        pass

minus = 0; real_idle = 0; t1 = 0; due_1 = False
while True:
    time.sleep(1)
    fscreen = check()
    t2 = int(int(get(["xprintidle"]))/1000)
    if t2 < t1:
        minus = 0; real_idle = 0
    else:
        if fscreen == True:
            minus = t2
    real_idle = t2 - minus
    due_2 = [real_idle > idletime][0]
    if all([real_idle > idletime, due_1 != due_2]):
        subprocess.Popen(["/bin/bash", "-c", command])
    due_1 = due_2
    t1 = t2

使用するには

  • スクリプトには以下が必要wmctrlですxprintidle:

    sudo apt-get install xdotool xprintidle
    
  • スクリプトを空のファイルにコピーし、run_ontime.py

  • 次のコマンドで実行します:

    python3 /path/to/run_ontime.py <seconds> <command>
    

    コマンドにスペースが含まれている場合は、引用符で囲む必要があります。たとえば次のようにテストしました:

    python3 /path/to/run_ontime.py 10 "firefox askubuntu.com"
    

    それはうまくいきました:)

注記

アイドル時間が経過するたびにコマンドが 1 回実行されます。

関連情報