From d1833c90cf9f1dce46d500203560305651856bd3 Mon Sep 17 00:00:00 2001 From: xionglinlin Date: Thu, 22 Jan 2026 10:19:05 +0800 Subject: [PATCH] fix: add MIME info change detection and reload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added file system monitoring for user mimeapps.list configuration file to detect external changes and reload MIME information automatically. The fix includes a new DBus signal to notify clients when MIME info changes, debounced file change handling, and protection against reload loops from internal writes. 1. Added MimeInfoChanged signal to DBus interface to notify clients when MIME information is updated 2. Implemented QFileSystemWatcher to monitor user's mimeapps.list file for external modifications 3. Added debounce timer (50ms) to handle rapid file change events and avoid multiple reloads 4. Added internal write flag to prevent reload loops when changes originate from the application itself 5. Created reloadMimeInfos() method to reset MIME manager and rescan all MIME information 6. Updated copyright years from 2023 to 2026 across modified files Log: Added automatic reload of MIME information when user configuration files are externally modified Influence: 1. Test that external modifications to ~/.config/mimeapps.list trigger MIME info reload 2. Verify that internal writes (setDefaultApplication/ unsetDefaultApplication) don't cause reload loops 3. Test that MimeInfoChanged signal is emitted when configuration changes 4. Verify debounce mechanism works correctly with rapid file changes 5. Test that MIME cache is properly updated after reload 6. Verify default application settings persist correctly after reload fix: 添加MIME信息变更检测和重新加载功能 添加了对用户mimeapps.list配置文件的文件系统监控,以检测外部更改并自动重 新加载MIME信息。该修复包括一个新的DBus信号用于在MIME信息变更时通知客户 端、防抖的文件变更处理以及防止内部写入导致的重载循环。 1. 在DBus接口中添加MimeInfoChanged信号,用于在MIME信息更新时通知客户端 2. 实现QFileSystemWatcher来监控用户的mimeapps.list文件的外部修改 3. 添加防抖定时器(50毫秒)以处理快速的文件变更事件,避免多次重新加载 4. 添加内部写入标志,防止应用程序自身发起更改时产生重载循环 5. 创建reloadMimeInfos()方法用于重置MIME管理器并重新扫描所有MIME信息 6. 将修改文件的版权年份从2023更新到2026 Log: 新增用户配置文件被外部修改时自动重新加载MIME信息的功能 Influence: 1. 测试外部修改~/.config/mimeapps.list文件是否会触发MIME信息重新加载 2. 验证内部写入(setDefaultApplication/unsetDefaultApplication)不会导致 重载循环 3. 测试配置变更时MimeInfoChanged信号是否正确发射 4. 验证防抖机制在快速文件变更时工作正常 5. 测试重新加载后MIME缓存是否正确更新 6. 验证默认应用程序设置在重新加载后是否正确保持 PMS: BUG-288389 --- api/dbus/org.desktopspec.MimeManager1.xml | 6 +++ src/dbus/applicationmanager1service.cpp | 12 +++-- src/dbus/applicationmanager1service.h | 3 +- src/dbus/mimemanager1service.cpp | 49 ++++++++++++++++++- src/dbus/mimemanager1service.h | 16 +++++- .../org.desktopspec.MimeManager1Adaptor.h | 4 ++ 6 files changed, 84 insertions(+), 6 deletions(-) diff --git a/api/dbus/org.desktopspec.MimeManager1.xml b/api/dbus/org.desktopspec.MimeManager1.xml index 370b3f2f..3e04beb0 100644 --- a/api/dbus/org.desktopspec.MimeManager1.xml +++ b/api/dbus/org.desktopspec.MimeManager1.xml @@ -25,5 +25,11 @@ + + + diff --git a/src/dbus/applicationmanager1service.cpp b/src/dbus/applicationmanager1service.cpp index 3c19bb1e..13802517 100644 --- a/src/dbus/applicationmanager1service.cpp +++ b/src/dbus/applicationmanager1service.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later #include "applicationadaptor.h" @@ -274,6 +274,13 @@ void ApplicationManager1Service::scanMimeInfos() noexcept } } +void ApplicationManager1Service::reloadMimeInfos() noexcept +{ + m_mimeManager->reset(); + scanMimeInfos(); + emit m_mimeManager->MimeInfoReloaded(); +} + void ApplicationManager1Service::scanApplications() noexcept { const auto &desktopFileDirs = getDesktopFileDirs(); @@ -639,8 +646,7 @@ void ApplicationManager1Service::doReloadApplications() removeOneApplication(appId); } - m_mimeManager->reset(); - scanMimeInfos(); + reloadMimeInfos(); updateAutostartStatus(); } diff --git a/src/dbus/applicationmanager1service.h b/src/dbus/applicationmanager1service.h index ac232703..326a7091 100644 --- a/src/dbus/applicationmanager1service.h +++ b/src/dbus/applicationmanager1service.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later @@ -41,6 +41,7 @@ class ApplicationManager1Service final : public QObject, protected QDBusContext [[nodiscard]] QList list() const; void initService(QDBusConnection &connection) noexcept; + void reloadMimeInfos() noexcept; QSharedPointer addApplication(DesktopFile desktopFileSource) noexcept; void removeOneApplication(const QString &appId) noexcept; void removeAllApplication() noexcept; diff --git a/src/dbus/mimemanager1service.cpp b/src/dbus/mimemanager1service.cpp index 87dabf84..78358e6a 100644 --- a/src/dbus/mimemanager1service.cpp +++ b/src/dbus/mimemanager1service.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later #include @@ -15,6 +15,21 @@ MimeManager1Service::MimeManager1Service(ApplicationManager1Service *parent) if (adaptor == nullptr or !registerObjectToDBus(this, DDEApplicationManager1MimeManager1ObjectPath, MimeManager1Interface)) { std::terminate(); } + + // 监控用户配置目录下的 mimeapps.list 文件 + connect(&m_mimeAppsWatcher, &QFileSystemWatcher::fileChanged, this, &MimeManager1Service::onMimeAppsFileChanged); + + // 添加用户配置目录下的 mimeapps.list 文件到监控 + QString userMimeAppsFile = getXDGConfigHome() + "/mimeapps.list"; + if (QFileInfo::exists(userMimeAppsFile)) { + m_mimeAppsWatcher.addPath(userMimeAppsFile); + } else { + qWarning() << "User mimeapps.list file does not exist:" << userMimeAppsFile; + } + + m_mimeAppsDebounceTimer.setSingleShot(true); + m_mimeAppsDebounceTimer.setInterval(50); + connect(&m_mimeAppsDebounceTimer, &QTimer::timeout, this, &MimeManager1Service::handleMimeAppsFileDebounced); } MimeManager1Service::~MimeManager1Service() = default; @@ -106,12 +121,15 @@ void MimeManager1Service::setDefaultApplication(const QStringMap &defaultApps) n return; } + m_internalWriteInProgress = true; for (auto it = defaultApps.constKeyValueBegin(); it != defaultApps.constKeyValueEnd(); ++it) { userConfig->setDefaultApplication(it->first, it->second); } if (!userConfig->writeToFile()) { safe_sendErrorReply(QDBusError::Failed, "set default app failed, these config will be reset after re-login."); + m_internalWriteInProgress = false; + return; } } @@ -126,12 +144,15 @@ void MimeManager1Service::unsetDefaultApplication(const QStringList &mimeTypes) return; } + m_internalWriteInProgress = true; for (const auto &mime : mimeTypes) { userConfig->unsetDefaultApplication(mime); } if (!userConfig->writeToFile()) { safe_sendErrorReply(QDBusError::Failed, "unset default app failed, these config will be reset after re-login."); + m_internalWriteInProgress = false; + return; } } @@ -156,3 +177,29 @@ void MimeManager1Service::updateMimeCache(QString dir) noexcept } } + +void MimeManager1Service::onMimeAppsFileChanged(const QString &path) +{ + if (!m_mimeAppsWatcher.files().contains(path) && QFileInfo::exists(path)) { + m_mimeAppsWatcher.addPath(path); + } + + // 如果是内部写入导致的文件变化,忽略 + if (m_internalWriteInProgress) { + m_internalWriteInProgress = false; + return; + } + + m_mimeAppsDebounceTimer.start(); +} + +void MimeManager1Service::handleMimeAppsFileDebounced() +{ + auto *parentService = qobject_cast(parent()); + if (!parentService) { + return; + } + + qInfo() << "Reloading MIME info due to external configuration change."; + parentService->reloadMimeInfos(); +} diff --git a/src/dbus/mimemanager1service.h b/src/dbus/mimemanager1service.h index 7849549c..8f942a3c 100644 --- a/src/dbus/mimemanager1service.h +++ b/src/dbus/mimemanager1service.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later @@ -8,6 +8,9 @@ #include #include #include +#include +#include + #include "global.h" #include "applicationmimeinfo.h" @@ -32,9 +35,20 @@ public Q_SLOTS: void setDefaultApplication(const QStringMap &defaultApps) noexcept; void unsetDefaultApplication(const QStringList &mimeTypes) noexcept; +Q_SIGNALS: + void MimeInfoReloaded(); + +private Q_SLOTS: + void onMimeAppsFileChanged(const QString &path); + void handleMimeAppsFileDebounced(); + private: QMimeDatabase m_database; std::vector m_infos; + QFileSystemWatcher m_mimeAppsWatcher; + // 内部写入标志,用于避免触发外部修改的处理 + bool m_internalWriteInProgress{false}; + QTimer m_mimeAppsDebounceTimer; }; #endif diff --git a/toolGenerate/qdbusxml2cpp/org.desktopspec.MimeManager1Adaptor.h b/toolGenerate/qdbusxml2cpp/org.desktopspec.MimeManager1Adaptor.h index 80f64f2d..3a620434 100644 --- a/toolGenerate/qdbusxml2cpp/org.desktopspec.MimeManager1Adaptor.h +++ b/toolGenerate/qdbusxml2cpp/org.desktopspec.MimeManager1Adaptor.h @@ -51,6 +51,9 @@ class MimeManager1Adaptor: public QDBusAbstractAdaptor " \n" " \n" " \n" +" \n" +" \n" +" \n" " \n" "") public: @@ -64,6 +67,7 @@ public Q_SLOTS: // METHODS void setDefaultApplication(const QStringMap &defaultApps); void unsetDefaultApplication(const QStringList &mimeTypes); Q_SIGNALS: // SIGNALS + void MimeInfoReloaded(); }; #endif