在Linux中禁用屏幕保护程序的更好的跨DE方式是什么?我在这里找到了something,但它只用于gnome-screensaver。我想知道是否有任何方法可以模拟击键或一些X.Org应用程序接口来禁用屏幕保护程序激活。
发布于 2012-07-21 23:39:29
我在一段时间之前一直在研究这个问题,最终通过subprocess使用了xdg-screensaver。
import subprocess
def suspend_screensaver():
window_id = subprocess.Popen('xwininfo -root | grep xwininfo | cut -d" " -f4', stdout=subprocess.PIPE, shell=True).stdout.read().strip()
#run xdg-screensaver on root window
subprocess.call(['xdg-screensaver', 'suspend', window_id])
def resume_screensaver(window_id):
subprocess.Popen('xdg-screensaver resume ' + window_id, shell=True)这并不理想,但显然没有其他解决方案不涉及dbus或gnome-screensaver-command等特定于DE的东西。
我真的不喜欢对xwininfo的调用,希望有一种更干净的方法,但到目前为止还找不到更好的方法。xwininfo方法的另一个问题是它使用根窗口的id,而不是应用程序窗口。使用应用程序窗口id而不是根窗口将消除对resume_screensaver方法的需要,因为一旦窗口被销毁,它将立即恢复。
如果你想模拟击键,这里有一个我已经使用了一段时间的简单的bash脚本。它确实需要xdotool,它必须单独安装。
#!/bin/bash
while :
do
sleep 200
nice -n 1 xdotool key shift
echo .
done更新
在使用上面的python解决方案一年多后,我发现它偶尔会创建僵尸进程和/或太多的xdg-screensaver实例,所以在深入研究后,我发现了一个更简单的替代方案,它是Gnome,但即使在非Gnome DE (XFCE)中也可以工作,因为许多基于GTK的应用程序都需要核心Gnome库,即使你没有Gnome桌面。
import subprocess
def suspend_screensaver():
'suspend linux screensaver'
proc = subprocess.Popen('gsettings set org.gnome.desktop.screensaver idle-activation-enabled false', shell=True)
proc.wait()
def resume_screensaver():
'resume linux screensaver'
proc = subprocess.Popen('gsettings set org.gnome.desktop.screensaver idle-activation-enabled true', shell=True)
proc.wait()发布于 2017-06-22 14:34:02
我知道这个问题很古老,但有一个更现代的答案:现在linux上的大多数DE都使用dbus进行通信,您可以使用以下内容:
shell中的,使用kde工具:
qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.Inhibit "myapps" "because I want it"此dbus调用将返回一个cookie (一个数字),该cookie将用于解除对screesaver的限制:
qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.UnInhibit $COOKIE在python中,它将类似于
import dbus
bus = dbus.SessionBus()
saver = bus.get_object('org.freedesktop.ScreenSaver', '/ScreenSaver')
saver_interface = dbus.Interface(saver, dbus_interface='org.freedesktop.ScreenSaver')
# now we can inhibit the screensaver
cookie=saver_interface.Inhibit("myapps", "because I want it")
# we can also restore it
saver_interface.UnInhibit(cookie)发布于 2015-04-27 14:48:41
讨论
TLDR;没有任何跨DE的方法来抑制纯Python的屏幕保护程序。然而,这个问题也问到了在Linux中这样做的问题(可能是从shell中)。需要明确的是,在Linux中没有任何特别好的跨DE方法,但至少有潜力。您可能希望使用黑客的xdg-screensaver shell脚本。
这是我花了一些时间来讨论的一个话题。我对任何解决方案都不满意,所以在尝试了一些自制工具后,我最终修改了咖啡因项目以满足我的需求,并从那以后一直快乐地使用它。我将总结我在这个过程中学到的一些东西。
如果你不熟悉咖啡因,我建议你去看看咖啡因(Launchpad PPA @ https://launchpad.net/~caffeine-developers/+archive/ubuntu/ppa)。
caffeine项目主要由以下脚本组成:caffeine-screensaver caffeine caffeine-indicator caffeinate
caffeine和caffeine-indicator是用Python3编写的,而caffeine-screensaver是用shell脚本编写的重新命名的xdg-screensaver。
ccpizza的前半部分的答案很棒,因为它是跨DE的,而且非常类似于caffeine的实现。我还没有遇到过xdg屏幕保护程序僵尸进程的任何问题,但我相信,如果我更好地了解它的用例或发生它的条件,这个问题是可以解决的。只需要一个运行xdg-screensaver suspend ROOT_WINDOW_ID的FYI,它将运行一个跟踪进程,并让它无限期地运行(直到它恢复)。
如果您对实现真正的跨DE解决方案感兴趣,那么我强烈建议您研究一下前面提到的xdg-screensaver/caffeine-screensaver。lightsOn的许多分支也已经成熟。
xdg-screensaver检测桌面环境(KDE、Gnome、XFCE、LXDE、screensaver或gnome-screensaver)并采取相应的行动。对于xdg-screensaver suspend命令,它运行xset -dpms来禁用特定于DPMS的命令,然后观察所提供的窗口ID的持续时间。如果该窗口消失,则运行resume命令并退出xdg-screensaver。xdg-screensaver resume命令由xset +dpms (仅当最初启用了DPMS时)和特定于DE的命令组成。
请注意,如果xprop可用,xdg-screensaver将只跟踪提供的窗口ID (它是x11-utils的一部分,所以它应该是)。为了跟踪窗口,它以xprop -id WINDOW_ID -spy为背景来监视窗口的变化。它将上述进程的PID和窗口ID存储在一个锁定文件中,以便在挂起和恢复时引用。DPMS的原始状态在单独的锁定文件中引用。锁文件应该确保没有重复的进程。
这个脚本一团糟,所以我同情那些不幸使用它的人,但我没有遇到任何问题。你可能不想重新发明轮子,所以如果你正在为公众消费创建一些东西,那么我建议你只需要选择它。如果您正在创建供个人使用的东西,那么只需深入挖掘并使用特定于您的DE的命令即可。
ccpizza建议使用subprocess.Popen('xwininfo -root | grep xwininfo | cut -d" " -f4', stdout=subprocess.PIPE, shell=True).stdout.read().strip()来获取桌面的根窗口ID。在xdg-screensaver suspend中使用桌面的根窗口ID将无限期禁用桌面的屏幕保护程序。使用特定窗口的ID将在窗口期间禁用桌面的屏幕保护程序。
Shell脚本
要确定活动窗口ID,可以运行以下命令:
xprop -root _NET_ACTIVE_WINDOW | awk -F '[ ,]' '{print $5}'要确定根窗口ID,可以运行以下命令:
xwininfo -root | awk '/^xwininfo: Window id: / {print $4}'要确定屏幕保护程序超时,可以运行以下命令:
xset q | awk '/^ timeout: / {print $2}'注意:如果关闭屏幕保护程序,则结果为0
要确定是启用还是禁用DPMS,可以运行以下命令:
xset q | awk '/^ DPMS is / {print tolower($3)}'Python脚本
还有一些纯Python选项。Xlib模块和ewmh (它是Xlib的包装器)在这方面很好用。
使用ewmh确定活动窗口ID
active_id = hex(ewmh.EWMH().getActiveWindow().id)使用ewmh确定根窗口ID
root_id = hex(ewmh.EWMH().root.id)使用Xlib确定活动窗口ID
from Xlib.display import Display
from Xlib.X import AnyPropertyType
active_id = hex(Display().screen().root.get_full_property(Display().get_atom('_NET_ACTIVE_WINDOW'), AnyPropertyType).value[0])使用Xlib确定根窗口ID
from Xlib.display import Display
root_id = hex(Display().screen().root.id)使用Xlib确定屏幕保护程序超时
from Xlib.display import Display
timeout = Display().get_screen_saver().timeouthttps://stackoverflow.com/questions/10885337
复制相似问题