From f3f9cfe44ed49d5bf3de0e318fa9c8ec48645ca4 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Thu, 20 Jul 2023 13:19:53 +0800 Subject: [PATCH] Add support for systemd power management --- .../powermanagement/powermanagement_x11.cpp | 89 ++++++++++++++----- src/gui/powermanagement/powermanagement_x11.h | 5 +- 2 files changed, 73 insertions(+), 21 deletions(-) diff --git a/src/gui/powermanagement/powermanagement_x11.cpp b/src/gui/powermanagement/powermanagement_x11.cpp index c555dd32d..7ddf1064e 100644 --- a/src/gui/powermanagement/powermanagement_x11.cpp +++ b/src/gui/powermanagement/powermanagement_x11.cpp @@ -45,21 +45,28 @@ PowerManagementInhibitor::PowerManagementInhibitor(QObject *parent) { delete m_busInterface; - m_busInterface = new QDBusInterface(u"org.freedesktop.PowerManagement"_s, u"/org/freedesktop/PowerManagement/Inhibit"_s - , u"org.freedesktop.PowerManagement.Inhibit"_s, QDBusConnection::sessionBus(), this); - m_manager = ManagerType::Freedesktop; + m_busInterface = new QDBusInterface(u"org.freedesktop.login1"_s, u"/org/freedesktop/login1"_s + , u"org.freedesktop.login1.Manager"_s, QDBusConnection::systemBus(), this); + m_manager = ManagerType::Systemd; if (!m_busInterface->isValid()) { delete m_busInterface; - m_busInterface = nullptr; - m_state = Error; + m_busInterface = new QDBusInterface(u"org.freedesktop.PowerManagement"_s, u"/org/freedesktop/PowerManagement/Inhibit"_s + , u"org.freedesktop.PowerManagement.Inhibit"_s, QDBusConnection::sessionBus(), this); + m_manager = ManagerType::Freedesktop; + if (!m_busInterface->isValid()) + { + delete m_busInterface; + m_busInterface = nullptr; + } } } if (m_busInterface) { m_busInterface->setTimeout(1000); + m_state = Idle; LogMsg(tr("Power management found suitable D-Bus interface. Interface: %1").arg(m_busInterface->interface())); } else @@ -77,6 +84,13 @@ void PowerManagementInhibitor::requestIdle() m_state = RequestIdle; qDebug("D-Bus: PowerManagementInhibitor: Requesting idle"); + if (m_manager == ManagerType::Systemd) + { + QDBusUnixFileDescriptor dummy; + m_fd.swap(dummy); + return; + } + const QString method = (m_manager == ManagerType::Gnome) ? u"Uninhibit"_s : u"UnInhibit"_s; @@ -95,9 +109,21 @@ void PowerManagementInhibitor::requestBusy() qDebug("D-Bus: PowerManagementInhibitor: Requesting busy"); const QString message = u"Active torrents are currently present"_s; - const auto args = (m_manager == ManagerType::Gnome) - ? QList {u"qBittorrent"_s, 0u, message, 4u} - : QList {u"qBittorrent"_s, message}; + + QList args; + switch (m_manager) + { + case ManagerType::Freedesktop: + args = {u"qBittorrent"_s, message}; + break; + case ManagerType::Gnome: + args = {u"qBittorrent"_s, 0u, message, 4u}; + break; + case ManagerType::Systemd: + args = {u"sleep"_s, u"qBittorrent"_s, message, u"block"_s}; + break; + } + const QDBusPendingCall pcall = m_busInterface->asyncCallWithArgumentList(u"Inhibit"_s, args); const auto *watcher = new QDBusPendingCallWatcher(pcall, this); connect(watcher, &QDBusPendingCallWatcher::finished, this, &PowerManagementInhibitor::onAsyncReply); @@ -128,22 +154,45 @@ void PowerManagementInhibitor::onAsyncReply(QDBusPendingCallWatcher *call) } else if (m_state == RequestBusy) { - const QDBusPendingReply reply = *call; - - if (reply.isError()) + if (m_manager == ManagerType::Systemd) { - qDebug("D-Bus: Reply: Error: %s", qUtf8Printable(reply.error().message())); - LogMsg(tr("Power management error. Action: %1. Error: %2").arg(u"RequestBusy"_s - , reply.error().message()), Log::WARNING); - m_state = Error; + const QDBusPendingReply reply = *call; + + if (reply.isError()) + { + qDebug("D-Bus: Reply: Error: %s", qUtf8Printable(reply.error().message())); + LogMsg(tr("Power management error. Action: %1. Error: %2").arg(u"RequestBusy"_s + , reply.error().message()), Log::WARNING); + m_state = Error; + } + else + { + m_state = Busy; + m_fd = reply.value(); + qDebug("D-Bus: PowerManagementInhibitor: Request successful, cookie is %d", m_cookie); + if (m_intendedState == Idle) + requestIdle(); + } } else { - m_state = Busy; - m_cookie = reply.value(); - qDebug("D-Bus: PowerManagementInhibitor: Request successful, cookie is %d", m_cookie); - if (m_intendedState == Idle) - requestIdle(); + const QDBusPendingReply reply = *call; + + if (reply.isError()) + { + qDebug("D-Bus: Reply: Error: %s", qUtf8Printable(reply.error().message())); + LogMsg(tr("Power management error. Action: %1. Error: %2").arg(u"RequestBusy"_s + , reply.error().message()), Log::WARNING); + m_state = Error; + } + else + { + m_state = Busy; + m_cookie = reply.value(); + qDebug("D-Bus: PowerManagementInhibitor: Request successful, cookie is %d", m_cookie); + if (m_intendedState == Idle) + requestIdle(); + } } } else diff --git a/src/gui/powermanagement/powermanagement_x11.h b/src/gui/powermanagement/powermanagement_x11.h index 02c93d089..3810efcb3 100644 --- a/src/gui/powermanagement/powermanagement_x11.h +++ b/src/gui/powermanagement/powermanagement_x11.h @@ -28,6 +28,7 @@ #pragma once +#include #include class QDBusInterface; @@ -61,7 +62,8 @@ private: enum class ManagerType { Freedesktop, // https://www.freedesktop.org/wiki/Specifications/power-management-spec/ - Gnome // https://github.com/GNOME/gnome-settings-daemon/blob/master/gnome-settings-daemon/org.gnome.SessionManager.xml + Gnome, // https://github.com/GNOME/gnome-settings-daemon/blob/master/gnome-settings-daemon/org.gnome.SessionManager.xml + Systemd // https://www.freedesktop.org/software/systemd/man/org.freedesktop.login1.html }; QDBusInterface *m_busInterface = nullptr; @@ -70,4 +72,5 @@ private: enum State m_state = Error; enum State m_intendedState = Idle; quint32 m_cookie = 0; + QDBusUnixFileDescriptor m_fd; };