如何以编程方式防止Linux计算机进入睡眠或打开屏幕保护程序?

20
在开发一个小型跨平台C++游戏时,我遇到了以下问题:当玩家使用USB游戏手柄而没有触摸键盘或鼠标时,电脑会在他们玩的时候自动进入睡眠状态。
在Windows中,可以使用SetThreadExecutionState函数轻松解决。在OS X中,我认为可以使用UpdateSystemActivity,但还未经过测试。
但问题是,在Linux中,DE之间没有通用的API。我发现在Gnome中,您可以通过使用DBus调用Inhibit()Uninhibit()来停止自动挂起,但仅适用于Gnome。
所以,是否存在一种跨桌面环境的编程方式(或非桌面环境的方式,例如如果用户使用类似于dwmawesome wm这样的东西),可以防止Linux系统(使用Xorg且没有root访问权限)在不更改用户配置文件的情况下进入睡眠状态或打开屏幕保护程序? PS:不要认为它太复杂了,但不知道该怎么做。

3
听起来实际的问题是操作系统没有将“游戏手柄”识别为活动设备 - 应该在操作系统驱动程序中修复。 - Mats Petersson
马茨是正确的。你不应该继续修改用户设置。当你的程序崩溃或我被强制终止时会发生什么?我记得游戏会搞乱各种设置,比如桌面的亮度/颜色。即使你分叉,我也可能对机器进行硬重置。你的方法应该是中断挂起,而不是禁用/启用它。 - Etherealone
@Etherealone 是的,我不会修改用户设置,但如何防止系统休眠?我知道在 X11 中有一个 XResetScreensaver 函数,但那只是屏幕保护,不是休眠,对吗? - Chan Kha Vu
我正在解决同样的问题(http://askubuntu.com/q/655531/171608)。是否有一款应用程序可以将游戏手柄输入转换为挂起计时器重置?有人制作了一个应用程序来防止屏幕保护程序启动(https://launchpad.net/~foresto/+archive/ubuntu/toys)。但我找不到任何在Linux上使用游戏手柄时防止挂起的东西。 - guttermonk
这似乎是Caffeine应该处理的问题,因此我提交了一个错误报告:https://bugs.launchpad.net/caffeine/+bug/1530544 请访问并单击“此错误影响您”。 - guttermonk
看一下 https://launchpad.net/keep.awake 是如何以编程方式实现的。它是围绕 Gnome 设计的,但不使用 Inhibit() 或 Uninhibit()。Keep.awake 的用例范围略微更广。 - DanglingPointer
4个回答

9

从快速查看mplayer和SDL是如何实现的,有两个方法可以防止屏幕保护启动:

  • 在程序运行期间禁用它:
    • 使用XScreenSaverSuspend
    • 使用DBus,调用org.freedesktop.ScreenSaver.Inhibit
  • 定期发出信号:
    • 使用XResetScreenSaver
    • 使用DBus,调用org.freedesktop.ScreenSaver.SimulateUserActivity

6
我正在使用QTDBUS进行开发。
QDBusConnection bus = QDBusConnection::sessionBus();
if(bus.isConnected())
{
    QString services[MAX_SERVICES] = {
        "org.freedesktop.ScreenSaver",
        "org.gnome.SessionManager"
    };
    QString paths[MAX_SERVICES] = {
        "/org/freedesktop/ScreenSaver",
        "/org/gnome/SessionManager"
    };

    for(int i = 0; i < MAX_SERVICES ; i++)
    {        
        QDBusInterface screenSaverInterface(
            services[i], paths[i],services[i], bus, this);
        if (!screenSaverInterface.isValid())
            continue;       

        QDBusReply<uint> reply = screenSaverInterface.call(
            "Inhibit", "YOUR_APP_NAME", "REASON");
        if (reply.isValid())
        {
            cookieID = reply.value();
            qDebug()<<"succesful"
        } else {   
            QDBusError error =reply.error();
            qDebug()<<error.message()<<error.name();   
        }
    }
}

2
据我所知,名字中带有“xdg”的东西是跨桌面环境功能的最佳选择。似乎有一个命令行实用程序叫做xdg-screensaver。它似乎有一堆硬编码的屏幕保护程序,然后回退到xset s off/xset s default,所以当它安装好了,你可能只需要调用它,或者当它没有安装时,可以回退到复制它的部分逻辑...

2
据我所知,xset 是一种用户偏好工具,可以更改用户显示器的选项,对吗?当然它会起作用,但是,如果程序崩溃或用户强制禁用它会怎样呢?这将破坏用户的设置。 - Chan Kha Vu

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接