有没有一种可靠的方法来抑制linux中的屏保?

时间:2009-01-20 04:37:14

标签: screensaver

我正在寻找一种体面的,非蹩脚的方式来禁止xscreensaver,kscreensaver或gnome-screensaver,哪些可能正在运行,最好是以屏幕保护程序无关的方式,它绝对必须执行 fast < / em>的

我已阅读xscreensaver常见问题解答(http://www.jwz.org/xscreensaver/faq.html)。

我有一个基于gtk的游戏程序,在混合多个音频通道的同时发出30帧/秒的速度,并且由于它是由操纵杆控制的,有时候“屏幕保护程序”会启动。我把“the”放在引号中,因为至少有三种不同的流行屏保,xscreensaver,gnome-screensaver和kscreensaver,每种都有自己独特且笨重的方法,应用程序可能通过这些方法禁止它们。

是否有人封装了代码以禁止所有这些代码进入 fast 代码块?哦,它必须与GPL兼容。

目前,如果检测到任何屏幕保护程序且操纵杆正在使用中,我的代码只是抱怨不合作的屏幕保护程序开发人员,除了建议用户手动禁用屏幕保护程序之外,实际上并没有尝试做任何其他操作我能想到的事情是如此令人难以置信的丑陋,我只是拒绝这样做。

只是想知道是否有其他人遇到过这个问题,以及他们做了什么,如果他们做了什么,如果它看起来像我看起来那样丑陋,或者如果那里有一些优雅的解决方案......似乎可能以某种方式合成X事件以欺骗屏幕保护程序,以为某些活动可能以通用的方式完成这个技巧,但我真的不确定如何做到这一点(并希望你不需要成为root用户)这样做。)

有什么想法吗?

谢谢,

- 史蒂夫


嗯,不幸的是,至少在Fedora核心8上,这似乎不起作用。

xdg-screensaver脚本在那里,似乎打算工作,它实际上不起作用。

一旦你执行“xdg-screensaver suspend window-id”,其中窗口id是从程序中获取的

xwindow_id = GDK_WINDOW_XWINDOW (GTK_WIDGET (widget)->window);

或者是否通过xprop获取窗口ID,并且手动运行xdg-screensaver,将创建两个进程:

[scameron@zuul wordwarvi]$ ps -efa | grep xdg
scameron  4218     1  0 20:12 pts/2    00:00:00 /bin/sh /usr/bin/xdg-screensaver suspend 0x3a00004
scameron  4223     1  0 20:12 pts/2    00:00:00 /bin/sh /usr/bin/xdg-screensaver suspend 0x3a00004
scameron  4313  3151  0 20:15 pts/1    00:00:00 grep xdg
[scameron@zuul wordwarvi]$ 

他们永远不会死,即使他们应该等待死亡的程序,屏幕保护程序永远不会重新启用。

[scameron@zuul wordwarvi]$ xdg-screensaver status
disabled
[scameron@zuul wordwarvi]$ ls -ltr /tmp | grep xdg
-rw------- 1 scameron scameron    15 2009-01-20 20:12 xdg-screensaver-scameron--0.0
[scameron@zuul wordwarvi]$ 

运行xdg-screensaver resume window-id不会恢复屏幕保护程序。

要重新启用屏幕保护程序,我必须手动终止它们,并在/ tmp中手动删除它留下的文件:

[scameron@zuul wordwarvi]$ kill 4218 4223
[scameron@zuul wordwarvi]$ rm /tmp/xdg-screensaver-scameron--0.0 
[scameron@zuul wordwarvi]$ xdg-screensaver status
enabled
[scameron@zuul wordwarvi]$ 

所以,善意,但似乎并没有真正发挥作用。


不,当然不期望每一帧运行它,但不希望它在运行时导致打嗝,就是这样。我想到了合成X事件的想法,我想象通常会让屏幕保护程序认为有活动。

看看xdg-screensaver(它似乎是一个shell脚本,最终只是为我的进程“等待” - 很酷)它似乎可以做到我想要的。我知道我不可能是唯一或第一个面对这个问题的人。

谢谢!

- 史蒂夫

6 个答案:

答案 0 :(得分:8)

不,但是......

没有很好的干净方法来做到这一点。在我看来,应该有一个由X服务器管理的机制,屏幕保护程序和感兴趣的应用程序都可以自愿地使用它来协商在一个或多个程序的运行时期间对任何屏幕保护程序的抑制。但据我所知,还没有这样的机制。 GNOME和KDE看起来正在实现这个问题的DBUS方法,但在我看来,即使它变得普遍(它还不够普及,在第三方代码中依赖它),这不是正确的方法。

但是,xdg-screensaver是一个FreeDesktop标准化shell脚本,您可以将其作为子进程运行来控制屏幕保护程序。它控制着大多数流行的屏幕保护程序,操作系统供应商将负责更新它/维护它以适应更新的屏幕保护程序或未来更好的方法。与许多其他kludges不同,如果您的应用程序通过某些忘记调用重新启用代码的路径崩溃或退出,它将自动重新启用屏幕保护程序。有关如何使用它的详细信息,请参见手册页。

作为一个GTK +用户,你可能会创建运行shell脚本的子流程(如果你还没有想要找到关于使用fork + exec的教程),那么最简单的方法是获取应用程序主窗口的XWindow ID以提供给xdg-screensaver。

你要求代码应该“快”。这让我想知道你是否期望每一帧运行它 - 不要。 xdg-screensaver解决方案允许您显式禁用或重新显示屏幕保护程序,而不是尝试每帧或类似地禁止它。

答案 1 :(得分:2)

电影播放器​​通常会禁用屏幕保护程序。您可以查看mplayer - 代码,看看他们是如何做到的。

对于常规X,他们使用支持的XScreenSaverSuspend

答案 2 :(得分:2)

它不是完全与桌面无关的解决方案,但如果安装了核心Gnome库(许多基于GTK的应用程序需要它们),它也可以在其他桌面环境中运行:

禁用屏幕保护程序:

gsettings set org.gnome.desktop.screensaver idle-activation-enabled false

(重新)启用屏幕保护程序:

gsettings set org.gnome.desktop.screensaver idle-activation-enabled true

答案 3 :(得分:2)

试试这个:xdg-screensaver suspend [window id]

(见:http://portland.freedesktop.org/xdg-utils-1.0/xdg-screensaver.html

Bash脚本解决方案:

activ_win_id=`DISPLAY=:0.${display} xprop -root _NET_ACTIVE_WINDOW`
activ_win_id=${activ_win_id:40:9}
xdg-screensaver suspend $activ_win_id

适用于gnome-screensaver。

而且更复杂的DBus&#34;抑制&#34;方法:https://people.gnome.org/~mccann/gnome-screensaver/docs/gnome-screensaver.html#gs-method-Inhibit

dbus-send --session \
      --dest=org.gnome.ScreenSaver \
      --type=method_call \
      --print-reply \
      --reply-timeout=20000 \
      /org/gnome/ScreenSaver \
      org.gnome.ScreenSaver.Inhibit \
      [application name e.g. ""] \
      [reason e.g."playing a game"] \
      [non-zero-random-integer e.g. 123]

答案 4 :(得分:1)

当前的方式(在Gnome 3.22下,可能还有其他如KDE)似乎就是这样,它将一个非禁止cookie作为uint32返回:

dbus-send --session \
      --dest=org.freedesktop.ScreenSaver \
      --type=method_call \
      --print-reply \
      --reply-timeout=20000 \
      /org/freedesktop/ScreenSaver \
      org.freedesktop.ScreenSaver.Inhibit \
      string:program string:reason

然后,禁用抑制:

dbus-send --session \
      --dest=org.freedesktop.ScreenSaver \
      --type=method_call \
      --print-reply \
      --reply-timeout=20000 \
      /org/freedesktop/ScreenSaver \
      org.freedesktop.ScreenSaver.UnInhibit \
      uint32:<inhibit-cookie>

这是一个small script,它禁用给定程序的屏幕保护程序,然后在退出时恢复它。

D-Feet特别有助于反省不断变化的D-Bus方法名称)

答案 5 :(得分:0)

这个“肮脏的解决方案”在 Debian 10 + LXDE 上对我有用:

[ "$(cat ~/.xsessionrc | grep 'xset -dpms')" ] || echo 'xset -dpms' >> ~/.xsessionrc  # disables DPMS (Energy Star) features
sed -i '/^timeout:/c timeout:\t3:00:00' ~/.xscreensaver  # 3 hours should be enough to see a film without interruptions
# DOESN'T WORK:  xset s off   # turns the screen saver functions off