Support old PowerManagement.Inhibit interface as fallback.

Encapsulate the code dealing with requesting an inhibitor lock in a
dedicated Inhibitor class. The lock is acquired in the constructor and
released in the destructor.

The constructor first tries to acquire the lock using the modern
"org.freedesktop.login1.Manager" interface, then tries the previous
"org.freedesktop.PowerManagement.Inhibit" interface as a fallback.
master
Damien Goutte-Gattat 7 months ago
parent 144b1bb14a
commit 94d5e050ab
Signed by: damien
GPG Key ID: 6F7F0F91D138FC7B

@ -4,6 +4,6 @@ dist_doc_DATA = AUTHORS COPYING README.md
bin_PROGRAMS = pm-inhibit
pm_inhibit_SOURCES = pm-inhibit.cpp
pm_inhibit_SOURCES = pm-inhibit.cpp inhibitor.cpp inhibitor.h
AM_CXXFLAGS = -fPIC

@ -0,0 +1,77 @@
/*
* pm-inhibit - Power Management Inhibition Tool
* Copyright (C) 2022 Damien Goutte-Gattat
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "inhibitor.h"
#include <QDBusConnection>
#include <QDBusInterface>
#include <QDBusReply>
#define LOGIN1_NAME "org.freedesktop.login1"
#define LOGIN1_PATH "/org/freekdesktop/login1"
#define INHIBIT_NAME "org.freedesktop.PowerManagement.Inhibit"
#define INHIBIT_PATH "/org/freedesktop/PowerManagement/Inhibit"
Inhibitor::Inhibitor(const QString& program, const QString& reason)
{
m_cookie = nullptr;
m_fallbackCookie = 0;
/* First try the modern login1 interface. */
QDBusInterface manager(LOGIN1_NAME, LOGIN1_PATH,
LOGIN1_NAME ".Manager", QDBusConnection::systemBus());
QDBusReply<QDBusUnixFileDescriptor> reply = manager.call("Inhibit",
"idle", program, reason, "block");
if ( reply.isValid() ) {
/* We need a copy of the file descriptor to prevent the lock from
* being automatically released at the end of the current scope. */
m_cookie = new QDBusUnixFileDescriptor(reply.value());
}
else {
/* Fallback to the old PowerManagement interface. */
QDBusInterface inhibit(INHIBIT_NAME, INHIBIT_PATH, INHIBIT_NAME,
QDBusConnection::sessionBus());
QDBusReply<unsigned> reply = inhibit.call("Inhibit", program, reason);
if ( reply.isValid() ) {
m_fallbackCookie = reply.value();
}
}
}
Inhibitor::~Inhibitor()
{
if ( m_cookie != nullptr ) {
/* Deleting this object will close the associated file
* descriptor, which will in turn release the lock. */
delete m_cookie;
}
else if ( m_fallbackCookie != 0 ) {
/* If we had to use the old interface to acquire the lock, it
* has to be explicitly released. */
QDBusInterface inhibit(INHIBIT_NAME, INHIBIT_PATH, INHIBIT_NAME,
QDBusConnection::sessionBus());
inhibit.call("UnInhibit", m_fallbackCookie);
}
}
bool
Inhibitor::isInhibited()
{
return m_cookie != nullptr || m_fallbackCookie != 0;
}

@ -0,0 +1,37 @@
/*
* pm-inhibit - Power Management Inhibition Tool
* Copyright (C) 2022 Damien Goutte-Gattat
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ICP20221113_INHIBITOR_H
#define ICP20221113_INHIBITOR_H
#include <QDBusUnixFileDescriptor>
class Inhibitor
{
public:
Inhibitor(const QString& program, const QString& reason);
~Inhibitor();
bool isInhibited();
private:
QDBusUnixFileDescriptor *m_cookie;
unsigned m_fallbackCookie;
};
#endif /* !ICP20221113_INHIBITOR_H */

@ -17,16 +17,11 @@
*/
#include <QCoreApplication>
#include <QDBusConnection>
#include <QDBusInterface>
#include <QDBusReply>
#include <QDBusUnixFileDescriptor>
#include <QTextStream>
#include <QStringList>
#include <QProcess>
#define LOGIN1_NAME "org.freedesktop.login1"
#define LOGIN1_PATH "/org/freedesktop/login1"
#include "inhibitor.h"
int
main(int argc, char **argv)
@ -40,14 +35,9 @@ main(int argc, char **argv)
return 1;
}
QDBusConnection dbus = QDBusConnection::systemBus();
QDBusInterface manager(LOGIN1_NAME, LOGIN1_PATH,
LOGIN1_NAME ".Manager", dbus);
QDBusReply<QDBusUnixFileDescriptor> reply = manager.call("Inhibit",
"idle", "pm-inhibit", "User-specified inhibition", "block");
if ( ! reply.isValid() ) {
cerr << "Cannot inhibit power management features: "
<< reply.error().message() << "\n";
Inhibitor inhibitor("pm-inhibit", "User-specified inhibition");
if ( ! inhibitor.isInhibited() ) {
cerr << "Cannot inhibit power management features" << "\n";
return 1;
}

Loading…
Cancel
Save