From b6b908b52aafdedef0fb0f9f2e35eda413cff42d Mon Sep 17 00:00:00 2001 From: wjyrich Date: Wed, 23 Jul 2025 18:07:02 +0800 Subject: [PATCH] fix: improve symlink resolution and Chrome PWA handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Added recursive symlink resolution with loop detection for desktop files 2. Implemented special handling for Chrome PWA applications 3. Added cleanup of associated icon files when uninstalling Chrome PWAs 4. Improved error handling and debug logging 5. Added QSet include for tracking visited symlink paths The changes address two main issues: 1. Symlinks to desktop files weren't being properly resolved, which could cause uninstallation failures 2. Chrome Progressive Web Apps created special desktop entries that needed custom uninstallation logic The new symlink resolution handles nested symlinks safely while preventing infinite loops, and the Chrome PWA handling ensures proper cleanup of both desktop entries and their icons. fix: 改进符号链接解析和 Chrome PWA 处理 1. 为桌面文件添加了带循环检测的递归符号链接解析 2. 实现了对 Chrome PWA 应用的特殊处理 3. 卸载 Chrome PWA 时添加了关联图标文件的清理 4. 改进了错误处理和调试日志 5. 添加了 QSet 包含用于跟踪访问过的符号链接路径 这些更改解决了两个主要问题: 1. 桌面文件的符号链接未被正确解析,可能导致卸载失败 2. Chrome 渐进式网页应用创建的特殊桌面条目需要自定义卸载逻辑 新的符号链接解析功能安全地处理嵌套符号链接同时防止无限循环,而 Chrome PWA 处理确保正确清理桌面条目及其关联图标 Pms: BUG-315791 --- dbus/launcher1compat.cpp | 73 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/dbus/launcher1compat.cpp b/dbus/launcher1compat.cpp index 9e02e67..1c82bc0 100644 --- a/dbus/launcher1compat.cpp +++ b/dbus/launcher1compat.cpp @@ -10,6 +10,9 @@ #include #include // this is the adapter of daemon.Launcher1 +// Qt includes +#include + // PackageKit-Qt #include @@ -166,7 +169,41 @@ void Launcher1Compat::RequestUninstall(const QString & desktop, bool skipPreinst return; } - QString desktopFilePath(desktopFileInfo.isSymLink() ? desktopFileInfo.symLinkTarget() : desktop); + QString desktopFilePath; + if (desktopFileInfo.isSymLink()) { + // Recursively resolve symlinks to get the final target + QString currentPath = desktop; + QSet visitedPaths; // Prevent infinite loops + + while (true) { + QFileInfo currentInfo(currentPath); + if (!currentInfo.isSymLink()) { + // Found the final target + desktopFilePath = currentPath; + break; + } + + QString symLinkTarget = currentInfo.symLinkTarget(); + if (!QFile::exists(symLinkTarget)) { + qDebug() << "Symlink target" << symLinkTarget << "does not exist, using original path" << desktop; + desktopFilePath = desktop; + break; + } + + if (visitedPaths.contains(currentPath)) { + qDebug() << "Circular symlink detected, using original path" << desktop; + desktopFilePath = desktop; + break; + } + + visitedPaths.insert(currentPath); + currentPath = symLinkTarget; + } + + qDebug() << "Resolved symlink chain from" << desktop << "to" << desktopFilePath; + } else { + desktopFilePath = desktop; + } DDesktopEntry desktopEntry(desktopFilePath); if (desktopEntry.status() != DDesktopEntry::NoError) { qDebug() << "Desktop file" << desktop << "is invalid."; @@ -221,6 +258,40 @@ void Launcher1Compat::RequestUninstall(const QString & desktop, bool skipPreinst sendNotification(desktopEntry.ddeDisplayName(), true); } // TODO: check if it's a flatpak or snap bundle and do the uninstallation? + // 单独处理chrome 的快捷浏览器创建卸载 + } else if (desktopFilePath.contains("/.local/share/applications/") && + (desktopFilePath.contains("chrome-") || + desktopEntry.stringValue("Exec").contains("google-chrome"))) { + // Handle Chrome PWA apps specifically + qDebug() << "Detected Chrome PWA application:" << desktopFilePath; + + bool success = true; + QString iconPath = desktopEntry.stringValue("Icon"); + + // Remove the desktop file + QFile desktopFile(desktopFilePath); + if (!desktopFile.remove()) { + qDebug() << "Failed to remove Chrome PWA desktop file:" << desktopFilePath; + success = false; + } + + // Remove the associated icon if it's a file path + if (success && !iconPath.isEmpty() && QFile::exists(iconPath)) { + QFile iconFile(iconPath); + if (!iconFile.remove()) { + qDebug() << "Warning: Failed to remove Chrome PWA icon file:" << iconPath; + } + } + + if (success) { + QFileInfo fileInfo(desktopFilePath); + postUninstallCleanUp(fileInfo.fileName()); + emit UninstallSuccess(desktopFilePath); + sendNotification(desktopEntry.ddeDisplayName(), true); + } else { + emit UninstallFailed(desktopFilePath, QString("Failed to remove Chrome PWA application")); + sendNotification(desktopEntry.ddeDisplayName(), false); + } } else { m_packageDisplayName = desktopEntry.ddeDisplayName();