diff --git a/applets/dde-apps/CMakeLists.txt b/applets/dde-apps/CMakeLists.txt index e21172bd5..bf67ebc8a 100644 --- a/applets/dde-apps/CMakeLists.txt +++ b/applets/dde-apps/CMakeLists.txt @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +# SPDX-FileCopyrightText: 2024 - 2026 UnionTech Software Technology Co., Ltd. # # SPDX-License-Identifier: GPL-3.0-or-later @@ -59,7 +59,6 @@ add_library(dde-apps SHARED ${DBUS_INTERFACES} target_link_libraries(dde-apps PRIVATE dde-shell-frame - Qt${QT_VERSION_MAJOR}::Concurrent yaml-cpp ) diff --git a/applets/dde-apps/amappitem.cpp b/applets/dde-apps/amappitem.cpp index 17eb7cb3a..5e658e48b 100644 --- a/applets/dde-apps/amappitem.cpp +++ b/applets/dde-apps/amappitem.cpp @@ -14,6 +14,8 @@ namespace apps { // AM static string static const QString AM_DBUS_SERVICE = "org.desktopspec.ApplicationManager1"; +static const QString AM_APPLICATION_INTERFACE = "org.desktopspec.ApplicationManager1.Application"; +static const QString DBUS_PROPERTIES_INTERFACE = "org.freedesktop.DBus.Properties"; static const QString DESKTOP_ENTRY_ICON_KEY = "Desktop Entry"; static const QString DEFAULT_KEY = "default"; static QString locale = QLocale::system().name(); @@ -22,6 +24,13 @@ AMAppItem::AMAppItem(const QDBusObjectPath &path, QObject *parent) : Application(AM_DBUS_SERVICE, path.path(), QDBusConnection::sessionBus(), parent) , AppItem(DUtil::unescapeFromObjectPath(path.path().split('/').last()), AppItemModel::AppItemType) { + QDBusConnection::sessionBus().connect(AM_DBUS_SERVICE, + path.path(), + DBUS_PROPERTIES_INTERFACE, + QStringLiteral("PropertiesChanged"), + QStringLiteral("sa{sv}as"), + this, + SLOT(onPropertyChanged(const QDBusMessage &))); } AMAppItem::AMAppItem(const QDBusObjectPath &path, const ObjectInterfaceMap &source, QObject *parent) @@ -34,6 +43,8 @@ AMAppItem::AMAppItem(const QDBusObjectPath &path, const ObjectInterfaceMap &sour auto name = getLocaleOrDefaultValue(qdbus_cast(appInfo.value(u8"Name")), locale, DEFAULT_KEY); auto genericName = getLocaleOrDefaultValue(qdbus_cast(appInfo.value(u8"GenericName")), locale, DEFAULT_KEY); auto xDeepinVendor = appInfo.value(u8"X_Deepin_Vendor").toString(); + AppItem::setGenericName(genericName); + AppItem::setVendor(xDeepinVendor); if (QStringLiteral("deepin") == xDeepinVendor && !genericName.isEmpty()) { AppItem::setAppName(genericName); @@ -63,7 +74,7 @@ AMAppItem::AMAppItem(const QDBusObjectPath &path, const ObjectInterfaceMap &sour auto autoStart = appInfo.value(u8"AutoStart").toBool(); AppItem::setAutoStart(autoStart); - auto isOnDesktop = appInfo.value(u8"OnDesktop").toBool(); + auto isOnDesktop = appInfo.value(u8"isOnDesktop").toBool(); AppItem::setOnDesktop(isOnDesktop); PropMap actionName; @@ -127,42 +138,87 @@ QString AMAppItem::getLocaleOrDefaultValue(const QStringMap &value, const QStrin void AMAppItem::onPropertyChanged(const QDBusMessage &msg) { - QList arguments = msg.arguments(); - if (3 != arguments.count()) + const QList arguments = msg.arguments(); + if (arguments.count() != 3) return; - QString interfaceName = msg.arguments().at(0).toString(); - if (interfaceName != QStringLiteral("org.desktopspec.ApplicationManager1.Application")) + if (arguments.at(0).toString() != AM_APPLICATION_INTERFACE) return; - // AM send changed signal together - auto name = getLocaleOrDefaultValue(Application::name(), locale, DEFAULT_KEY); - auto genericName = getLocaleOrDefaultValue(Application::genericName(), locale, DEFAULT_KEY); - auto xDeepinVendor = Application::x_Deepin_Vendor(); - if (QStringLiteral("deepin") == xDeepinVendor && !genericName.isEmpty()) { - AppItem::setAppName(genericName); - } else { - AppItem::setAppName(name); + QVariantMap changedProperties = qdbus_cast(arguments.at(1)); + + const auto value = [&changedProperties](QLatin1StringView name) { + return changedProperties.value(name); + }; + const auto contains = [&changedProperties](QLatin1StringView name) { + return changedProperties.contains(name); + }; + + if (contains(QLatin1String("Name")) || contains(QLatin1String("GenericName")) + || contains(QLatin1String("X_Deepin_Vendor"))) { + const QString name = getLocaleOrDefaultValue( + contains(QLatin1String("Name")) + ? qdbus_cast(value(QLatin1String("Name"))) + : Application::name(), + locale, + DEFAULT_KEY); + const QString genericName = getLocaleOrDefaultValue( + contains(QLatin1String("GenericName")) + ? qdbus_cast(value(QLatin1String("GenericName"))) + : Application::genericName(), + locale, + DEFAULT_KEY); + const QString vendor = contains(QLatin1String("X_Deepin_Vendor")) + ? value(QLatin1String("X_Deepin_Vendor")).toString() + : Application::x_Deepin_Vendor(); + AppItem::setGenericName(genericName); + AppItem::setVendor(vendor); + AppItem::setAppName(vendor == QLatin1String("deepin") && !genericName.isEmpty() ? genericName : name); } - auto iconName = Application::icons().value(DESKTOP_ENTRY_ICON_KEY); - AppItem::setAppIconName(iconName); - - AppItem::setNoDisPlay(Application::noDisplay()); - AppItem::setDDECategories(AppItemModel::DDECategories(CategoryUtils::parseBestMatchedCategory(Application::categories()))); - AppItem::setLastLaunchedTime(Application::lastLaunchedTime()); - AppItem::setInstalledTime(Application::installedTime()); - AppItem::setStartupWMclass(Application::startupWMClass()); - AppItem::setAutoStart(Application::autoStart()); - AppItem::setOnDesktop(Application::isOnDesktop()); - AppItem::setXLingLong(Application::x_linglong()); - AppItem::setId(Application::iD()); - AppItem::setXCreatedBy(Application::x_CreatedBy()); - AppItem::setExecs(Application::execs()); - - auto actions = Application::actions(); - auto actionName = Application::actionName(); - updateActions(actions, actionName); + if (contains(QLatin1String("Icons"))) { + const auto icons = qdbus_cast(value(QLatin1String("Icons"))); + AppItem::setAppIconName(icons.value(DESKTOP_ENTRY_ICON_KEY)); + } + if (contains(QLatin1String("NoDisplay"))) + AppItem::setNoDisPlay(value(QLatin1String("NoDisplay")).toBool()); + if (contains(QLatin1String("Categories"))) { + const auto categories = value(QLatin1String("Categories")).toStringList(); + AppItem::setDDECategories(AppItemModel::DDECategories(CategoryUtils::parseBestMatchedCategory(categories))); + AppItem::setCategories(categories); + } + if (contains(QLatin1String("LastLaunchedTime"))) + AppItem::setLastLaunchedTime(value(QLatin1String("LastLaunchedTime")).toULongLong()); + if (contains(QLatin1String("LaunchedTimes"))) + AppItem::setData(value(QLatin1String("LaunchedTimes")).toULongLong(), AppItemModel::LaunchedTimesRole); + if (contains(QLatin1String("InstalledTime"))) + AppItem::setInstalledTime(value(QLatin1String("InstalledTime")).toULongLong()); + if (contains(QLatin1String("StartupWMClass"))) + AppItem::setStartupWMclass(value(QLatin1String("StartupWMClass")).toString()); + if (contains(QLatin1String("AutoStart"))) + AppItem::setAutoStart(value(QLatin1String("AutoStart")).toBool()); + if (contains(QLatin1String("isOnDesktop"))) + AppItem::setOnDesktop(value(QLatin1String("isOnDesktop")).toBool()); + if (contains(QLatin1String("X_linglong"))) + AppItem::setXLingLong(value(QLatin1String("X_linglong")).toBool()); + if (contains(QLatin1String("ID"))) + AppItem::setId(value(QLatin1String("ID")).toString()); + if (contains(QLatin1String("X_CreatedBy"))) + AppItem::setXCreatedBy(value(QLatin1String("X_CreatedBy")).toString()); + if (contains(QLatin1String("Execs"))) + AppItem::setExecs(qdbus_cast(value(QLatin1String("Execs")))); + if (contains(QLatin1String("DesktopSourcePath"))) + AppItem::setDesktopSourcePath(value(QLatin1String("DesktopSourcePath")).toString()); + + if (contains(QLatin1String("Actions")) || contains(QLatin1String("ActionName"))) { + const QStringList actions = contains(QLatin1String("Actions")) + ? value(QLatin1String("Actions")).toStringList() + : Application::actions(); + const PropMap actionNames = contains(QLatin1String("ActionName")) + ? qdbus_cast(value(QLatin1String("ActionName"))) + : Application::actionName(); + updateActions(actions, actionNames); + } } void AMAppItem::updateActions(const QStringList &actions, const PropMap &actionName) @@ -175,8 +231,6 @@ void AMAppItem::updateActions(const QStringList &actions, const PropMap &actionN actionObject.insert(QStringLiteral("name"), getLocaleOrDefaultValue(localeNames, locale, DEFAULT_KEY)); actionsArray.append(actionObject); } - if (actions.size() > 0) { - AppItem::setActions(QJsonDocument(actionsArray).toJson()); - } + AppItem::setActions(actions.isEmpty() ? QString() : QJsonDocument(actionsArray).toJson()); } } diff --git a/applets/dde-apps/amappitemmodel.cpp b/applets/dde-apps/amappitemmodel.cpp index 38291a6d9..5801dea82 100644 --- a/applets/dde-apps/amappitemmodel.cpp +++ b/applets/dde-apps/amappitemmodel.cpp @@ -8,8 +8,6 @@ #include "objectmanager1interface.h" #include -#include -#include Q_LOGGING_CATEGORY(appsLog, "org.deepin.dde.shell.dde-apps.amappitemmodel") @@ -50,25 +48,29 @@ AMAppItemModel::AMAppItemModel(QObject *parent) removeRow(res.first().row()); }); - // load static desktop info from am asynchronously - auto reply = m_manager->GetManagedObjects(); - auto *watcher = new QDBusPendingCallWatcher(reply, this); + auto watcher = new QDBusPendingCallWatcher(m_manager->GetManagedObjects(), this); connect(watcher, &QDBusPendingCallWatcher::finished, this, [this, watcher]() { - watcher->deleteLater(); QDBusPendingReply reply = *watcher; + watcher->deleteLater(); if (reply.isError()) { - qCWarning(appsLog()) << "Failed to get managed objects:" << reply.error().message(); + qCWarning(appsLog) << "Failed to load applications from ApplicationManager:" << reply.error(); return; } - auto apps = reply.value(); - for (auto app = apps.cbegin(); app != apps.cend(); app++) { - auto path = app.key(); - if (!path.path().isEmpty()) { - auto c = new AMAppItem(path, app.value()); - appendRow(c); - } + + const auto apps = reply.value(); + for (auto app = apps.cbegin(); app != apps.cend(); ++app) { + const auto path = app.key(); + if (path.path().isEmpty()) + continue; + + const auto desktopId = DUtil::unescapeFromObjectPath(path.path().split('/').last()); + if (!match(index(0, 0), AppItemModel::DesktopIdRole, desktopId, 1, Qt::MatchExactly).isEmpty()) + continue; + appendRow(new AMAppItem(path, app.value())); } - setProperty("ready", true); + + m_ready = true; + Q_EMIT readyChanged(true); qCDebug(appsLog) << "AMAppItemModel is now ready with apps counts:" << rowCount(); }); } diff --git a/applets/dde-apps/appitem.cpp b/applets/dde-apps/appitem.cpp index 9ef29c124..9dd1a6803 100644 --- a/applets/dde-apps/appitem.cpp +++ b/applets/dde-apps/appitem.cpp @@ -230,4 +230,24 @@ void AppItem::setDesktopSourcePath(const QString &desktopSourcePath) { setData(desktopSourcePath, AppItemModel::DesktopSourcePathRole); } -} \ No newline at end of file + +QString AppItem::vendor() const +{ + return data(AppItemModel::VendorRole).toString(); +} + +void AppItem::setVendor(const QString &vendor) +{ + setData(vendor, AppItemModel::VendorRole); +} + +QString AppItem::genericName() const +{ + return data(AppItemModel::GenericNameRole).toString(); +} + +void AppItem::setGenericName(const QString &genericName) +{ + setData(genericName, AppItemModel::GenericNameRole); +} +} diff --git a/applets/dde-apps/appitem.h b/applets/dde-apps/appitem.h index cdd48b1d0..4a1ac5981 100644 --- a/applets/dde-apps/appitem.h +++ b/applets/dde-apps/appitem.h @@ -78,5 +78,11 @@ class AppItem : public QStandardItem QString desktopSourcePath() const; void setDesktopSourcePath(const QString &desktopSourcePath); + + QString vendor() const; + void setVendor(const QString &vendor); + + QString genericName() const; + void setGenericName(const QString &genericName); }; } diff --git a/applets/dde-apps/appitemmodel.cpp b/applets/dde-apps/appitemmodel.cpp index d26c41c9a..e208f4d7c 100644 --- a/applets/dde-apps/appitemmodel.cpp +++ b/applets/dde-apps/appitemmodel.cpp @@ -32,6 +32,8 @@ QHash AppItemModel::roleNames() const {AppItemModel::IdRole, QByteArrayLiteral("id")}, {AppItemModel::XCreatedByRole, QByteArrayLiteral("xCreatedBy")}, {AppItemModel::ExecsRole, QByteArrayLiteral("execs")}, - {AppItemModel::DesktopSourcePathRole, QByteArrayLiteral("desktopSourcePath")}}; + {AppItemModel::DesktopSourcePathRole, QByteArrayLiteral("desktopSourcePath")}, + {AppItemModel::VendorRole, QByteArrayLiteral("vendor")}, + {AppItemModel::GenericNameRole, QByteArrayLiteral("genericName")}}; } } diff --git a/applets/dde-apps/appitemmodel.h b/applets/dde-apps/appitemmodel.h index ef3d3ace1..356b63c92 100644 --- a/applets/dde-apps/appitemmodel.h +++ b/applets/dde-apps/appitemmodel.h @@ -10,6 +10,8 @@ namespace apps { class AppItemModel : public QStandardItemModel { + Q_OBJECT + public: enum Roles { DesktopIdRole = AppGroupManager::ExtendRole, @@ -32,6 +34,8 @@ class AppItemModel : public QStandardItemModel ExecsRole, CategoriesRole, DesktopSourcePathRole, + VendorRole, + GenericNameRole, }; Q_ENUM(Roles) diff --git a/applets/dde-apps/appsapplet.cpp b/applets/dde-apps/appsapplet.cpp index aeaf6bfcf..7404e3e74 100644 --- a/applets/dde-apps/appsapplet.cpp +++ b/applets/dde-apps/appsapplet.cpp @@ -1,14 +1,14 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2024 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later #include "appsapplet.h" #include "amappitemmodel.h" #include "appgroupmanager.h" +#include "appitemmodel.h" #include "pluginfactory.h" -#include -#include +#include namespace apps { @@ -20,16 +20,6 @@ AppsApplet::AppsApplet(QObject *parent) connect(m_appModel, &AMAppItemModel::readyChanged, this, &AppsApplet::appModelReadyChanged); } -AppsApplet::~AppsApplet() -{ - -} - -bool AppsApplet::load() -{ - return true; -} - QAbstractItemModel *AppsApplet::groupModel() const { return m_groupModel; @@ -45,6 +35,15 @@ bool AppsApplet::appModelReady() const return m_appModel->ready(); } +QVariantMap AppsApplet::ddeCategories() const +{ + QVariantMap categories; + const QMetaEnum metaEnum = QMetaEnum::fromType(); + for (int i = 0; i < metaEnum.keyCount(); ++i) + categories.insert(QString::fromLatin1(metaEnum.key(i)), metaEnum.value(i)); + return categories; +} + D_APPLET_CLASS(AppsApplet) } diff --git a/applets/dde-apps/appsapplet.h b/applets/dde-apps/appsapplet.h index 6c81d73ee..65d08f4d4 100644 --- a/applets/dde-apps/appsapplet.h +++ b/applets/dde-apps/appsapplet.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2024 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -7,36 +7,34 @@ #include "applet.h" #include "dsglobal.h" -#include +#include +#include DS_USE_NAMESPACE namespace apps { class AMAppItemModel; -class AppItem; class AppsApplet : public DApplet { Q_OBJECT Q_PROPERTY(QAbstractItemModel *appModel READ appModel CONSTANT FINAL) Q_PROPERTY(bool appModelReady READ appModelReady NOTIFY appModelReadyChanged FINAL) Q_PROPERTY(QAbstractItemModel *appGroupModel READ groupModel CONSTANT FINAL) + Q_PROPERTY(QVariantMap ddeCategories READ ddeCategories CONSTANT FINAL) public: explicit AppsApplet(QObject *parent = nullptr); - ~AppsApplet(); - - bool load() override; QAbstractItemModel *appModel() const; QAbstractItemModel *groupModel() const; bool appModelReady() const; + QVariantMap ddeCategories() const; signals: void appModelReadyChanged(bool ready); private: - bool m_appModelReady; AMAppItemModel *m_appModel; QAbstractItemModel *m_groupModel; };