From dc96c21c7de26831d9d48f81a8c535fc3f767521 Mon Sep 17 00:00:00 2001 From: ComixHe Date: Fri, 8 Sep 2023 10:58:41 +0800 Subject: [PATCH] feat: emit signal when AutoStart Changed Signed-off-by: ComixHe --- src/constant.h | 1 + src/dbus/applicationmanager1service.cpp | 7 +++ src/dbus/applicationmanager1service.h | 3 +- src/dbus/applicationservice.cpp | 16 ++++-- src/dbus/applicationservice.h | 4 +- src/propertiesForwarder.cpp | 71 +++++++++++++++++++++++++ src/propertiesForwarder.h | 22 ++++++++ 7 files changed, 118 insertions(+), 6 deletions(-) create mode 100644 src/propertiesForwarder.cpp create mode 100644 src/propertiesForwarder.h diff --git a/src/constant.h b/src/constant.h index 7557567..528661a 100644 --- a/src/constant.h +++ b/src/constant.h @@ -41,6 +41,7 @@ constexpr auto JobInterface = "org.desktopspec.JobManager1.Job"; constexpr auto ApplicationManagerInterface = "org.desktopspec.ApplicationManager1"; constexpr auto InstanceInterface = "org.desktopspec.ApplicationManager1.Instance"; constexpr auto ApplicationInterface = "org.desktopspec.ApplicationManager1.Application"; +constexpr auto PropertiesInterface = u8"org.freedesktop.DBus.Properties"; constexpr auto systemdOption = u8"systemd"; constexpr auto splitOption = u8"split"; diff --git a/src/dbus/applicationmanager1service.cpp b/src/dbus/applicationmanager1service.cpp index 662bc74..1cdc52e 100644 --- a/src/dbus/applicationmanager1service.cpp +++ b/src/dbus/applicationmanager1service.cpp @@ -6,6 +6,7 @@ #include "applicationservice.h" #include "dbus/AMobjectmanager1adaptor.h" #include "systemdsignaldispatcher.h" +#include "propertiesForwarder.h" #include #include #include @@ -81,6 +82,10 @@ ApplicationManager1Service::ApplicationManager1Service(std::unique_ptrapplicationPath(), application); + emit listChanged(); emit InterfacesAdded(application->applicationPath(), getChildInterfacesAndPropertiesFromObject(ptr)); return true; @@ -251,6 +257,7 @@ void ApplicationManager1Service::removeOneApplication(const QDBusObjectPath &app emit InterfacesRemoved(application, getChildInterfacesFromObject(it->data())); unregisterObjectFromDBus(application.path()); m_applicationList.remove(application); + emit listChanged(); } } diff --git a/src/dbus/applicationmanager1service.h b/src/dbus/applicationmanager1service.h index 775685c..f8516ff 100644 --- a/src/dbus/applicationmanager1service.h +++ b/src/dbus/applicationmanager1service.h @@ -29,7 +29,7 @@ public: ApplicationManager1Service &operator=(const ApplicationManager1Service &) = delete; ApplicationManager1Service &operator=(ApplicationManager1Service &&) = delete; - Q_PROPERTY(QList List READ list) + Q_PROPERTY(QList List READ list NOTIFY listChanged) [[nodiscard]] QList list() const; bool addApplication(DesktopFile desktopFileSource) noexcept; @@ -48,6 +48,7 @@ public Q_SLOTS: Q_SIGNALS: void InterfacesAdded(const QDBusObjectPath &object_path, const ObjectInterfaceMap &interfaces); void InterfacesRemoved(const QDBusObjectPath &object_path, const QStringList &interfaces); + void listChanged(); private: std::unique_ptr m_identifier; diff --git a/src/dbus/applicationservice.cpp b/src/dbus/applicationservice.cpp index 63e0115..d1f2d2d 100644 --- a/src/dbus/applicationservice.cpp +++ b/src/dbus/applicationservice.cpp @@ -6,6 +6,7 @@ #include "APPobjectmanager1adaptor.h" #include "applicationchecker.h" #include "applicationmanager1service.h" +#include "propertiesForwarder.h" #include "dbus/instanceadaptor.h" #include "launchoptions.h" #include @@ -84,6 +85,11 @@ QSharedPointer ApplicationService::createApplicationService( return nullptr; } + if (auto *ptr = new (std::nothrow) PropertiesForwarder{app->m_applicationPath.path(), app.data()}; ptr == nullptr) { + qCritical() << "new PropertiesForwarder of Application failed."; + return nullptr; + } + return app; } @@ -402,12 +408,14 @@ bool ApplicationService::autostartCheck(const QString &linkPath) noexcept { QFileInfo info{linkPath}; - if (!info.exists() or !info.isSymbolicLink()) { + if (info.exists()) { + if (info.isSymbolicLink()) { + return true; + } qWarning() << "same name desktop file exists:" << linkPath << "but this may not created by AM."; - return false; } - return true; + return false; } bool ApplicationService::isAutoStart() const noexcept @@ -437,6 +445,8 @@ void ApplicationService::setAutoStart(bool autostart) noexcept } } } + + emit autostartChanged(); } QList ApplicationService::instances() const noexcept diff --git a/src/dbus/applicationservice.h b/src/dbus/applicationservice.h index 8480277..e2b7f82 100644 --- a/src/dbus/applicationservice.h +++ b/src/dbus/applicationservice.h @@ -58,8 +58,7 @@ public: // FIXME: // This property should implement with fuse guarded $XDG_CONFIG_HOME/autostart/. // Current implementation has some problems, - // such as it will not emit changed signal. - Q_PROPERTY(bool AutoStart READ isAutoStart WRITE setAutoStart) + Q_PROPERTY(bool AutoStart READ isAutoStart WRITE setAutoStart NOTIFY autostartChanged) [[nodiscard]] bool isAutoStart() const noexcept; void setAutoStart(bool autostart) noexcept; @@ -107,6 +106,7 @@ public Q_SLOTS: Q_SIGNALS: void InterfacesAdded(const QDBusObjectPath &object_path, const ObjectInterfaceMap &interfaces); void InterfacesRemoved(const QDBusObjectPath &object_path, const QStringList &interfaces); + void autostartChanged(); private: friend class ApplicationManager1Service; diff --git a/src/propertiesForwarder.cpp b/src/propertiesForwarder.cpp new file mode 100644 index 0000000..eef4c8e --- /dev/null +++ b/src/propertiesForwarder.cpp @@ -0,0 +1,71 @@ +// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#include "propertiesForwarder.h" +#include "global.h" +#include +#include +#include + +PropertiesForwarder::PropertiesForwarder(QString path, QObject *parent) + : QObject(parent) + , m_path(std::move(path)) +{ + const auto *mo = parent->metaObject(); + + if (mo == nullptr) { + qCritical() << "relay propertiesChanged failed."; + return; + } + + for (auto i = mo->propertyOffset(); i < mo->propertyCount(); ++i) { + auto prop = mo->property(i); + if (!prop.hasNotifySignal()) { + continue; + } + + auto signal = prop.notifySignal(); + auto slot = metaObject()->method(metaObject()->indexOfSlot("PropertyChanged()")); + QObject::connect(parent, signal, this, slot); + } +} + +void PropertiesForwarder::PropertyChanged() +{ + auto *sender = QObject::sender(); + auto sigIndex = QObject::senderSignalIndex(); + + const auto *mo = sender->metaObject(); + if (mo == nullptr) { + qCritical() << "PropertiesForwarder::PropertyChanged [relay propertiesChanged failed.]"; + return; + } + + auto sig = mo->property(sigIndex); + const auto *propName = sig.name(); + auto value = sig.read(sender); + + auto childs = sender->children(); + QString interface; + for (const auto &adaptor : childs) { + if (adaptor->inherits("QDBusAbstractAdaptor")) { + const auto *adaptorMo = adaptor->metaObject(); + if (adaptorMo->indexOfProperty(propName) != -1) { + interface = getDBusInterface(adaptor->metaObject()->metaType()); + break; + } + } + }; + + if (interface.isEmpty()) { + return; + } + + auto msg = QDBusMessage::createSignal(m_path, interface, "PropertiesChanged"); + msg << QString{ApplicationInterface}; + msg << QVariantMap{{QString{propName}, value}}; + msg << QStringList{}; + + ApplicationManager1DBus::instance().globalServerBus().send(msg); +} diff --git a/src/propertiesForwarder.h b/src/propertiesForwarder.h new file mode 100644 index 0000000..e095ed2 --- /dev/null +++ b/src/propertiesForwarder.h @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#ifndef PROPERTIESFORWARDER_H +#define PROPERTIESFORWARDER_H + +#include + +class PropertiesForwarder : public QObject +{ + Q_OBJECT +public: + explicit PropertiesForwarder(QString path, QObject *parent); +public Q_SLOTS: + void PropertyChanged(); + +private: + QString m_path; +}; + +#endif