Repository navigation
Conversation
1. Introduce FolderContentRegistry singleton for resolving folder content references 2. Add FolderPresentation base class for pinned folder icon metadata (title, preview icons, icon/content URLs) 3. Define FolderContentProvider interface for dynamically loaded plugins 4. Implement reference encoding/decoding using base64url-encoded provider IDs 5. Support provider discovery via plugin directories, DDE_SHELL_PLUGIN_PATH, and library paths 6. Add normalizeReference and referenceWithId helpers for id validation and rebuild 7. Preserve pins with fallback presentation when a provider is unavailable 8. Register new source/header files in CMakeLists.txt Log: Added folder content provider plugin system for custom folder pins on the taskbar/dock Influence: 1. Test reference encoding and decoding with valid and invalid inputs 2. Verify provider loading from all search paths (plugins dir, install dir, DDE_SHELL_PLUGIN_PATH, library paths) 3. Test normalizeReference behavior with available and missing providers 4. Verify fallback FolderPresentation is created when provider is missing 5. Test that pins are retained when provider is temporarily unavailable 6. Validate base64url ID encoding handles special characters and empty IDs correctly 7. Confirm source pattern validation rejects malformed references 8. Test referenceWithId rebuilds references while preserving source feat: 添加文件夹内容提供者注册表 1. 引入 FolderContentRegistry 单例,用于解析文件夹内容引用 2. 添加 FolderPresentation 基类,用于固定文件夹图标的元数据(标题、预览 图标、图标/内容 URL) 3. 定义 FolderContentProvider 接口,用于动态加载插件 4. 实现基于 base64url 编码提供者 ID 的引用编解码 5. 支持通过插件目录、DDE_SHELL_PLUGIN_PATH 和库路径发现提供者 6. 添加 normalizeReference 和 referenceWithId 辅助方法,用于 ID 校验和 重建 7. 当提供者不可用时,通过回退展示保留固定项 8. 在 CMakeLists.txt 中注册新的源文件和头文件 Log: 新增文件夹内容提供者插件系统,支持任务栏/停靠栏自定义文件夹固定项 Influence: 1. 使用有效和无效输入测试引用编解码 2. 验证从所有搜索路径(插件目录、安装目录、DDE_SHELL_PLUGIN_PATH、库路 径)加载提供者 3. 测试在提供者可用和缺失情况下 normalizeReference 的行为 4. 验证提供者缺失时创建回退的 FolderPresentation 5. 测试提供者临时不可用时固定项是否保留 6. 验证 base64url ID 编码正确处理特殊字符和空 ID 7. 确认 source 模式校验拒绝格式错误的引用 8. 测试 referenceWithId 在保留 source 的同时重建引用 PMS: TASK-397253
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: wjyrich The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Reviewer's GuideIntroduces a singleton folder-content registry and plugin contract that encodes and validates folder references, discovers and caches providers across configured plugin paths, normalizes provider IDs, and preserves unavailable pins through fallback presentations. Sequence diagram for folder reference creation and presentation resolutionsequenceDiagram
participant Client
participant Registry as FolderContentRegistry
participant Provider as FolderContentProvider
participant Presentation as FolderPresentation
Client->>Registry: normalizeReference(reference)
Registry->>Registry: decode(reference, source, id)
Registry->>Registry: provider(source)
Registry->>Provider: normalizeId(id)
Provider-->>Registry: normalizedId
Registry-->>Client: reference(source, normalizedId)
Client->>Registry: create(reference, parent)
Registry->>Registry: decode(reference, source, id)
Registry->>Provider: create(id, parent)
Provider-->>Registry: FolderPresentation
Registry-->>Client: FolderPresentation
Sequence diagram for provider discovery and unavailable pin fallbacksequenceDiagram
participant Registry as FolderContentRegistry
participant PluginLoader as QPluginLoader
participant Provider as FolderContentProvider
participant Pin as FolderPresentation
Registry->>Registry: provider(source)
Registry->>PluginLoader: instance()
PluginLoader-->>Registry: plugin object
Registry->>Provider: qobject_cast<FolderContentProvider>()
Provider-->>Registry: provider instance
Registry->>Provider: create(id, parent)
Provider-->>Registry: FolderPresentation
alt provider unavailable
Registry->>Pin: new FolderPresentation(parent)
Pin-->>Registry: fallback presentation
end
Flow diagram for folder reference validation and normalizationflowchart TD
A[Folder reference] --> B[decode]
B -->|invalid format or encoding| X[Return empty or false]
B -->|valid source and non-empty ID| C["provider(source)"]
C -->|available| D[normalizeId]
D -->|normalized ID| E["reference(source, normalized ID)"]
E --> F[Normalized reference]
C -->|unavailable| X
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 2 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="frame/foldercontent.cpp" line_range="22" />
<code_context>
+
+QString FolderContentRegistry::reference(const QString &source, const QString &id)
+{
+ return QStringLiteral("folder/%1/%2").arg(source, QString::fromLatin1(id.toUtf8().toBase64(
+ QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals)));
+}
</code_context>
<issue_to_address>
**Generated folder reference is unusable**
When a caller passes an empty ID or a source that fails the accepted pattern, `reference()` encodes the arguments without checking the decoder's constraints, so `decode()` rejects the returned value and callers cannot use it with `isReference()` or `create()`.
Make `reference()` reject empty IDs and sources that fail the decoder's pattern before constructing a reference.
</issue_to_address>
### Comment 2
<location path="frame/foldercontent.cpp" line_range="54-79" />
<code_context>
+ if (m_providers.contains(source))
</code_context>
<issue_to_address>
**Concurrent lookups race on providers**
When two threads call `create()` or `normalizeReference()` on the singleton at the same time, `provider()` checks and updates the shared `m_providers` hash without synchronization, so concurrent `create()` or `normalizeReference()` calls can race while loading and inserting providers, corrupting the cache or returning inconsistent results. Constructing a `QPluginLoader` with the registry as parent from a non-owner thread also violates QObject thread-affinity rules.
Serialize registry operations on the registry's owning thread, or protect provider lookup/loading and cache updates with an appropriate synchronization strategy.
</issue_to_address>|
|
||
| QString FolderContentRegistry::reference(const QString &source, const QString &id) | ||
| { | ||
| return QStringLiteral("folder/%1/%2").arg(source, QString::fromLatin1(id.toUtf8().toBase64( |
There was a problem hiding this comment.
🟡 Medium · Generated folder reference is unusable
When a caller passes an empty ID or a source that fails the accepted pattern, reference() encodes the arguments without checking the decoder's constraints, so decode() rejects the returned value and callers cannot use it with isReference() or create().
Make reference() reject empty IDs and sources that fail the decoder's pattern before constructing a reference.
Prompt for AI agents
In `frame/foldercontent.cpp` at line 22:
**Generated folder reference is unusable**
When a caller passes an empty ID or a source that fails the accepted pattern, `reference()` encodes the arguments without checking the decoder's constraints, so `decode()` rejects the returned value and callers cannot use it with `isReference()` or `create()`.
Make `reference()` reject empty IDs and sources that fail the decoder's pattern before constructing a reference.| if (m_providers.contains(source)) | ||
| return m_providers.value(source); | ||
|
|
||
| // Content providers live in the regular shell plugin directory and follow | ||
| // the same file naming as every other shell plugin: | ||
| // org.deepin.ds.folderprovider.<source>.so | ||
| const auto fileName = QStringLiteral("org.deepin.ds.folderprovider.%1.so").arg(source); | ||
| QStringList dirs { | ||
| QDir(QCoreApplication::applicationDirPath()).absoluteFilePath("../plugins"), | ||
| QStringLiteral(DDE_SHELL_PLUGIN_INSTALL_DIR) | ||
| }; | ||
| const auto runtimePaths = qEnvironmentVariable("DDE_SHELL_PLUGIN_PATH"); | ||
| if (!runtimePaths.isEmpty()) | ||
| dirs.append(runtimePaths.split(QDir::listSeparator(), Qt::SkipEmptyParts)); | ||
| dirs.append(QCoreApplication::libraryPaths()); | ||
|
|
||
| for (const auto &dir : dirs) { | ||
| const auto path = QDir(dir).filePath(fileName); | ||
| if (!QFileInfo::exists(path)) | ||
| continue; | ||
| auto loader = new QPluginLoader(path, this); | ||
| auto object = loader->instance(); | ||
| auto contentProvider = qobject_cast<FolderContentProvider *>(object); | ||
| if (contentProvider) { | ||
| m_providers.insert(source, contentProvider); | ||
| return contentProvider; |
There was a problem hiding this comment.
🟡 Medium · Concurrent lookups race on providers
When two threads call create() or normalizeReference() on the singleton at the same time, provider() checks and updates the shared m_providers hash without synchronization, so concurrent create() or normalizeReference() calls can race while loading and inserting providers, corrupting the cache or returning inconsistent results. Constructing a QPluginLoader with the registry as parent from a non-owner thread also violates QObject thread-affinity rules.
Serialize registry operations on the registry's owning thread, or protect provider lookup/loading and cache updates with an appropriate synchronization strategy.
Prompt for AI agents
In `frame/foldercontent.cpp` at lines 54-79:
**Concurrent lookups race on providers**
When two threads call `create()` or `normalizeReference()` on the singleton at the same time, `provider()` checks and updates the shared `m_providers` hash without synchronization, so concurrent `create()` or `normalizeReference()` calls can race while loading and inserting providers, corrupting the cache or returning inconsistent results. Constructing a `QPluginLoader` with the registry as parent from a non-owner thread also violates QObject thread-affinity rules.
Serialize registry operations on the registry's owning thread, or protect provider lookup/loading and cache updates with an appropriate synchronization strategy.|
TAG Bot New tag: 2.0.61 |
Log: Added folder content provider plugin system for custom folder pins on the taskbar/dock
Influence:
feat: 添加文件夹内容提供者注册表
Log: 新增文件夹内容提供者插件系统,支持任务栏/停靠栏自定义文件夹固定项
Influence:
PMS: TASK-397253
Summary by Sourcery
Add extensible folder content provider support for custom taskbar and dock folder pins.
New Features:
Bug Fixes:
Enhancements:
Build: