From f3f9cfe44ed49d5bf3de0e318fa9c8ec48645ca4 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Thu, 20 Jul 2023 13:19:53 +0800 Subject: [PATCH 1/4] 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; }; From b5fbfdf1069dc8d83366627b1788a9d20e807517 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Thu, 20 Jul 2023 15:39:18 +0800 Subject: [PATCH 2/4] Use correct type https://doc.qt.io/qt-6/qdbustypesystem.html https://dbus.freedesktop.org/doc/dbus-specification.html#id-1.3.8 --- src/gui/powermanagement/powermanagement_x11.cpp | 2 +- src/gui/powermanagement/powermanagement_x11.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/powermanagement/powermanagement_x11.cpp b/src/gui/powermanagement/powermanagement_x11.cpp index 7ddf1064e..585a84232 100644 --- a/src/gui/powermanagement/powermanagement_x11.cpp +++ b/src/gui/powermanagement/powermanagement_x11.cpp @@ -176,7 +176,7 @@ void PowerManagementInhibitor::onAsyncReply(QDBusPendingCallWatcher *call) } else { - const QDBusPendingReply reply = *call; + const QDBusPendingReply reply = *call; if (reply.isError()) { diff --git a/src/gui/powermanagement/powermanagement_x11.h b/src/gui/powermanagement/powermanagement_x11.h index 3810efcb3..4da9ece22 100644 --- a/src/gui/powermanagement/powermanagement_x11.h +++ b/src/gui/powermanagement/powermanagement_x11.h @@ -71,6 +71,6 @@ private: enum State m_state = Error; enum State m_intendedState = Idle; - quint32 m_cookie = 0; + uint m_cookie = 0; QDBusUnixFileDescriptor m_fd; }; From dbb1b1e9bb97883b9f8edbc7a4d76c1d8e72fe7b Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Thu, 20 Jul 2023 15:51:36 +0800 Subject: [PATCH 3/4] Use default timeout --- src/gui/powermanagement/powermanagement_x11.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/powermanagement/powermanagement_x11.cpp b/src/gui/powermanagement/powermanagement_x11.cpp index 585a84232..49d586762 100644 --- a/src/gui/powermanagement/powermanagement_x11.cpp +++ b/src/gui/powermanagement/powermanagement_x11.cpp @@ -65,7 +65,6 @@ PowerManagementInhibitor::PowerManagementInhibitor(QObject *parent) 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())); } From 76b5ca6b8b22f93ff700232b0f72d5dbef9ecbb5 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Thu, 20 Jul 2023 17:32:23 +0800 Subject: [PATCH 4/4] Remove debugging messages As requested in https://github.com/qbittorrent/qBittorrent/pull/19344#discussion_r1269156895 --- src/gui/powermanagement/powermanagement_x11.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/gui/powermanagement/powermanagement_x11.cpp b/src/gui/powermanagement/powermanagement_x11.cpp index 49d586762..6ade281fa 100644 --- a/src/gui/powermanagement/powermanagement_x11.cpp +++ b/src/gui/powermanagement/powermanagement_x11.cpp @@ -81,7 +81,6 @@ void PowerManagementInhibitor::requestIdle() return; m_state = RequestIdle; - qDebug("D-Bus: PowerManagementInhibitor: Requesting idle"); if (m_manager == ManagerType::Systemd) { @@ -105,7 +104,6 @@ void PowerManagementInhibitor::requestBusy() return; m_state = RequestBusy; - qDebug("D-Bus: PowerManagementInhibitor: Requesting busy"); const QString message = u"Active torrents are currently present"_s; @@ -138,7 +136,6 @@ void PowerManagementInhibitor::onAsyncReply(QDBusPendingCallWatcher *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"RequestIdle"_s , reply.error().message()), Log::WARNING); m_state = Error; @@ -146,7 +143,6 @@ void PowerManagementInhibitor::onAsyncReply(QDBusPendingCallWatcher *call) else { m_state = Idle; - qDebug("D-Bus: PowerManagementInhibitor: Request successful"); if (m_intendedState == Busy) requestBusy(); } @@ -159,7 +155,6 @@ void PowerManagementInhibitor::onAsyncReply(QDBusPendingCallWatcher *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; @@ -168,7 +163,6 @@ void PowerManagementInhibitor::onAsyncReply(QDBusPendingCallWatcher *call) { m_state = Busy; m_fd = reply.value(); - qDebug("D-Bus: PowerManagementInhibitor: Request successful, cookie is %d", m_cookie); if (m_intendedState == Idle) requestIdle(); } @@ -179,7 +173,6 @@ void PowerManagementInhibitor::onAsyncReply(QDBusPendingCallWatcher *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; @@ -188,7 +181,6 @@ void PowerManagementInhibitor::onAsyncReply(QDBusPendingCallWatcher *call) { m_state = Busy; m_cookie = reply.value(); - qDebug("D-Bus: PowerManagementInhibitor: Request successful, cookie is %d", m_cookie); if (m_intendedState == Idle) requestIdle(); } @@ -199,7 +191,6 @@ void PowerManagementInhibitor::onAsyncReply(QDBusPendingCallWatcher *call) const QDBusPendingReply reply = *call; const QDBusError error = reply.error(); - qDebug("D-Bus: Unexpected reply in state %d", m_state); if (error.isValid()) { LogMsg(tr("Power management unexpected error. State: %1. Error: %2").arg(QString::number(m_state)