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.
-
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.
-
@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 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]);
thereply
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?
-
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. -
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.