From 3a65a3f427122508d3cff12b31f0df4b8533bfd9 Mon Sep 17 00:00:00 2001 From: zhangkun Date: Tue, 20 May 2025 17:45:00 +0800 Subject: [PATCH] feat: improve the logic of obtaining icons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Added support for fetching icons from ApplicationManager DBus interface 2. Special handling for Linglong containerized apps where executable path isn't accessible 3. Added fallback to default icon when theme icon not available 4. Implemented DBus communication to get app icons from desktop entry 5. Added necessary header includes and DBus constants The changes were necessary because: 1. Linglong apps run in containers making their executable paths inaccessible 2. Previous implementation couldn't properly display icons for containerized apps 3. New solution uses ApplicationManager DBus interface as reliable icon source 4. Maintains backward compatibility with regular applications feat: 改进玲珑应用的图标处理 1. 添加从ApplicationManager DBus接口获取图标支持 2. 对玲珑容器化应用特殊处理,其可执行路径无法访问 3. 添加主题图标不可用时的默认图标回退机制 4. 实现通过DBus从桌面条目获取应用图标 5. 添加必要的头文件包含和DBus常量 修改原因: 1. 玲珑应用运行在容器中导致其可执行路径无法访问 2. 原实现无法正确显示容器化应用的图标 3. 新方案使用ApplicationManager DBus接口作为可靠图标来源 4. 保持对常规应用的向后兼容性 pms: BUG-315995 pms: BUG-281765 --- src/widgets/inhibitwarnview.cpp | 49 +++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/src/widgets/inhibitwarnview.cpp b/src/widgets/inhibitwarnview.cpp index 73455c49..16396e42 100644 --- a/src/widgets/inhibitwarnview.cpp +++ b/src/widgets/inhibitwarnview.cpp @@ -10,10 +10,22 @@ #include #include +#ifdef ENABLE_DSS_SNIPE +#include +#include +#include +#endif + #include DWIDGET_USE_NAMESPACE +#ifdef ENABLE_DSS_SNIPE +#define AMDBUS_SERVICE "org.desktopspec.ApplicationManager1" +#define AMDBUS_PATH_APP_PREFIX "/org/desktopspec/ApplicationManager1" +#define AMDBUS_APP_INTERFACE "org.desktopspec.ApplicationManager1.Application" +#endif + const int ButtonWidth = 200; const int ButtonHeight = 64; const int FIXED_INHIBITOR_WIDTH = 328; @@ -86,16 +98,41 @@ void InhibitWarnView::setInhibitorList(const QList &list) for (const InhibitorData &inhibitor : list) { QIcon icon; - if (inhibitor.icon.isEmpty() && inhibitor.pid) { + if (inhibitor.icon.isEmpty()) { + QString iconName; +#ifdef ENABLE_DSS_SNIPE + do { + const auto appId = Dtk::Core::DSGApplication::getId(inhibitor.pid); + if (appId.isEmpty()) + break; + const auto amDBusAppPath = QString("%1/%2").arg(AMDBUS_PATH_APP_PREFIX, DUtil::escapeToObjectPath(appId)); + QDBusReply reply = DDBusSender() + .service(AMDBUS_SERVICE) + .path(amDBusAppPath) + .interface(AMDBUS_APP_INTERFACE) + .property("Icons") + .get(); + if (reply.isValid()) { + auto ret = qdbus_cast>(reply.value().variant()); + iconName = ret.value("Desktop Entry"); + } else { + qCWarning(DDE_SHELL) << "Get icon error:" << reply.error().message(); + break; + } + } while(0); +#endif + + if (iconName.isEmpty() && inhibitor.pid) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - QFileInfo executable_info(QFile::symLinkTarget(QString("/proc/%1/exe").arg(inhibitor.pid))); + QFileInfo executable_info(QFile::symLinkTarget(QString("/proc/%1/exe").arg(inhibitor.pid))); #else - QFileInfo executable_info(QFile::readLink(QString("/proc/%1/exe").arg(inhibitor.pid))); + QFileInfo executable_info(QFile::readLink(QString("/proc/%1/exe").arg(inhibitor.pid))); #endif - - if (executable_info.exists()) { - icon = QIcon::fromTheme(executable_info.fileName()); + // 玲珑应用的exe指向的路径是容器内的路径,在容器外无法访问,因此不能判断文件是否存在 + QString iconName = executable_info.fileName(); } + + icon = QIcon::fromTheme(iconName); } else { icon = QIcon::fromTheme(inhibitor.icon, QIcon::fromTheme("application-x-desktop")); }