forked from quickshell/quickshell
service/mpris: finish mpris implementation
This commit is contained in:
parent
3b6d1c3bd8
commit
4ee9ac7f7c
16 changed files with 911 additions and 578 deletions
|
@ -188,9 +188,9 @@ public:
|
|||
|
||||
dbus::DBusPropertyGroup properties;
|
||||
dbus::DBusProperty<quint32> version {this->properties, "Version"};
|
||||
dbus::DBusProperty<QString> textDirection {this->properties, "TextDirection"};
|
||||
dbus::DBusProperty<QString> textDirection {this->properties, "TextDirection", "", false};
|
||||
dbus::DBusProperty<QString> status {this->properties, "Status"};
|
||||
dbus::DBusProperty<QStringList> iconThemePath {this->properties, "IconThemePath"};
|
||||
dbus::DBusProperty<QStringList> iconThemePath {this->properties, "IconThemePath", {}, false};
|
||||
|
||||
void prepareToShow(qint32 item, bool sendOpened);
|
||||
void updateLayout(qint32 parent, qint32 depth);
|
||||
|
|
|
@ -112,6 +112,8 @@ void asyncReadPropertyInternal(
|
|||
}
|
||||
|
||||
void AbstractDBusProperty::tryUpdate(const QVariant& variant) {
|
||||
this->mExists = true;
|
||||
|
||||
auto error = this->read(variant);
|
||||
if (error.isValid()) {
|
||||
qCWarning(logDbusProperties).noquote()
|
||||
|
@ -159,6 +161,44 @@ void AbstractDBusProperty::update() {
|
|||
}
|
||||
}
|
||||
|
||||
void AbstractDBusProperty::write() {
|
||||
if (this->group == nullptr) {
|
||||
qFatal(logDbusProperties) << "Tried to write dbus property" << this->name
|
||||
<< "which is not attached to a group";
|
||||
} else {
|
||||
const QString propStr = this->toString();
|
||||
|
||||
if (this->group->interface == nullptr) {
|
||||
qFatal(logDbusProperties).noquote()
|
||||
<< "Tried to write property" << propStr << "of a disconnected interface";
|
||||
}
|
||||
|
||||
qCDebug(logDbusProperties).noquote() << "Writing property" << propStr;
|
||||
|
||||
auto pendingCall = this->group->propertyInterface->Set(
|
||||
this->group->interface->interface(),
|
||||
this->name,
|
||||
QDBusVariant(this->serialize())
|
||||
);
|
||||
|
||||
auto* call = new QDBusPendingCallWatcher(pendingCall, this);
|
||||
|
||||
auto responseCallback = [propStr](QDBusPendingCallWatcher* call) {
|
||||
const QDBusPendingReply<> reply = *call;
|
||||
|
||||
if (reply.isError()) {
|
||||
qCWarning(logDbusProperties).noquote() << "Error writing property" << propStr;
|
||||
qCWarning(logDbusProperties) << reply.error();
|
||||
}
|
||||
delete call;
|
||||
};
|
||||
|
||||
QObject::connect(call, &QDBusPendingCallWatcher::finished, this, responseCallback);
|
||||
}
|
||||
}
|
||||
|
||||
bool AbstractDBusProperty::exists() const { return this->mExists; }
|
||||
|
||||
QString AbstractDBusProperty::toString() const {
|
||||
const QString group = this->group == nullptr ? "{ NO GROUP }" : this->group->toString();
|
||||
return group + ':' + this->name;
|
||||
|
@ -232,7 +272,7 @@ void DBusPropertyGroup::updateAllViaGetAll() {
|
|||
} else {
|
||||
qCDebug(logDbusProperties).noquote()
|
||||
<< "Received GetAll property set for" << this->toString();
|
||||
this->updatePropertySet(reply.value());
|
||||
this->updatePropertySet(reply.value(), true);
|
||||
}
|
||||
|
||||
delete call;
|
||||
|
@ -242,7 +282,7 @@ void DBusPropertyGroup::updateAllViaGetAll() {
|
|||
QObject::connect(call, &QDBusPendingCallWatcher::finished, this, responseCallback);
|
||||
}
|
||||
|
||||
void DBusPropertyGroup::updatePropertySet(const QVariantMap& properties) {
|
||||
void DBusPropertyGroup::updatePropertySet(const QVariantMap& properties, bool complainMissing) {
|
||||
for (const auto [name, value]: properties.asKeyValueRange()) {
|
||||
auto prop = std::find_if(
|
||||
this->properties.begin(),
|
||||
|
@ -251,11 +291,21 @@ void DBusPropertyGroup::updatePropertySet(const QVariantMap& properties) {
|
|||
);
|
||||
|
||||
if (prop == this->properties.end()) {
|
||||
qCDebug(logDbusProperties) << "Ignoring untracked property update" << name << "for" << this;
|
||||
qCDebug(logDbusProperties) << "Ignoring untracked property update" << name << "for"
|
||||
<< this->toString();
|
||||
} else {
|
||||
(*prop)->tryUpdate(value);
|
||||
}
|
||||
}
|
||||
|
||||
if (complainMissing) {
|
||||
for (const auto* prop: this->properties) {
|
||||
if (prop->required && !properties.contains(prop->name)) {
|
||||
qCWarning(logDbusProperties)
|
||||
<< prop->name << "missing from property set for" << this->toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString DBusPropertyGroup::toString() const {
|
||||
|
@ -291,7 +341,7 @@ void DBusPropertyGroup::onPropertiesChanged(
|
|||
}
|
||||
}
|
||||
|
||||
this->updatePropertySet(changedProperties);
|
||||
this->updatePropertySet(changedProperties, false);
|
||||
}
|
||||
|
||||
} // namespace qs::dbus
|
||||
|
|
|
@ -79,22 +79,31 @@ class AbstractDBusProperty: public QObject {
|
|||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
explicit AbstractDBusProperty(QString name, const QMetaType& type, QObject* parent = nullptr)
|
||||
explicit AbstractDBusProperty(
|
||||
QString name,
|
||||
const QMetaType& type,
|
||||
bool required,
|
||||
QObject* parent = nullptr
|
||||
)
|
||||
: QObject(parent)
|
||||
, name(std::move(name))
|
||||
, type(type) {}
|
||||
, type(type)
|
||||
, required(required) {}
|
||||
|
||||
[[nodiscard]] bool exists() const;
|
||||
[[nodiscard]] QString toString() const;
|
||||
[[nodiscard]] virtual QString valueString() = 0;
|
||||
|
||||
public slots:
|
||||
void update();
|
||||
void write();
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
|
||||
protected:
|
||||
virtual QDBusError read(const QVariant& variant) = 0;
|
||||
virtual QVariant serialize() = 0;
|
||||
|
||||
private:
|
||||
void tryUpdate(const QVariant& variant);
|
||||
|
@ -103,6 +112,8 @@ private:
|
|||
|
||||
QString name;
|
||||
QMetaType type;
|
||||
bool required;
|
||||
bool mExists = false;
|
||||
|
||||
friend class DBusPropertyGroup;
|
||||
};
|
||||
|
@ -133,7 +144,7 @@ private slots:
|
|||
);
|
||||
|
||||
private:
|
||||
void updatePropertySet(const QVariantMap& properties);
|
||||
void updatePropertySet(const QVariantMap& properties, bool complainMissing);
|
||||
|
||||
DBusPropertiesInterface* propertyInterface = nullptr;
|
||||
QDBusAbstractInterface* interface = nullptr;
|
||||
|
@ -145,17 +156,23 @@ private:
|
|||
template <typename T>
|
||||
class DBusProperty: public AbstractDBusProperty {
|
||||
public:
|
||||
explicit DBusProperty(QString name, QObject* parent = nullptr, T value = T())
|
||||
: AbstractDBusProperty(std::move(name), QMetaType::fromType<T>(), parent)
|
||||
explicit DBusProperty(
|
||||
QString name,
|
||||
T value = T(),
|
||||
bool required = true,
|
||||
QObject* parent = nullptr
|
||||
)
|
||||
: AbstractDBusProperty(std::move(name), QMetaType::fromType<T>(), required, parent)
|
||||
, value(std::move(value)) {}
|
||||
|
||||
explicit DBusProperty(
|
||||
DBusPropertyGroup& group,
|
||||
QString name,
|
||||
QObject* parent = nullptr,
|
||||
T value = T()
|
||||
T value = T(),
|
||||
bool required = true,
|
||||
QObject* parent = nullptr
|
||||
)
|
||||
: DBusProperty(std::move(name), parent, std::move(value)) {
|
||||
: DBusProperty(std::move(name), std::move(value), required, parent) {
|
||||
group.attachProperty(this);
|
||||
}
|
||||
|
||||
|
@ -165,7 +182,7 @@ public:
|
|||
return str;
|
||||
}
|
||||
|
||||
[[nodiscard]] T get() const { return this->value; }
|
||||
[[nodiscard]] const T& get() const { return this->value; }
|
||||
|
||||
void set(T value) {
|
||||
this->value = std::move(value);
|
||||
|
@ -183,6 +200,8 @@ protected:
|
|||
return result.error;
|
||||
}
|
||||
|
||||
QVariant serialize() override { return QVariant::fromValue(this->value); }
|
||||
|
||||
private:
|
||||
T value;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue