我正在尝试使用xprintidle
来获取 X (Unity) 空闲时间,以便我可以在一定时间后将显示器置于睡眠状态。(我必须使用,xset dpms force off
因为使用正常的 Ubuntu 电源/挂起设置时,我的显示器不会重新打开。不同的问题...)但xprintidle
无论我是否在使用我的机器,每 30 秒都会重置为 0 毫秒。即,无论我是在移动鼠标/单击/滚动还是在键盘上打字。我怀疑有什么东西导致 Unity 认为我没有空闲,但我不知道那可能是什么。
以下是显示该问题的输出:
x-pc-linux% while [[ $(xprintidle) -lt 60000 ]]; do
echo "$(date +%T) $(xprintidle)" && sleep 1;
done
13:24:47 12
13:24:48 917
13:24:49 1924
13:24:50 2933
13:24:51 3940
13:24:52 4946
13:24:53 5955
13:24:54 6963
13:24:55 7969
13:24:56 8976
13:24:57 9982
13:24:58 10990
.
. # snip
.
13:25:08 21061
13:25:09 22069
13:25:10 23078
13:25:11 24085
13:25:12 342
13:25:13 1350
13:25:14 2358
13:25:15 3364
13:25:16 4372
13:25:17 5380
13:25:18 6388
13:25:19 7395
13:25:20 8402
13:25:21 9409
13:25:22 10417
.
. # snip
.
13:25:35 23511
13:25:36 24519
13:25:37 25525
13:25:38 26532
13:25:39 27540
13:25:40 28549
13:25:41 29556
13:25:42 551
13:25:43 1559
13:25:44 2566
^C%
注意空闲时间在 12 秒和 42 秒处如何重置。(好吧,我有最终答案,但不是这个问题!)
我也尝试过跑步w
(“w”命令的空闲时间输出说明了什么?),但不幸的是,X 空闲时间显示为“?xdm?”。
x-pc-linux% w
13:37:47 up 2 days, 3:28, 4 users, load average: 1.76, 2.04, 2.07
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
*** :0 :0 Sat10 ?xdm? 4days 0.59s /sbin/upstart --user
*** pts/1 :0 Sat10 2:09m 0.39s 0.30s zsh
*** pts/4 :0 Sun14 0.00s 5:34 0.00s w
*** pts/12 192.168.1.144 11:20 20:11 13.41s 13.32s zsh
[编辑] 我也尝试过直接从 XScreenSaver 扩展获取空闲时间这里在 Andrey Sidorov 的回答中,但我每 30 秒就会重置一次相同的计时器。
这x.org 文档仅提及
空闲字段指定自任何输入设备上接收到用户的最后一次输入以来的毫秒数。
答案1
查看源代码xprintidle
(请参阅下文了解我是如何做到这一点的),我们看到:
This program prints the "idle time" of the user to stdout. The "idle
time" is the number of milliseconds since input was received on any
input device. If unsuccessful, the program prints a message to stderr
and exits with a non-zero exit code.
因此,我猜想移动鼠标会重置超时。这是有道理的,因为所讨论的超时会导致屏幕变黑/锁定。
进一步查看源代码,可以看到xprintidle
使用的功能。(XScreenSaverAllocInfo()
、DPMSQueryExtension()
等)。阅读man
这些功能的页面将为您提供更多详细信息(man XScreenSaverAllocInfo
)。
我如何获得源代码来查看:
# Includes several set-up-the-environment steps
mkdir ${HOME}/apt-src
cd ${HOME}/apt-src
sudo apt-get install apt-src
apt-src install xprintidle
cd xprintidle-0.2/
ls
less xprintidle.c
cd ..
apt-src remove xprintidle
答案2
就我而言,当虚拟摄像头处于活动状态时,OBS 每隔约 30 秒重置一次空闲计时器。
我编写了一个脚本来忽略 30 秒的循环。这样,即使您无法找出导致周期性空闲重置的原因,您仍然可以根据空闲情况采取行动。
https://github.com/poleguy/sweep/blob/master/check_idle.py
关键逻辑是这样的:
def get_idle_corrected():
# get idle time, but ignoring any resets that occur at a 30 second period
# because these are due to obs interrupting the idle to force the screen active
global idle_last
global time_start
time_end = time.monotonic()
idle = int(subprocess.check_output("xprintidle").decode("utf-8").strip())/1000
if idle > idle_last:
# still idle
pass
elif idle_last + poll_period - idle > idle_periodic_reset_low and idle_last + poll_period - idle < idle_periodic_reset_high:
# ignore periodic reset near 30 seconds due to obs
pass
else:
# idle time went down, but not near the expected periodic reset due to obs.
# so this is reported as a true idle reset
time_start = time.monotonic() + idle
idle_last = idle
print(f'idle {idle}, idle_corrected {time_end - time_start:0.3f}')
# return the time elapsed since we saw a non-periodic reset of the idle count
return time_end - time_start