forked from quickshell/quickshell
		
	service/upower: add power-profiles support
This commit is contained in:
		
							parent
							
								
									66b9917e70
								
							
						
					
					
						commit
						47bcf8ee61
					
				
					 6 changed files with 462 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -36,8 +36,8 @@ template <typename T>
 | 
			
		|||
class DBusResult {
 | 
			
		||||
public:
 | 
			
		||||
	explicit DBusResult() = default;
 | 
			
		||||
	explicit DBusResult(T value): value(std::move(value)) {}
 | 
			
		||||
	explicit DBusResult(QDBusError error): error(std::move(error)) {}
 | 
			
		||||
	DBusResult(T value): value(std::move(value)) {}
 | 
			
		||||
	DBusResult(QDBusError error): error(std::move(error)) {}
 | 
			
		||||
	explicit DBusResult(T value, QDBusError error)
 | 
			
		||||
	    : value(std::move(value))
 | 
			
		||||
	    , error(std::move(error)) {}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,6 +21,7 @@ qt_add_dbus_interface(DBUS_INTERFACES
 | 
			
		|||
qt_add_library(quickshell-service-upower STATIC
 | 
			
		||||
	core.cpp
 | 
			
		||||
	device.cpp
 | 
			
		||||
	powerprofiles.cpp
 | 
			
		||||
	${DBUS_INTERFACES}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,6 +54,14 @@ private:
 | 
			
		|||
	DBusUPowerService* service = nullptr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
///! Provides access to the UPower service.
 | 
			
		||||
/// An interface to the [UPower daemon], which can be used to
 | 
			
		||||
/// view battery and power statistics for your computer and
 | 
			
		||||
/// connected devices.
 | 
			
		||||
///
 | 
			
		||||
/// > [!NOTE] The UPower daemon must be installed to use this service.
 | 
			
		||||
///
 | 
			
		||||
/// [UPower daemon]: https://upower.freedesktop.org
 | 
			
		||||
class UPowerQml: public QObject {
 | 
			
		||||
	Q_OBJECT;
 | 
			
		||||
	QML_NAMED_ELEMENT(UPower);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,5 +3,6 @@ description = "UPower Service"
 | 
			
		|||
headers = [
 | 
			
		||||
	"core.hpp",
 | 
			
		||||
	"device.hpp",
 | 
			
		||||
	"powerprofiles.hpp",
 | 
			
		||||
]
 | 
			
		||||
-----
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										213
									
								
								src/services/upower/powerprofiles.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										213
									
								
								src/services/upower/powerprofiles.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,213 @@
 | 
			
		|||
#include "powerprofiles.hpp"
 | 
			
		||||
 | 
			
		||||
#include <qcontainerfwd.h>
 | 
			
		||||
#include <qdbusconnection.h>
 | 
			
		||||
#include <qdbuserror.h>
 | 
			
		||||
#include <qdbusinterface.h>
 | 
			
		||||
#include <qdbusmetatype.h>
 | 
			
		||||
#include <qdebug.h>
 | 
			
		||||
#include <qlist.h>
 | 
			
		||||
#include <qlogging.h>
 | 
			
		||||
#include <qloggingcategory.h>
 | 
			
		||||
#include <qobject.h>
 | 
			
		||||
#include <qstringliteral.h>
 | 
			
		||||
 | 
			
		||||
#include "../../dbus/bus.hpp"
 | 
			
		||||
#include "../../dbus/properties.hpp"
 | 
			
		||||
 | 
			
		||||
namespace qs::service::upower {
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
Q_LOGGING_CATEGORY(logPowerProfiles, "quickshell.service.powerprofiles", QtWarningMsg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString PowerProfile::toString(PowerProfile::Enum profile) {
 | 
			
		||||
	switch (profile) {
 | 
			
		||||
	case PowerProfile::PowerSaver: return QStringLiteral("PowerSaver");
 | 
			
		||||
	case PowerProfile::Balanced: return QStringLiteral("Balanced");
 | 
			
		||||
	case PowerProfile::Performance: return QStringLiteral("Performance");
 | 
			
		||||
	default: return QStringLiteral("Invalid");
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString PerformanceDegradationReason::toString(PerformanceDegradationReason::Enum reason) {
 | 
			
		||||
	switch (reason) {
 | 
			
		||||
	case PerformanceDegradationReason::LapDetected: return QStringLiteral("LapDetected");
 | 
			
		||||
	case PerformanceDegradationReason::HighTemperature: return QStringLiteral("HighTemperature");
 | 
			
		||||
	default: return QStringLiteral("Invalid");
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool PowerProfileHold::operator==(const PowerProfileHold& other) const {
 | 
			
		||||
	return other.profile == this->profile && other.applicationId == this->applicationId
 | 
			
		||||
	    && other.reason == this->reason;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QDebug& operator<<(QDebug& debug, const PowerProfileHold& hold) {
 | 
			
		||||
	auto saver = QDebugStateSaver(debug);
 | 
			
		||||
 | 
			
		||||
	debug.nospace();
 | 
			
		||||
	debug << "PowerProfileHold(profile=" << hold.profile << ", applicationId=" << hold.applicationId
 | 
			
		||||
	      << ", reason=" << hold.reason << ')';
 | 
			
		||||
 | 
			
		||||
	return debug;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PowerProfiles::PowerProfiles() {
 | 
			
		||||
	qDBusRegisterMetaType<QList<QVariantMap>>();
 | 
			
		||||
 | 
			
		||||
	this->bHasPerformanceProfile.setBinding([this]() {
 | 
			
		||||
		return this->bProfiles.value().contains(PowerProfile::Performance);
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	qCDebug(logPowerProfiles) << "Starting PowerProfiles Service.";
 | 
			
		||||
 | 
			
		||||
	auto bus = QDBusConnection::systemBus();
 | 
			
		||||
 | 
			
		||||
	if (!bus.isConnected()) {
 | 
			
		||||
		qCWarning(logPowerProfiles
 | 
			
		||||
		) << "Could not connect to DBus. PowerProfiles services will not work.";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this->service = new QDBusInterface(
 | 
			
		||||
	    "org.freedesktop.UPower.PowerProfiles",
 | 
			
		||||
	    "/org/freedesktop/UPower/PowerProfiles",
 | 
			
		||||
	    "org.freedesktop.UPower.PowerProfiles",
 | 
			
		||||
	    bus,
 | 
			
		||||
	    this
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	if (!this->service->isValid()) {
 | 
			
		||||
		qCDebug(logPowerProfiles
 | 
			
		||||
		) << "PowerProfilesDaemon is not currently running, attempting to start it.";
 | 
			
		||||
 | 
			
		||||
		dbus::tryLaunchService(this, bus, "org.freedesktop.UPower.PowerProfiles", [this](bool success) {
 | 
			
		||||
			if (success) {
 | 
			
		||||
				qCDebug(logPowerProfiles) << "Successfully launched PowerProfiles service.";
 | 
			
		||||
				this->init();
 | 
			
		||||
			} else {
 | 
			
		||||
				qCWarning(logPowerProfiles)
 | 
			
		||||
				    << "Could not start PowerProfilesDaemon. The PowerProfiles service will not work.";
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
	} else {
 | 
			
		||||
		this->init();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PowerProfiles::init() {
 | 
			
		||||
	this->properties.setInterface(this->service);
 | 
			
		||||
	this->properties.updateAllViaGetAll();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PowerProfiles::setProfile(PowerProfile::Enum profile) {
 | 
			
		||||
	if (profile == PowerProfile::Performance && !this->bHasPerformanceProfile) {
 | 
			
		||||
		qCCritical(logPowerProfiles
 | 
			
		||||
		) << "Cannot request performance profile as it is not present for this device.";
 | 
			
		||||
		return;
 | 
			
		||||
	} else if (profile < PowerProfile::PowerSaver || profile > PowerProfile::Performance) {
 | 
			
		||||
		qCCritical(logPowerProfiles) << "Tried to request invalid power profile" << profile;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this->bProfile = profile;
 | 
			
		||||
	this->pProfile.write();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PowerProfiles* PowerProfiles::instance() {
 | 
			
		||||
	static auto* instance = new PowerProfiles(); // NOLINT
 | 
			
		||||
	return instance;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PowerProfilesQml::PowerProfilesQml(QObject* parent): QObject(parent) {
 | 
			
		||||
	auto* instance = PowerProfiles::instance();
 | 
			
		||||
 | 
			
		||||
	this->bProfile.setBinding([instance]() { return instance->bProfile.value(); });
 | 
			
		||||
 | 
			
		||||
	this->bHasPerformanceProfile.setBinding([instance]() {
 | 
			
		||||
		return instance->bHasPerformanceProfile.value();
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	this->bDegradationReason.setBinding([instance]() { return instance->bDegradationReason.value(); }
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	this->bHolds.setBinding([instance]() { return instance->bHolds.value(); });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace qs::service::upower
 | 
			
		||||
 | 
			
		||||
namespace qs::dbus {
 | 
			
		||||
 | 
			
		||||
using namespace qs::service::upower;
 | 
			
		||||
 | 
			
		||||
DBusResult<PowerProfile::Enum> DBusDataTransform<PowerProfile::Enum>::fromWire(const Wire& wire) {
 | 
			
		||||
	if (wire == QStringLiteral("power-saver")) {
 | 
			
		||||
		return PowerProfile::PowerSaver;
 | 
			
		||||
	} else if (wire == QStringLiteral("balanced")) {
 | 
			
		||||
		return PowerProfile::Balanced;
 | 
			
		||||
	} else if (wire == QStringLiteral("performance")) {
 | 
			
		||||
		return PowerProfile::Performance;
 | 
			
		||||
	} else {
 | 
			
		||||
		return QDBusError(QDBusError::InvalidArgs, QString("Invalid PowerProfile: %1").arg(wire));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString DBusDataTransform<PowerProfile::Enum>::toWire(Data data) {
 | 
			
		||||
	switch (data) {
 | 
			
		||||
	case PowerProfile::PowerSaver: return QStringLiteral("power-saver");
 | 
			
		||||
	case PowerProfile::Balanced: return QStringLiteral("balanced");
 | 
			
		||||
	case PowerProfile::Performance: return QStringLiteral("performance");
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DBusResult<QList<PowerProfile::Enum>>
 | 
			
		||||
DBusDataTransform<QList<PowerProfile::Enum>>::fromWire(const Wire& wire) {
 | 
			
		||||
	QList<PowerProfile::Enum> profiles;
 | 
			
		||||
 | 
			
		||||
	for (const auto& entry: wire) {
 | 
			
		||||
		auto profile =
 | 
			
		||||
		    DBusDataTransform<PowerProfile::Enum>::fromWire(entry.value("Profile").value<QString>());
 | 
			
		||||
 | 
			
		||||
		if (!profile.isValid()) return profile.error;
 | 
			
		||||
		profiles.append(profile.value);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return profiles;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DBusResult<PerformanceDegradationReason::Enum>
 | 
			
		||||
DBusDataTransform<PerformanceDegradationReason::Enum>::fromWire(const Wire& wire) {
 | 
			
		||||
	if (wire.isEmpty()) {
 | 
			
		||||
		return PerformanceDegradationReason::None;
 | 
			
		||||
	} else if (wire == QStringLiteral("lap-detected")) {
 | 
			
		||||
		return PerformanceDegradationReason::LapDetected;
 | 
			
		||||
	} else if (wire == QStringLiteral("high-operating-temperature")) {
 | 
			
		||||
		return PerformanceDegradationReason::HighTemperature;
 | 
			
		||||
	} else {
 | 
			
		||||
		return QDBusError(
 | 
			
		||||
		    QDBusError::InvalidArgs,
 | 
			
		||||
		    QString("Invalid PerformanceDegradationReason: %1").arg(wire)
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DBusResult<QList<PowerProfileHold>>
 | 
			
		||||
DBusDataTransform<QList<PowerProfileHold>>::fromWire(const Wire& wire) {
 | 
			
		||||
	QList<PowerProfileHold> holds;
 | 
			
		||||
 | 
			
		||||
	for (const auto& entry: wire) {
 | 
			
		||||
		auto profile =
 | 
			
		||||
		    DBusDataTransform<PowerProfile::Enum>::fromWire(entry.value("Profile").value<QString>());
 | 
			
		||||
 | 
			
		||||
		if (!profile.isValid()) return profile.error;
 | 
			
		||||
 | 
			
		||||
		auto applicationId = entry.value("ApplicationId").value<QString>();
 | 
			
		||||
		auto reason = entry.value("Reason").value<QString>();
 | 
			
		||||
 | 
			
		||||
		holds.append(PowerProfileHold(profile.value, applicationId, reason));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return holds;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace qs::dbus
 | 
			
		||||
							
								
								
									
										237
									
								
								src/services/upower/powerprofiles.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										237
									
								
								src/services/upower/powerprofiles.hpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,237 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <utility>
 | 
			
		||||
 | 
			
		||||
#include <qcontainerfwd.h>
 | 
			
		||||
#include <qdbusinterface.h>
 | 
			
		||||
#include <qdebug.h>
 | 
			
		||||
#include <qobject.h>
 | 
			
		||||
#include <qproperty.h>
 | 
			
		||||
#include <qqmlintegration.h>
 | 
			
		||||
#include <qtmetamacros.h>
 | 
			
		||||
#include <qtypes.h>
 | 
			
		||||
 | 
			
		||||
#include "../../dbus/properties.hpp"
 | 
			
		||||
 | 
			
		||||
namespace qs::service::upower {
 | 
			
		||||
 | 
			
		||||
///! Power profile exposed by the PowerProfiles service.
 | 
			
		||||
/// See @@PowerProfiles.
 | 
			
		||||
class PowerProfile: public QObject {
 | 
			
		||||
	Q_OBJECT;
 | 
			
		||||
	QML_ELEMENT;
 | 
			
		||||
	QML_SINGLETON;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	enum Enum : quint8 {
 | 
			
		||||
		/// This profile will limit system performance in order to save power.
 | 
			
		||||
		PowerSaver = 0,
 | 
			
		||||
		/// This profile is the default, and will attempt to strike a balance
 | 
			
		||||
		/// between performance and power consumption.
 | 
			
		||||
		Balanced = 1,
 | 
			
		||||
		/// This profile will maximize performance at the cost of power consumption.
 | 
			
		||||
		Performance = 2,
 | 
			
		||||
	};
 | 
			
		||||
	Q_ENUM(Enum);
 | 
			
		||||
 | 
			
		||||
	Q_INVOKABLE static QString toString(qs::service::upower::PowerProfile::Enum profile);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
///! Reason for performance degradation exposed by the PowerProfiles service.
 | 
			
		||||
/// See @@PowerProfiles.degradationReason for more information.
 | 
			
		||||
class PerformanceDegradationReason: public QObject {
 | 
			
		||||
	Q_OBJECT;
 | 
			
		||||
	QML_ELEMENT;
 | 
			
		||||
	QML_SINGLETON;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	enum Enum : quint8 {
 | 
			
		||||
		/// Performance has not been degraded in a way power-profiles-daemon can detect.
 | 
			
		||||
		None = 0,
 | 
			
		||||
		/// Performance has been reduced due to the computer's lap detection function,
 | 
			
		||||
		/// which attempts to keep the computer from getting too hot while on your lap.
 | 
			
		||||
		LapDetected = 1,
 | 
			
		||||
		/// Performance has been reduced due to high system temperatures.
 | 
			
		||||
		HighTemperature = 2,
 | 
			
		||||
	};
 | 
			
		||||
	Q_ENUM(Enum);
 | 
			
		||||
 | 
			
		||||
	// clang-format off
 | 
			
		||||
	Q_INVOKABLE static QString toString(qs::service::upower::PerformanceDegradationReason::Enum reason);
 | 
			
		||||
	// clang-format on
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class PowerProfileHold;
 | 
			
		||||
 | 
			
		||||
} // namespace qs::service::upower
 | 
			
		||||
 | 
			
		||||
namespace qs::dbus {
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct DBusDataTransform<qs::service::upower::PowerProfile::Enum> {
 | 
			
		||||
	using Wire = QString;
 | 
			
		||||
	using Data = qs::service::upower::PowerProfile::Enum;
 | 
			
		||||
	static DBusResult<Data> fromWire(const Wire& wire);
 | 
			
		||||
	static Wire toWire(Data data);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct DBusDataTransform<QList<qs::service::upower::PowerProfile::Enum>> {
 | 
			
		||||
	using Wire = QList<QVariantMap>;
 | 
			
		||||
	using Data = QList<qs::service::upower::PowerProfile::Enum>;
 | 
			
		||||
	static DBusResult<Data> fromWire(const Wire& wire);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct DBusDataTransform<qs::service::upower::PerformanceDegradationReason::Enum> {
 | 
			
		||||
	using Wire = QString;
 | 
			
		||||
	using Data = qs::service::upower::PerformanceDegradationReason::Enum;
 | 
			
		||||
	static DBusResult<Data> fromWire(const Wire& wire);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct DBusDataTransform<QList<qs::service::upower::PowerProfileHold>> {
 | 
			
		||||
	using Wire = QList<QVariantMap>;
 | 
			
		||||
	using Data = QList<qs::service::upower::PowerProfileHold>;
 | 
			
		||||
	static DBusResult<Data> fromWire(const Wire& wire);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace qs::dbus
 | 
			
		||||
 | 
			
		||||
namespace qs::service::upower {
 | 
			
		||||
 | 
			
		||||
// docgen can't hit gadgets yet
 | 
			
		||||
class PowerProfileHold {
 | 
			
		||||
	Q_GADGET;
 | 
			
		||||
	QML_VALUE_TYPE(powerProfileHold);
 | 
			
		||||
	Q_PROPERTY(qs::service::upower::PowerProfile::Enum profile MEMBER profile CONSTANT);
 | 
			
		||||
	Q_PROPERTY(QString applicationId MEMBER applicationId CONSTANT);
 | 
			
		||||
	Q_PROPERTY(QString reason MEMBER reason CONSTANT);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	explicit PowerProfileHold() = default;
 | 
			
		||||
	explicit PowerProfileHold(PowerProfile::Enum profile, QString applicationId, QString reason)
 | 
			
		||||
	    : profile(profile)
 | 
			
		||||
	    , applicationId(std::move(applicationId))
 | 
			
		||||
	    , reason(std::move(reason)) {}
 | 
			
		||||
 | 
			
		||||
	PowerProfile::Enum profile = PowerProfile::Balanced;
 | 
			
		||||
	QString applicationId;
 | 
			
		||||
	QString reason;
 | 
			
		||||
 | 
			
		||||
	[[nodiscard]] bool operator==(const PowerProfileHold& other) const;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
QDebug& operator<<(QDebug& debug, const PowerProfileHold& hold);
 | 
			
		||||
 | 
			
		||||
class PowerProfiles: public QObject {
 | 
			
		||||
	Q_OBJECT;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	void setProfile(PowerProfile::Enum profile);
 | 
			
		||||
 | 
			
		||||
	// clang-format off
 | 
			
		||||
	Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(PowerProfiles, PowerProfile::Enum, bProfile, PowerProfile::Balanced);
 | 
			
		||||
	Q_OBJECT_BINDABLE_PROPERTY(PowerProfiles, bool, bHasPerformanceProfile);
 | 
			
		||||
	Q_OBJECT_BINDABLE_PROPERTY(PowerProfiles, PerformanceDegradationReason::Enum, bDegradationReason);
 | 
			
		||||
	Q_OBJECT_BINDABLE_PROPERTY(PowerProfiles, QList<PowerProfileHold>, bHolds);
 | 
			
		||||
	// clang-format on
 | 
			
		||||
 | 
			
		||||
	static PowerProfiles* instance();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	explicit PowerProfiles();
 | 
			
		||||
	void init();
 | 
			
		||||
 | 
			
		||||
	// clang-format off
 | 
			
		||||
	Q_OBJECT_BINDABLE_PROPERTY(PowerProfiles, QList<PowerProfile::Enum>, bProfiles);
 | 
			
		||||
 | 
			
		||||
	QS_DBUS_BINDABLE_PROPERTY_GROUP(PowerProfiles, properties);
 | 
			
		||||
	QS_DBUS_PROPERTY_BINDING(PowerProfiles, pProfile, bProfile, properties, "ActiveProfile");
 | 
			
		||||
	QS_DBUS_PROPERTY_BINDING(PowerProfiles, pProfiles, bProfiles, properties, "Profiles");
 | 
			
		||||
	QS_DBUS_PROPERTY_BINDING(PowerProfiles, pPerformanceDegraded, bDegradationReason, properties, "PerformanceDegraded");
 | 
			
		||||
	QS_DBUS_PROPERTY_BINDING(PowerProfiles, pHolds, bHolds, properties, "ActiveProfileHolds");
 | 
			
		||||
	// clang-format on
 | 
			
		||||
 | 
			
		||||
	QDBusInterface* service = nullptr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
///! Provides access to the Power Profiles service.
 | 
			
		||||
/// An interface to the UPower [power profiles daemon], which can be
 | 
			
		||||
/// used to view and manage power profiles.
 | 
			
		||||
///
 | 
			
		||||
/// > [!NOTE] The power profiles daemon must be installed to use this service.
 | 
			
		||||
/// > Installing UPower does not necessarily install the power profiles daemon.
 | 
			
		||||
///
 | 
			
		||||
/// [power profiles daemon]: https://gitlab.freedesktop.org/upower/power-profiles-daemon
 | 
			
		||||
class PowerProfilesQml: public QObject {
 | 
			
		||||
	Q_OBJECT;
 | 
			
		||||
	QML_NAMED_ELEMENT(PowerProfiles);
 | 
			
		||||
	QML_SINGLETON;
 | 
			
		||||
	// clang-format off
 | 
			
		||||
	/// The current power profile.
 | 
			
		||||
	///
 | 
			
		||||
	/// This property may be set to change the system's power profile, however
 | 
			
		||||
	/// it cannot be set to `Performance` unless @@hasPerformanceProfile is true.
 | 
			
		||||
	Q_PROPERTY(qs::service::upower::PowerProfile::Enum profile READ default WRITE setProfile NOTIFY profileChanged BINDABLE bindableProfile);
 | 
			
		||||
	/// If the system has a performance profile.
 | 
			
		||||
	///
 | 
			
		||||
	/// If this property is false, your system does not have a performance
 | 
			
		||||
	/// profile known to power-profiles-daemon.
 | 
			
		||||
	Q_PROPERTY(bool hasPerformanceProfile READ default NOTIFY hasPerformanceProfileChanged BINDABLE bindableHasPerformanceProfile);
 | 
			
		||||
	/// If power-profiles-daemon detects degraded system performance, the reason
 | 
			
		||||
	/// for the degradation will be present here.
 | 
			
		||||
	Q_PROPERTY(qs::service::upower::PerformanceDegradationReason::Enum degradationReason READ default NOTIFY degradationReasonChanged BINDABLE bindableDegradationReason);
 | 
			
		||||
	/// Power profile holds created by other applications.
 | 
			
		||||
	///
 | 
			
		||||
	/// This property returns a `powerProfileHold` object, which has the following properties.
 | 
			
		||||
	/// - `profile` - The @@PowerProfile held by the application.
 | 
			
		||||
	/// - `applicationId` - A string identifying the application
 | 
			
		||||
	/// - `reason` - The reason the application has given for holding the profile.
 | 
			
		||||
	///
 | 
			
		||||
	/// Applications may "hold" a power profile in place for their lifetime, such
 | 
			
		||||
	/// as a game holding Performance mode or a system daemon holding Power Saver mode
 | 
			
		||||
	/// when reaching a battery threshold. If the user selects a different profile explicitly
 | 
			
		||||
	/// (e.g. by setting @@profile$) all holds will be removed.
 | 
			
		||||
	///
 | 
			
		||||
	/// Multiple applications may hold a power profile, however if multiple applications request
 | 
			
		||||
	/// profiles than `PowerSaver` will win over `Performance`. Only `Performance` and `PowerSaver`
 | 
			
		||||
	/// profiles may be held.
 | 
			
		||||
	Q_PROPERTY(QList<qs::service::upower::PowerProfileHold> holds READ default NOTIFY holdsChanged BINDABLE bindableHolds);
 | 
			
		||||
	// clang-format on
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
	void profileChanged();
 | 
			
		||||
	void hasPerformanceProfileChanged();
 | 
			
		||||
	void degradationReasonChanged();
 | 
			
		||||
	void holdsChanged();
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	explicit PowerProfilesQml(QObject* parent = nullptr);
 | 
			
		||||
 | 
			
		||||
	[[nodiscard]] QBindable<PowerProfile::Enum> bindableProfile() const { return &this->bProfile; }
 | 
			
		||||
 | 
			
		||||
	static void setProfile(PowerProfile::Enum profile) {
 | 
			
		||||
		PowerProfiles::instance()->setProfile(profile);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	[[nodiscard]] QBindable<bool> bindableHasPerformanceProfile() const {
 | 
			
		||||
		return &this->bHasPerformanceProfile;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	[[nodiscard]] QBindable<PerformanceDegradationReason::Enum> bindableDegradationReason() const {
 | 
			
		||||
		return &this->bDegradationReason;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	[[nodiscard]] QBindable<QList<PowerProfileHold>> bindableHolds() const { return &this->bHolds; }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	// clang-format off
 | 
			
		||||
	Q_OBJECT_BINDABLE_PROPERTY(PowerProfilesQml, PowerProfile::Enum, bProfile, &PowerProfilesQml::profileChanged);
 | 
			
		||||
	Q_OBJECT_BINDABLE_PROPERTY(PowerProfilesQml, bool, bHasPerformanceProfile, &PowerProfilesQml::hasPerformanceProfileChanged);
 | 
			
		||||
	Q_OBJECT_BINDABLE_PROPERTY(PowerProfilesQml, PerformanceDegradationReason::Enum, bDegradationReason, &PowerProfilesQml::degradationReasonChanged);
 | 
			
		||||
	Q_OBJECT_BINDABLE_PROPERTY(PowerProfilesQml, QList<PowerProfileHold>, bHolds, &PowerProfilesQml::holdsChanged);
 | 
			
		||||
	// clang-format on
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace qs::service::upower
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue