在Linux中禁用屏幕保护程序的跨DE方法有哪些?我在这里找到了something,但它只适用于gnome-screensaver。我想知道是否有任何方法可以模拟击键或某些X.Org API来禁用屏幕保护程序激活。
答案 0 :(得分:4)
我前一段时间一直在研究这个问题,最后最终使用xdg-screensaver
,我通过subprocess
调用。
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)
这并不理想,但显然没有其他解决方案不会涉及到特定于DE的内容,如dbus
或gnome-screensaver-command
。
我真的不喜欢xwininfo
的号召,并希望有一个更清洁的方式,但到目前为止找不到更好的东西。 xwininfo
方法的另一个问题是它使用根窗口的id而不是app窗口。使用应用程序窗口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()
答案 1 :(得分:2)
我知道这个问题很老,但有一个更现代的答案:现在大多数关于linux的DE使用dbus进行通信,你可以使用它:
shell中的,使用kde工具:
qdbus org.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.Inhibit "myapps" "because I want it"
这个dbus调用将返回一个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)
答案 2 :(得分:0)
TLDR;没有任何跨DE方法来禁止使用纯Python的屏幕保护程序。然而,问题还提到了使用Linux(可能来自shell)。需要明确的是,在Linux中没有任何特别好的跨DE方法,但至少有潜力。您可能想要使用hackish xdg-screensaver
shell脚本。
这是我花了一些时间的话题。我对那里的任何解决方案都不满意,所以在玩了一些自制工具之后,我最终修改了咖啡因项目以满足我的需求,从那时起就开心地使用它。我将总结一下我在这个过程中学到的一些东西。
如果您不熟悉它,我建议您查看咖啡因(Launchpad PPA @ https://launchpad.net/~caffeine-developers/+archive/ubuntu/ppa)。
咖啡因项目主要是包含以下脚本:caffeine-screensaver
caffeine
caffeine-indicator
caffeinate
caffeine
和caffeine-indicator
是用Python 3编写的,而caffeine-screensaver
是用shell脚本编写的重新命名的xdg-screensaver
。
ccpizza 的上半部分答案很棒,因为它是跨DE的,与咖啡因的实现非常相似。我对xdg-screensaver zombie进程没有任何问题,但我确信如果我更好地了解用例或它发生的条件,它可以得到纠正。只是运行xdg-screensaver suspend ROOT_WINDOW_ID
的一个FYI将为跟踪过程提供背景并使其无限期运行(直到恢复)。
如果您对实施真正的跨DE解决方案感兴趣,那么我强烈建议您检查前面提到的xdg-screensaver
/ caffeine-screensaver
。 lightsOn的许多叉子也已成熟。
xdg-screensaver
检测桌面环境(KDE,Gnome,XFCE,LXDE,xscreensaver或gnome-screensaver)并采取相应措施。对于xdg-screensaver suspend
命令,它运行xset -dpms
以禁用DPMS,特定于DE的命令,然后监视提供的窗口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。使用桌面的根窗口ID xdg-screensaver suspend
将无限期地禁用桌面的屏幕保护程序。使用特定窗口的ID将在窗口期间禁用桌面的屏幕保护程序。
要确定有效窗口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选项。 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().timeout