19

While developing a small cross-platform game on C++, I got stuck with following issue: when players are playing with a USB gamepad without touching a keyboard or mouse, the computer sleeps automatically while they're playing.

In Windows, it can be done easily using SetThreadExecutionState function. In OS X, I think it can be done with UpdateSystemActivity but not tested yet.

But the problem is, in Linux there's nothing like a common API between DE's. I've found that in Gnome you can stop the auto-suspending by using DBus calls Inhibit() and Uninhibit(), but it works only for Gnome.

So, is there exists a programatically cross-DE way (or non-DE way, for example if user is using something like dwm or awesome wm) to prevent a Linux system (using Xorg and without root access of course) from sleeping or turning on screensaver without changing user configuration files?

PS: Don't think that it's too complicated, but don't know how unfortunately.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Chan Kha Vu
  • 9,834
  • 6
  • 32
  • 64
  • 3
    Sounds like the actual problem is that the OS doesn't see the "gamepad" as activity - should be fixed in the OS drivers. – Mats Petersson Jul 19 '15 at 08:57
  • Mats is right. You should not go on and modify user settings. What is going to happen when your program crashes or I have to forcibly terminate it? I remember games messing up all kinds of settings like brightness/color of the desktop. Even if you fork, I might do a hard reset on the machine. Your approach should be *interrupting* the suspend, not disabling/enabling it. – Etherealone Jul 19 '15 at 14:15
  • @Etherealone yep, I'm not going to modify user settings, but how to prevent it from suspending? I know that in `X11` there is a `XResetScreensaver` function, but it's just a screen saver, not sleeping, right? – Chan Kha Vu Jul 19 '15 at 15:19
  • I'm fighting the same problem (http://askubuntu.com/q/655531/171608). Is there an app to translate gamepad inputs into suspend-timer resets? Someone made one to keep the screensaver from kicking in (https://launchpad.net/~foresto/+archive/ubuntu/toys). But I can't find anything to keep from suspending while gaming with a gamepad on Linux. – guttermonk Jan 02 '16 at 04:35
  • This sounds like something that Caffeine should handle, so I submitted a bug report: https://bugs.launchpad.net/caffeine/+bug/1530544 Please visit and click "This bug affects you." – guttermonk Jan 02 '16 at 14:18
  • Have a look at how https://launchpad.net/keep.awake does it programmatically. It is however designed around Gnome but doesn't use Inhibit() or Uninhibit(). Use-case is a bit wider for keep.awake. – DanglingPointer Apr 28 '20 at 01:13

4 Answers4

9

From a quick look at how mplayer and SDL do it, there are two things you can do to prevent the screensaver from firing up:

  • Disable it for the duration of the program:
    • Using XScreenSaverSuspend
    • Using DBus, calling org.freedesktop.ScreenSaver.Inhibit
  • Ping it periodically:
    • Using XResetScreenSaver
    • Using DBus, calling org.freedesktop.ScreenSaver.SimulateUserActivity
ninjalj
  • 42,493
  • 9
  • 106
  • 148
5

I'm using QTDBUS using that

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();   
        }
    }
}
Chan Kha Vu
  • 9,834
  • 6
  • 32
  • 64
Virupaksha
  • 51
  • 1
  • 4
2

As far as I can tell, things with xdg in the name are the way to go for cross-desktop-environment functionality. There appears to be a commandline utility called xdg-screensaver. It seems to have a bunch of screensavers hardwired and then fall back to xset s off/xset s default, so you might want to just call it when it's installed, or fall back to copying part of its logic when it's not...

ben
  • 1,994
  • 12
  • 20
  • 2
    As I understand, xset is user preference utility that change options of user's display, right? Of course it will work, but, what if the program crashes or the user forcibly disable it? It will mess up the user's settings. – Chan Kha Vu Jul 19 '15 at 15:21
0

I've put together code to disable idle sleep for Ubuntu, Mac OS and Windows:

https://gist.github.com/Vineg/eca223fbf478a3c806444a13e538a9fc

It is based on Virupaksha answer.

George Vinokhodov
  • 327
  • 1
  • 4
  • 10