diff --git a/src/Hyprpaper.cpp b/src/Hyprpaper.cpp index 1247426..4f1ea86 100644 --- a/src/Hyprpaper.cpp +++ b/src/Hyprpaper.cpp @@ -4,6 +4,7 @@ #include #include #include "helpers/RandomGenerator.hpp" +#include "helpers/ImagePicker.hpp" CHyprpaper::CHyprpaper() = default; @@ -180,21 +181,13 @@ void CHyprpaper::preloadAllWallpapersFromConfig() { unloadWallpaper(path); } - std::vector images; - for (auto& entry : std::filesystem::directory_iterator(wp)) { - if (entry.is_regular_file()) { - auto ext = entry.path().extension().string(); - if (ext == ".png" || ext == ".jpg" || ext == ".jpeg" || ext == ".webp" || ext == ".jxl") - images.push_back(entry.path()); - } - } - if (!images.empty()) { - // Use CRandomGenerator instead - wp = images[CRandomGenerator::get().getRandomIndex(images.size())].string(); - } else { + // Use our helper to pick a random image. + std::string randomImage = getRandomImageFromDirectory(wp); + if (randomImage.empty()) { Debug::log(LOG, "No valid images in directory {}", wp); continue; } + wp = randomImage; } // For non-directory requests, skip if already loaded. diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index d6283c4..238c6ae 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -3,6 +3,7 @@ #include #include #include "../helpers/RandomGenerator.hpp" +#include "../helpers/ImagePicker.hpp" // Utility function to safely expand a tilde at the beginning of a path. static std::string expandTilde(const std::string& path) { @@ -61,28 +62,13 @@ static Hyprlang::CParseResult handleWallpaper(const char* C, const char* V) { } } - std::vector images; - for (auto& entry : std::filesystem::directory_iterator(WALLPAPER)) { - if (entry.is_regular_file()) { - auto ext = entry.path().extension().string(); - if (ext == ".png" || ext == ".jpg" || ext == ".jpeg" || ext == ".webp" || ext == ".jxl") { - if (entry.path().string() != currentWallpaper) { - images.push_back(entry.path()); - } - } - } + // Use our helper with an exclusion to avoid reselecting the same image. + std::string randomImage = getRandomImageFromDirectory(WALLPAPER, currentWallpaper); + if (randomImage.empty()) { + result.setError("No valid images in directory"); + return result; } - - if (images.empty()) { - if (!currentWallpaper.empty()) { - images.push_back(currentWallpaper); - } else { - result.setError("No valid images in directory"); - return result; - } - } - - WALLPAPER = images[CRandomGenerator::get().getRandomIndex(images.size())].string(); + WALLPAPER = randomImage; } if (!g_pHyprpaper->isPreloaded(WALLPAPER)) { diff --git a/src/helpers/ImagePicker.cpp b/src/helpers/ImagePicker.cpp new file mode 100644 index 0000000..defe473 --- /dev/null +++ b/src/helpers/ImagePicker.cpp @@ -0,0 +1,30 @@ +#include "ImagePicker.hpp" +#include "RandomGenerator.hpp" +#include +#include +#include + +std::string getRandomImageFromDirectory(const std::string &dirPath, const std::string &ignore) { + std::vector images; + for (const auto &entry : std::filesystem::directory_iterator(dirPath)) { + if (entry.is_regular_file()) { + auto ext = entry.path().extension().string(); + if ((ext == ".png" || ext == ".jpg" || ext == ".jpeg" || + ext == ".webp" || ext == ".jxl")) { + if (ignore.empty() || entry.path().string() != ignore) { + images.push_back(entry.path()); + } + } + } + } + + if (images.empty()) { + // If no alternative was found but the ignored file exists, return it. + if (!ignore.empty() && std::filesystem::exists(ignore)) + return ignore; + return ""; + } + + std::shuffle(images.begin(), images.end(), CRandomGenerator::get().getGenerator()); + return images.front().string(); +} diff --git a/src/helpers/ImagePicker.hpp b/src/helpers/ImagePicker.hpp new file mode 100644 index 0000000..7df300f --- /dev/null +++ b/src/helpers/ImagePicker.hpp @@ -0,0 +1,7 @@ +#pragma once +#include + +// Returns a random image path from the given directory. +// If 'ignore' is provided, that file (if present) will be excluded from the selection. +// Returns an empty string if no valid image is found. +std::string getRandomImageFromDirectory(const std::string &dirPath, const std::string &ignore = "");