From 12ea80ee309fe1795c911722277607f105c940e9 Mon Sep 17 00:00:00 2001 From: PiliLily Date: Sat, 8 Aug 2026 11:31:32 +0000 Subject: [PATCH 1/2] fix(widget): invalidate metadata cache on search path change New widget search paths have the highest priority, so cached metadata can no longer be trusted after a path is added. Clear the metadata cache while holding the existing lock. Signed-off-by: PiliLily --- framework/widget/widget-loader.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/framework/widget/widget-loader.cpp b/framework/widget/widget-loader.cpp index 3fc7973..eb4f51d 100644 --- a/framework/widget/widget-loader.cpp +++ b/framework/widget/widget-loader.cpp @@ -68,6 +68,7 @@ public: if (!widgetSearchPath.contains(path)) { // 添加的自定义搜索路径优先级最高 widgetSearchPath.prepend(path); + m_metadataCache.clear(); } } -- Gitee From 8cb245158140154c9480f23232f70528605e5568 Mon Sep 17 00:00:00 2001 From: PiliLily Date: Sat, 8 Aug 2026 11:31:53 +0000 Subject: [PATCH 2/2] test(widget): cover search path priority cache invalidation Load a widget from a lower-priority directory, add a higher-priority directory with the same ID, and verify that subsequent metadata loads use the new package. Signed-off-by: PiliLily --- framework/autotest/test-widget-loader.cpp | 35 +++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/framework/autotest/test-widget-loader.cpp b/framework/autotest/test-widget-loader.cpp index d50862e..aaf6cdd 100644 --- a/framework/autotest/test-widget-loader.cpp +++ b/framework/autotest/test-widget-loader.cpp @@ -14,14 +14,15 @@ using namespace UkuiQuick; namespace { QString createWidgetPackage(const QString &basePath, const QString &id, WidgetMetadata::Hosts hosts, - const QStringList &applicationIds = {}, bool isContainer = false) + const QStringList &applicationIds = {}, bool isContainer = false, + const QString &name = QString()) { const QString root = QDir(basePath).filePath(id); QDir().mkpath(root); QJsonObject object{ {QStringLiteral("Id"), id}, - {QStringLiteral("Name"), id}, + {QStringLiteral("Name"), name.isEmpty() ? id : name}, {QStringLiteral("ShowIn"), hosts.testFlag(WidgetMetadata::All) ? QStringLiteral("All") : QString(hosts.testFlag(WidgetMetadata::Panel) ? QStringLiteral("Panel") : QStringLiteral("SideBar"))}, {QStringLiteral("Contents"), QJsonObject{ @@ -57,6 +58,7 @@ class widget_loader_test : public QObject private slots: void metadataAndWidgetCanBeLoadedFromCustomPath(); + void searchPathPriorityInvalidatesMetadataCache(); void widgetsAreFilteredByHostAndApplication(); void widgetsMetadataKeepsUniqueEntries(); }; @@ -84,6 +86,35 @@ void widget_loader_test::metadataAndWidgetCanBeLoadedFromCustomPath() QVERIFY(qobject_cast(container.get()) != nullptr); } +void widget_loader_test::searchPathPriorityInvalidatesMetadataCache() +{ + QTemporaryDir lowerPriorityDir; + QTemporaryDir higherPriorityDir; + QVERIFY(lowerPriorityDir.isValid()); + QVERIFY(higherPriorityDir.isValid()); + + const QString id = QStringLiteral("priority-widget"); + createWidgetPackage(lowerPriorityDir.path(), id, WidgetMetadata::All, {}, false, + QStringLiteral("Lower priority")); + createWidgetPackage(higherPriorityDir.path(), id, WidgetMetadata::All, {}, false, + QStringLiteral("Higher priority")); + + WidgetLoader loader; + loader.addWidgetSearchPath(lowerPriorityDir.path()); + + const WidgetMetadata initialMetadata = loader.loadMetadata(id); + QVERIFY(initialMetadata.isValid()); + QCOMPARE(initialMetadata.name(), QStringLiteral("Lower priority")); + + loader.addWidgetSearchPath(higherPriorityDir.path()); + + const WidgetMetadata updatedMetadata = loader.loadMetadata(id); + QVERIFY(updatedMetadata.isValid()); + QCOMPARE(updatedMetadata.name(), QStringLiteral("Higher priority")); + QCOMPARE(updatedMetadata.root().absolutePath(), + QDir(higherPriorityDir.path()).absoluteFilePath(id)); +} + void widget_loader_test::widgetsAreFilteredByHostAndApplication() { QTemporaryDir dir; -- Gitee