Last active
April 10, 2024 20:10
-
-
Save Vineg/eca223fbf478a3c806444a13e538a9fc to your computer and use it in GitHub Desktop.
Cross platform tool to prevent operating system from sleep after long inactive time (usually named Inhibitor). Requires QT DBus library for communication on Linux OS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "suspend_inhibitor.h" | |
#ifdef __APPLE__ | |
#include <IOKit/pwr_mgt/IOPMLib.h> | |
#elif defined(_WIN32) | |
#include <Windows.h> | |
#elif defined(__linux__) | |
#include <QtDBus/QtDBus> | |
#endif | |
#include <iostream> | |
namespace { | |
#ifdef __linux__ | |
class LinuxSuspendInhibitor { | |
public: | |
LinuxSuspendInhibitor() : bus_(QDBusConnection::sessionBus()) | |
{ | |
if (bus_.isConnected()) | |
available_dbus_services_ = bus_.interface()->registeredServiceNames().value(); | |
} | |
template <typename T> | |
void logReply(const QDBusReply<T> &reply) const; | |
void inhibit(bool enable, uint32_t *cookies) const; | |
private: | |
const QDBusConnection bus_; | |
QStringList available_dbus_services_; | |
}; | |
template<> | |
void LinuxSuspendInhibitor::logReply(const QDBusReply<void> &reply) const { | |
if (reply.isValid()) | |
{ | |
std::cout << "succesful" << std::endl; | |
} else { | |
QDBusError error = reply.error(); | |
std::cout << error.message().toStdString() << error.name().toStdString() << std::endl; | |
} | |
} | |
template <typename T> | |
void LinuxSuspendInhibitor::logReply(const QDBusReply<T> &reply) const | |
{ | |
if (reply.isValid()) | |
{ | |
std::cout << "succesful: " << reply << std::endl; | |
} else { | |
QDBusError error = reply.error(); | |
std::cout << error.message().toStdString() << error.name().toStdString() << std::endl; | |
} | |
} | |
void LinuxSuspendInhibitor::inhibit(bool enable, uint32_t *cookies) const | |
{ | |
if(bus_.isConnected()) { | |
QString services[MAX_SERVICES] = { | |
"org.gnome.SessionManager" | |
}; | |
QString paths[MAX_SERVICES] = { | |
"/org/gnome/SessionManager" | |
}; | |
for (int i = 0; i < MAX_SERVICES; i++) { | |
if (!available_dbus_services_.contains(services[i])) | |
continue; | |
QDBusInterface sessionManagerInterface(services[i], paths[i], services[i], bus_); | |
if (!sessionManagerInterface.isValid()) | |
continue; | |
uint32_t xid = 0; | |
uint32_t flags = 0x4; // Inhibit suspending the session or computer | |
if (enable) { | |
QDBusReply<unsigned int> reply; | |
reply = sessionManagerInterface.call("Inhibit", "Metashape", xid, "Processing", flags); | |
cookies[i] = reply.value(); | |
// logReply(reply); | |
} else { | |
QDBusReply<void> reply; | |
reply = sessionManagerInterface.call("Uninhibit", cookies[i]); | |
// logReply(reply); | |
} | |
} | |
} | |
} | |
const LinuxSuspendInhibitor linux_inhibitor_ = LinuxSuspendInhibitor(); | |
#endif | |
} | |
void SuspendInhibitor::inhibit(bool enable) | |
{ | |
// Prevent OS from suspending | |
#if defined(_WIN32) | |
SetThreadExecutionState(ES_CONTINUOUS | (enable ? ES_SYSTEM_REQUIRED : 0)); | |
#elif defined(__APPLE__) | |
if (enable) { | |
CFStringRef name = CFSTR("Metashape processing"); | |
if (IOPMAssertionCreateWithName(kIOPMAssertionTypePreventUserIdleSystemSleep, | |
kIOPMAssertionLevelOn, name, | |
&s_power_assertion_) != kIOReturnSuccess) { | |
s_power_assertion_ = kIOPMNullAssertionID; | |
} | |
} else { | |
if (s_power_assertion_ != kIOPMNullAssertionID) { | |
IOPMAssertionRelease(s_power_assertion_); | |
s_power_assertion_ = kIOPMNullAssertionID; | |
} | |
} | |
#elif defined(__linux__) | |
linux_inhibitor_.inhibit(enable, cookies_); | |
#endif | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#ifdef __APPLE__ | |
#include <IOKit/pwr_mgt/IOPMLib.h> | |
#endif | |
namespace { | |
#ifdef __linux__ | |
const int MAX_SERVICES = 1; | |
#endif | |
} | |
class SuspendInhibitor { | |
public: | |
SuspendInhibitor() { inhibit(true); } | |
~SuspendInhibitor() { inhibit(false); } | |
private: | |
void inhibit(bool enable); | |
#if defined(__APPLE__) | |
IOPMAssertionID s_power_assertion_ = kIOPMNullAssertionID; | |
#elif defined(__linux__) | |
unsigned int cookies_[MAX_SERVICES]; | |
#endif | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment