forked from quickshell/quickshell
service/upower: add upower service
This commit is contained in:
parent
497c9c4e50
commit
24f54f579f
10 changed files with 638 additions and 0 deletions
165
src/services/upower/core.cpp
Normal file
165
src/services/upower/core.cpp
Normal file
|
@ -0,0 +1,165 @@
|
|||
#include "core.hpp"
|
||||
|
||||
#include <qcontainerfwd.h>
|
||||
#include <qdbusconnection.h>
|
||||
#include <qdbusconnectioninterface.h>
|
||||
#include <qdbusextratypes.h>
|
||||
#include <qdbuspendingcall.h>
|
||||
#include <qdbuspendingreply.h>
|
||||
#include <qdbusservicewatcher.h>
|
||||
#include <qlogging.h>
|
||||
#include <qloggingcategory.h>
|
||||
#include <qobject.h>
|
||||
#include <qqmllist.h>
|
||||
#include <qtmetamacros.h>
|
||||
|
||||
#include "../../core/model.hpp"
|
||||
#include "../../dbus/properties.hpp"
|
||||
#include "dbus_service.h"
|
||||
#include "device.hpp"
|
||||
|
||||
namespace qs::service::upower {
|
||||
|
||||
Q_LOGGING_CATEGORY(logUPower, "quickshell.service.upower", QtWarningMsg);
|
||||
|
||||
UPower::UPower() {
|
||||
qCDebug(logUPower) << "Starting UPower";
|
||||
|
||||
auto bus = QDBusConnection::systemBus();
|
||||
|
||||
if (!bus.isConnected()) {
|
||||
qCWarning(logUPower) << "Could not connect to DBus. UPower service will not work.";
|
||||
return;
|
||||
}
|
||||
|
||||
this->service =
|
||||
new DBusUPowerService("org.freedesktop.UPower", "/org/freedesktop/UPower", bus, this);
|
||||
|
||||
if (!this->service->isValid()) {
|
||||
qCWarning(logUPower) << "Cannot connect to the UPower service.";
|
||||
return;
|
||||
}
|
||||
|
||||
QObject::connect(
|
||||
&this->pOnBattery,
|
||||
&dbus::AbstractDBusProperty::changed,
|
||||
this,
|
||||
&UPower::onBatteryChanged
|
||||
);
|
||||
|
||||
this->serviceProperties.setInterface(this->service);
|
||||
this->serviceProperties.updateAllViaGetAll();
|
||||
|
||||
this->registerExisting();
|
||||
}
|
||||
|
||||
void UPower::registerExisting() {
|
||||
this->registerDevice("/org/freedesktop/UPower/devices/DisplayDevice");
|
||||
|
||||
auto pending = this->service->EnumerateDevices();
|
||||
auto* call = new QDBusPendingCallWatcher(pending, this);
|
||||
|
||||
auto responseCallback = [this](QDBusPendingCallWatcher* call) {
|
||||
const QDBusPendingReply<QList<QDBusObjectPath>> reply = *call;
|
||||
|
||||
if (reply.isError()) {
|
||||
qCWarning(logUPower) << "Failed to enumerate devices:" << reply.error().message();
|
||||
} else {
|
||||
for (const QDBusObjectPath& devicePath: reply.value()) {
|
||||
this->registerDevice(devicePath.path());
|
||||
}
|
||||
}
|
||||
|
||||
delete call;
|
||||
};
|
||||
|
||||
QObject::connect(call, &QDBusPendingCallWatcher::finished, this, responseCallback);
|
||||
}
|
||||
|
||||
void UPower::onDeviceReady() {
|
||||
auto* device = qobject_cast<UPowerDevice*>(this->sender());
|
||||
|
||||
if (device->path() == "/org/freedesktop/UPower/devices/DisplayDevice") {
|
||||
this->mDisplayDevice = device;
|
||||
emit this->displayDeviceChanged();
|
||||
qCDebug(logUPower) << "Display UPowerDevice" << device->path() << "ready";
|
||||
return;
|
||||
}
|
||||
|
||||
this->readyDevices.insertObject(device);
|
||||
qCDebug(logUPower) << "UPowerDevice" << device->path() << "ready";
|
||||
}
|
||||
|
||||
void UPower::onDeviceDestroyed(QObject* object) {
|
||||
auto* device = static_cast<UPowerDevice*>(object); // NOLINT
|
||||
|
||||
this->mDevices.remove(device->path());
|
||||
|
||||
if (device == this->mDisplayDevice) {
|
||||
this->mDisplayDevice = nullptr;
|
||||
emit this->displayDeviceChanged();
|
||||
qCDebug(logUPower) << "Display UPowerDevice" << device->path() << "destroyed";
|
||||
return;
|
||||
}
|
||||
|
||||
this->readyDevices.removeObject(device);
|
||||
qCDebug(logUPower) << "UPowerDevice" << device->path() << "destroyed";
|
||||
}
|
||||
|
||||
void UPower::registerDevice(const QString& path) {
|
||||
if (this->mDevices.contains(path)) {
|
||||
qCDebug(logUPower) << "Skipping duplicate registration of UPowerDevice" << path;
|
||||
return;
|
||||
}
|
||||
|
||||
auto* device = new UPowerDevice(path, this);
|
||||
if (!device->isValid()) {
|
||||
qCWarning(logUPower) << "Ignoring invalid UPowerDevice registration of" << path;
|
||||
delete device;
|
||||
return;
|
||||
}
|
||||
|
||||
this->mDevices.insert(path, device);
|
||||
QObject::connect(device, &UPowerDevice::ready, this, &UPower::onDeviceReady);
|
||||
QObject::connect(device, &QObject::destroyed, this, &UPower::onDeviceDestroyed);
|
||||
|
||||
qCDebug(logUPower) << "Registered UPowerDevice" << path;
|
||||
}
|
||||
|
||||
UPowerDevice* UPower::displayDevice() { return this->mDisplayDevice; }
|
||||
|
||||
ObjectModel<UPowerDevice>* UPower::devices() { return &this->readyDevices; }
|
||||
|
||||
bool UPower::onBattery() const { return this->pOnBattery.get(); }
|
||||
|
||||
UPower* UPower::instance() {
|
||||
static UPower* instance = new UPower(); // NOLINT
|
||||
return instance;
|
||||
}
|
||||
|
||||
UPowerQml::UPowerQml(QObject* parent): QObject(parent) {
|
||||
QObject::connect(
|
||||
UPower::instance(),
|
||||
&UPower::displayDeviceChanged,
|
||||
this,
|
||||
&UPowerQml::displayDeviceChanged
|
||||
);
|
||||
QObject::connect(
|
||||
UPower::instance(),
|
||||
&UPower::onBatteryChanged,
|
||||
this,
|
||||
&UPowerQml::onBatteryChanged
|
||||
);
|
||||
}
|
||||
|
||||
UPowerDevice* UPowerQml::displayDevice() { // NOLINT
|
||||
return UPower::instance()->displayDevice();
|
||||
}
|
||||
|
||||
ObjectModel<UPowerDevice>* UPowerQml::devices() { // NOLINT
|
||||
return UPower::instance()->devices();
|
||||
}
|
||||
|
||||
bool UPowerQml::onBattery() { return UPower::instance()->onBattery(); }
|
||||
|
||||
} // namespace qs::service::upower
|
Loading…
Add table
Add a link
Reference in a new issue