Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions desktop/base/file_operations/filter_target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,27 @@ QStringList filter_target(const QString& dirent_path, const QStringList& filters
return result;
}

QStringList filter_target_recursive(const QString& dirent_path, const QStringList& filters) {
QStringList result;
QDir dir(dirent_path);

if (!dir.exists()) {
return result;
}

// Collect matching files at this level (files only, same as filter_target).
const QFileInfoList files = dir.entryInfoList(filters, QDir::Files | QDir::NoDotAndDotDot);
for (const auto& entry : files) {
result.append(entry.absoluteFilePath());
}

// Descend into each subdirectory so nested resource packs are discovered.
const QFileInfoList subdirs = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
for (const auto& sub : subdirs) {
result.append(filter_target_recursive(sub.absoluteFilePath(), filters));
}

return result;
}

} // namespace cf::desktop::base::filesystem
24 changes: 24 additions & 0 deletions desktop/base/file_operations/filter_target.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,28 @@ QStringList& request_filterlist(const FilterType what);
* @return QStringList
*/
QStringList filter_target(const QString& dirent_path, const QStringList& filters);

/**
* @brief Recursively list files matching the filters under a directory.
*
* Like filter_target(), but descends into subdirectories so that files
* nested in pack subdirectories (for example a wallpaper resource pack
* installed under wallpapers/<pack>/) are discovered. The top-level
* directory and every subdirectory are scanned; matching file paths are
* accumulated.
*
* @param[in] dirent_path Absolute path of the root directory to scan.
* @param[in] filters Name filters to match (for example image globs).
*
* @return Absolute file paths of matching files; empty if the directory
* does not exist or no file matches.
*
* @throws None.
*
* @note None.
* @warning None.
* @since 0.19
* @ingroup filesystem
*/
QStringList filter_target_recursive(const QString& dirent_path, const QStringList& filters);
} // namespace cf::desktop::base::filesystem
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ namespace cf::desktop::path {
* @brief Provider for desktop main directory paths.
*
* Manages resolution of standard desktop directory paths including Home,
* Desktop, Documents, Downloads, Music, Pictures, Videos, Apps, and Runtime.
* Desktop, Documents, Downloads, Music, Pictures, Wallpapers, Videos, Apps,
* and Runtime.
*
* @ingroup desktop_base
*/
Expand All @@ -41,6 +42,7 @@ class DesktopMainPathProvider : public aex::Singleton<DesktopMainPathProvider> {
X(Downloads) \
X(Music) \
X(Pictures) \
X(Wallpapers) \
X(Videos) \
X(Apps) \
X(Runtime)
Expand Down
26 changes: 22 additions & 4 deletions desktop/ui/components/shell_layer_impl/wallpaper_setup.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "wallpaper_setup.h"
#include "cflog.h"
#include "cfpath/desktop_main_path_resolvers.h"
#include "filter_target.h"
#include "shell_layer_impl/WallpaperShellLayerStrategy.h"
#include "wallpaper/ImageWallPaperLayer.h"
Expand All @@ -19,13 +20,30 @@ std::unique_ptr<WallPaperLayer> make_layer() {
using namespace base::filesystem;

auto layer = std::make_unique<ImageWallPaperLayer>();
// Resolve wallpaper pictures through policy chain
const QStringList pic_filters = request_filterlist(FilterType::Pictures);

// Primary source: policy chain (config source_path -> Pictures), flat scan.
auto picture_dirent = WallpaperImages().execute();
if (!picture_dirent.has_value() || picture_dirent->isEmpty()) {
return layer; // return out!
QStringList pictures;
if (picture_dirent.has_value() && !picture_dirent->isEmpty()) {
pictures = filter_target(picture_dirent.value(), pic_filters);
}

// Fallback: bundled Wallpapers directory, scanned recursively so resource
// packs installed under wallpapers/<pack>/ are discovered. Tried only when
// the primary source yielded nothing, so users with their own pictures are
// unaffected; an empty Pictures directory now falls through to the bundled
// pack instead of leaving the desktop without a wallpaper.
if (pictures.isEmpty()) {
const QString wallpapers_dir = path::DesktopMainPathProvider::instance().absolutePath(
path::DesktopMainPathProvider::PathType::Wallpapers);
pictures = filter_target_recursive(wallpapers_dir, pic_filters);
}

if (pictures.isEmpty()) {
return layer; // No wallpaper available anywhere.
}

auto pictures = filter_target(picture_dirent.value(), request_filterlist(FilterType::Pictures));
auto storage = std::make_unique<WallPaperAccessStorage>();
storage->addTokens(WallPaperTokenFactory::fromFiles(pictures));
log::tracef("Initialized with {} files", storage->size());
Expand Down
1 change: 1 addition & 0 deletions document/status/current.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ description: CFDesktop 项目进度的唯一事实来源与全局导航。
## 最近里程碑(git 可证)

- **2026-06**:`refactor: refactor the ui subsystem`;`hwtier system enabled`;文档清理
- **2026-06(壁纸资源包发现)**:壁纸层支持运行时动态发现第三方资源包——新增 `Wallpapers` PathType(`<desktop_active_root>/Wallpapers/`)+ `filter_target_recursive` 递归扫描;`make_layer()` 改为「首个有图的源胜出」(config → Pictures 平铺,空则回退 Wallpapers 递归)。CF-Gallery 等包安装到 `Wallpapers/<pack>/` 即被发现,**CFDesktop 零编译期耦合**(无 submodule/无 `#ifdef`/无 CMake option)。详见 [aels_cross_repo_deps.md](../todo/desktop/aels_cross_repo_deps.md)。动画轮播引擎(Gradient/Movement)留待下一批。
- **已达成**:Milestone 1「桌面骨架可见」;Phase 0 / 1 / 2 / A(CI) / 6 / G(Widget) / H(显示后端)(详见 [SUMMARY.md](../todo/done/SUMMARY.md))

## 新人入门
Expand Down
1 change: 1 addition & 0 deletions document/todo/desktop/aels_cross_repo_deps.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ description: CFDesktop 消费的 AELS 组织独立仓(含拟新建)的跨仓
| **lightroot** | 现代化 BuildRoot(根文件系统构建) | 与 OTA/部署同层 |
| **edgecv** | OpenCV 封装(desktop + embedded) | 相机/图像应用可选依赖 |
| **bareline** | 嵌入式+PC CLI 交互框架 | 终端 App 的 pty 层可借鉴 |
| **CF-Gallery** | 摄影静物壁纸静态资源包(CC BY-NC-ND 4.0,VitePress 收录站) | **非构建依赖**:运行时动态发现——资源包安装到 `<desktop_active_root>/Wallpapers/<pack>/`(默认 `~/desktop/Wallpapers/`)即被壁纸层递归扫描消费。CFDesktop 零编译期耦合(**无 submodule、无 `#ifdef`、无 CMake option**);图片绝不进二进制,「开关」=是否安装了该资源包。 |

---

Expand Down
Loading