Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Prevent computer from sleeping using DBus



  • I need a way to prevent the computer from sleeping, turn it on/off at runtime.

    I believe SetThreadExecutionState does that for windows, now I am looking for a way to do that in Linux.

    I posted this question here and I've been told that I can use QDBus module for that.

    I read the doc but couldn't figure out how to do that, even with this example that says it does what I am trying to achieve.


  • Lifetime Qt Champion

    Hi
    But did you try the Qt code shown ?
    Didn't that work?



  • @mrjj didn't test because couldn't find what what parameters to put here:

    QDBusReply<uint> reply = screenSaverInterface.call(
                "Inhibit", "YOUR_APP_NAME", "REASON");
    

    What is the REASON?

    Also if that works I still don't know how to disable it, letting the computer sleep normally.


  • Lifetime Qt Champion

    @hbatalha
    its just some text explaining why this command was run.
    Maybe it can be seen in some log or something.
    I think you can write anything but if you have a good reason thats not super long, it would be perfect.

    For the "Inhibit"
    You can read here how it works etc.
    https://www.freedesktop.org/wiki/Software/systemd/inhibit/

    Im not sure what the opposite of "Inhibit" is. It says to release the lock but
    not sure what text command it would be.
    But digging around the protocol should reveal that.



  • @mrjj I will test it and get back to you



  • @mrjj I tested the code it seems to be working fine, I modified the code so I can turn it on/off at runtime:

    void MainWindow::toggleSleepPevention()
    {
    #ifdef Q_OS_LINUX
        const int MAX_SERVICES = 2;
    
        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"
            };
    
    
            static uint cookies[2];
    
            for(int i = 0; i < MAX_SERVICES ; i++)
            {
                QDBusInterface screenSaverInterface( services[i], paths[i],services[i], bus);
    
                if (!screenSaverInterface.isValid())
                    continue;
    
                QDBusReply<uint> reply;
    
                if(preferences.preventSleep == true)
                {
                    reply = screenSaverInterface.call("Inhibit", "nzuri-video Downloader", "REASON");
                }
                else
                {
                    reply  = screenSaverInterface.call("UnInhibit", cookies[i]);
                }
    
                if (reply.isValid())
                {
                    cookies[i] = reply.value();
    
                    qDebug()<<"succesful: " << reply;
                }
                else
                {
                    QDBusError error =reply.error();
                    qDebug()<<error.message()<<error.name();
                }
            }
        }
    #endif
    }
    

    In this code: reply = screenSaverInterface.call("UnInhibit", cookies[i]); the reply isn't valid so it throws the following error:

    "Unexpected reply signature: got \"<empty signature>\", expected \"u\" (uint)" "org.freedesktop.DBus.Error.InvalidSignature"
    "No such method “UnInhibit”" "org.freedesktop.DBus.Error.UnknownMethod"
    

    But it worked despite this error. I might have to do some more tests to confirm though. And the tests are slow because I have to always wait 5 minutes to check if the computer is sleeping or not.

    A question: Could this code be cross-platform or freedesktop.org is only for linux?


  • Lifetime Qt Champion

    Hi
    It seems "UnInhibit" is unknown so not sure it why seems to work.

    • A question: Could this code be cross-platform or freedesktop.org is only for linux?

    I have only seen it implemented on linux. In theory, any Os could
    support it.

    https://www.freedesktop.org/wiki/Software/dbus/
    (Windows port)

    It seems the d-bus part is ported to windows but
    its unclear what it can do on this platform.



  • @mrjj

    It seems "UnInhibit" is unknown so not sure it why seems to work.

    According to this doc it exists, not sure why I am getting the error saying it doesn't. If you pass it the wrong arguments the compiler will complain that it is receiving the wrong arguments at the same time saying it doesn't exist. Confusing.

    It seems the d-bus part is ported to windows but
    its unclear what it can do on this platform.

    Ok, I will be better off using SetThreadExecutionState I think.


Log in to reply