Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package hyprpaper for openSUSE:Factory checked in at 2026-08-03 17:17:15 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/hyprpaper (Old) and /work/SRC/openSUSE:Factory/.hyprpaper.new.16738 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "hyprpaper" Mon Aug 3 17:17:15 2026 rev:10 rq:1369175 version:0.8.4 Changes: -------- --- /work/SRC/openSUSE:Factory/hyprpaper/hyprpaper.changes 2026-02-17 18:45:53.220315229 +0100 +++ /work/SRC/openSUSE:Factory/.hyprpaper.new.16738/hyprpaper.changes 2026-08-03 17:17:29.955140500 +0200 @@ -1,0 +2,10 @@ +Fri Jul 31 16:31:49 UTC 2026 - Nassim Lhadj <[email protected]> + +- Update to version 0.8.4: + * Fix: set id and overwrite wildcard on explicit + * protocol: add a status object + * feature: add ability to randomize sort order + * feature: add opt-in recursive wallpaper directory scanning + * config/ui: add random-shuffle slideshow order + +------------------------------------------------------------------- Old: ---- hyprpaper-0.8.3.tar.gz New: ---- hyprpaper-0.8.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ hyprpaper.spec ++++++ --- /var/tmp/diff_new_pack.VLEuHO/_old 2026-08-03 17:17:30.855171820 +0200 +++ /var/tmp/diff_new_pack.VLEuHO/_new 2026-08-03 17:17:30.859171960 +0200 @@ -17,7 +17,7 @@ Name: hyprpaper -Version: 0.8.3 +Version: 0.8.4 Release: 0 Summary: Wayland wallpaper utility with IPC controls License: BSD-3-Clause ++++++ hyprpaper-0.8.3.tar.gz -> hyprpaper-0.8.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.8.3/.github/workflows/nix-build.yaml new/hyprpaper-0.8.4/.github/workflows/nix-build.yaml --- old/hyprpaper-0.8.3/.github/workflows/nix-build.yaml 2026-01-29 16:50:46.000000000 +0100 +++ new/hyprpaper-0.8.4/.github/workflows/nix-build.yaml 2026-04-29 22:21:53.000000000 +0200 @@ -1,50 +1,12 @@ -name: Build Hyprpaper (Nix) +name: Build on: [push, pull_request, workflow_dispatch] + jobs: nix: - name: "Build" - runs-on: ubuntu-latest - steps: - - name: Clone repository - uses: actions/checkout@v3 - with: - submodules: recursive - - - name: Install Nix - uses: nixbuild/nix-quick-install-action@v31 - with: - nix_conf: | - keep-env-derivations = true - keep-outputs = true - - - name: Restore and save Nix store - uses: nix-community/cache-nix-action@v6 - with: - # restore and save a cache using this key - primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }} - # if there's no cache hit, restore a cache by this prefix - restore-prefixes-first-match: nix-${{ runner.os }}- - # collect garbage until the Nix store size (in bytes) is at most this number - # before trying to save a new cache - # 1G = 1073741824 - gc-max-store-size-linux: 1G - # do purge caches - purge: true - # purge all versions of the cache - purge-prefixes: nix-${{ runner.os }}- - # created more than this number of seconds ago - purge-created: 0 - # or, last accessed more than this number of seconds ago - # relative to the start of the `Post Restore and save Nix store` phase - purge-last-accessed: 0 - # except any version with the key that is the same as the `primary-key` - purge-primary-key: never - - - uses: cachix/cachix-action@v12 - with: - name: hyprland - authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - - - name: Build Hyprpaper with default settings - run: nix build --print-build-logs --accept-flake-config + if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork) + uses: hyprwm/actions/.github/workflows/nix.yml@main + secrets: inherit + with: + submodules: recursive + command: nix build --print-build-logs --accept-flake-config diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.8.3/VERSION new/hyprpaper-0.8.4/VERSION --- old/hyprpaper-0.8.3/VERSION 2026-01-29 16:50:46.000000000 +0100 +++ new/hyprpaper-0.8.4/VERSION 2026-04-29 22:21:53.000000000 +0200 @@ -1 +1 @@ -0.8.3 +0.8.4 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.8.3/flake.lock new/hyprpaper-0.8.4/flake.lock --- old/hyprpaper-0.8.3/flake.lock 2026-01-29 16:50:46.000000000 +0100 +++ new/hyprpaper-0.8.4/flake.lock 2026-04-29 22:21:53.000000000 +0200 @@ -16,11 +16,11 @@ ] }, "locked": { - "lastModified": 1765900596, - "narHash": "sha256-+hn8v9jkkLP9m+o0Nm5SiEq10W0iWDSotH2XfjU45fA=", + "lastModified": 1772460678, + "narHash": "sha256-NYaWs8fYJ38IgFld0hGSdT2LEVhrgO8SiRReBjIH7YY=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "d83c97f8f5c0aae553c1489c7d9eff3eadcadace", + "rev": "5d2cb726b16ee349df443f84b64cff53221b6983", "type": "github" }, "original": { @@ -42,11 +42,11 @@ ] }, "locked": { - "lastModified": 1763733840, - "narHash": "sha256-JnET78yl5RvpGuDQy3rCycOCkiKoLr5DN1fPhRNNMco=", + "lastModified": 1772461523, + "narHash": "sha256-mI6A51do+hEUzeJKk9YSWfVHdI/SEEIBi2tp5Whq5mI=", "owner": "hyprwm", "repo": "hyprgraphics", - "rev": "8f1bec691b2d198c60cccabca7a94add2df4ed1a", + "rev": "7d63c04b4a2dd5e59ef943b4b143f46e713df804", "type": "github" }, "original": { @@ -68,11 +68,11 @@ ] }, "locked": { - "lastModified": 1764612430, - "narHash": "sha256-54ltTSbI6W+qYGMchAgCR6QnC1kOdKXN6X6pJhOWxFg=", + "lastModified": 1772459629, + "narHash": "sha256-/iwvNUYShmmnwmz/czEUh6+0eF5vCMv0xtDW0STPIuM=", "owner": "hyprwm", "repo": "hyprlang", - "rev": "0d00dc118981531aa731150b6ea551ef037acddd", + "rev": "7615ee388de18239a4ab1400946f3d0e498a8186", "type": "github" }, "original": { @@ -106,11 +106,11 @@ ] }, "locked": { - "lastModified": 1765999299, - "narHash": "sha256-C0tMHhVMEN2XlgMVeuJSbY64h9UhR2AKk5Hxxlxx6cA=", + "lastModified": 1772462885, + "narHash": "sha256-5pHXrQK9zasMnIo6yME6EOXmWGFMSnCITcfKshhKJ9I=", "owner": "hyprwm", "repo": "hyprtoolkit", - "rev": "0a5d2c25d018112434e802212a1ad57ca1e24819", + "rev": "9af245a69fa6b286b88ddfc340afd288e00a6998", "type": "github" }, "original": { @@ -129,11 +129,11 @@ ] }, "locked": { - "lastModified": 1766002182, - "narHash": "sha256-Ji2ty5d6yuToq59SZfpG0T5B5SkF3UiHoDl8VMyQp14=", + "lastModified": 1772459870, + "narHash": "sha256-xxkK2Cvqxpf/4UGcJ/TyCwrvmiNWsKsJfFzHMp2bxis=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "1c527b30feb7bed959ac07ae034a6105e6b65fd3", + "rev": "e63f3a79334dec49f8eb1691f66f18115df04085", "type": "github" }, "original": { @@ -152,11 +152,11 @@ ] }, "locked": { - "lastModified": 1763640274, - "narHash": "sha256-Uan1Nl9i4TF/kyFoHnTq1bd/rsWh4GAK/9/jDqLbY5A=", + "lastModified": 1772459835, + "narHash": "sha256-978jRz/y/9TKmZb/qD4lEYHCQGHpEXGqy+8X2lFZsak=", "owner": "hyprwm", "repo": "hyprwayland-scanner", - "rev": "f6cf414ca0e16a4d30198fd670ec86df3c89f671", + "rev": "0a692d4a645165eebd65f109146b8861e3a925e7", "type": "github" }, "original": { @@ -178,11 +178,11 @@ ] }, "locked": { - "lastModified": 1765741352, - "narHash": "sha256-jTJQy1m2XkcZJABajYVP249fCWPl3GbLe3Z8KiQmZqg=", + "lastModified": 1772463520, + "narHash": "sha256-GIjASzYnV4fK19HnyJKmHyqyxHxIpjusK9foEA4Yo+4=", "owner": "hyprwm", "repo": "hyprwire", - "rev": "b8ca85082fd5c3cdd3d11027492cd0332b517078", + "rev": "4e1933ae5602b350c5b6633f5c932549c9b8aca2", "type": "github" }, "original": { @@ -193,11 +193,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1765779637, - "narHash": "sha256-KJ2wa/BLSrTqDjbfyNx70ov/HdgNBCBBSQP3BIzKnv4=", + "lastModified": 1772433332, + "narHash": "sha256-izhTDFKsg6KeVBxJS9EblGeQ8y+O8eCa6RcW874vxEc=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "1306659b587dc277866c7b69eb97e5f07864d8c4", + "rev": "cf59864ef8aa2e178cccedbe2c178185b0365705", "type": "github" }, "original": { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.8.3/flake.nix new/hyprpaper-0.8.4/flake.nix --- old/hyprpaper-0.8.3/flake.nix 2026-01-29 16:50:46.000000000 +0100 +++ new/hyprpaper-0.8.4/flake.nix 2026-04-29 22:21:53.000000000 +0200 @@ -58,58 +58,38 @@ }; }; - outputs = { - self, - nixpkgs, - systems, - ... - } @ inputs: let - inherit (nixpkgs) lib; - eachSystem = lib.genAttrs (import systems); + outputs = + { + self, + nixpkgs, + systems, + ... + }@inputs: + let + inherit (nixpkgs) lib; + eachSystem = lib.genAttrs (import systems); - pkgsFor = eachSystem (system: - import nixpkgs { - localSystem.system = system; - overlays = with self.overlays; [hyprpaper]; + pkgsFor = eachSystem ( + system: + import nixpkgs { + localSystem.system = system; + overlays = with self.overlays; [ hyprpaper-with-deps ]; + } + ); + in + { + overlays = import ./nix/overlays.nix { inherit inputs lib self; }; + + packages = eachSystem (system: { + default = self.packages.${system}.hyprpaper; + inherit (pkgsFor.${system}) hyprpaper hyprpaper-debug; }); - mkDate = longDate: (lib.concatStringsSep "-" [ - (builtins.substring 0 4 longDate) - (builtins.substring 4 2 longDate) - (builtins.substring 6 2 longDate) - ]); - version = lib.removeSuffix "\n" (builtins.readFile ./VERSION); - in { - overlays = { - default = self.overlays.hyprpaper; - hyprpaper = lib.composeManyExtensions [ - inputs.aquamarine.overlays.default - inputs.hyprgraphics.overlays.default - inputs.hyprlang.overlays.default - inputs.hyprutils.overlays.default - inputs.hyprwayland-scanner.overlays.default - inputs.hyprtoolkit.overlays.default - inputs.hyprwire.overlays.default - (final: prev: rec { - hyprpaper = final.callPackage ./nix/default.nix { - stdenv = final.gcc15Stdenv; - version = version + "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty"); - commit = self.rev or ""; - }; - hyprpaper-debug = hyprpaper.override {debug = true;}; - }) - ]; - }; - packages = eachSystem (system: { - default = self.packages.${system}.hyprpaper; - inherit (pkgsFor.${system}) hyprpaper hyprpaper-debug; - }); + homeManagerModules = { + default = self.homeManagerModules.hyprpaper; + hyprpaper = builtins.throw "hyprpaper: the flake HM module has been removed. Use the module from Home Manager upstream."; + }; - homeManagerModules = { - default = self.homeManagerModules.hyprpaper; - hyprpaper = builtins.throw "hyprpaper: the flake HM module has been removed. Use the module from Home Manager upstream."; + formatter = eachSystem (system: pkgsFor.${system}.nixfmt-tree); }; - - formatter = eachSystem (system: pkgsFor.${system}.alejandra); - }; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.8.3/hw-protocols/hyprpaper_core.xml new/hyprpaper-0.8.4/hw-protocols/hyprpaper_core.xml --- old/hyprpaper-0.8.3/hw-protocols/hyprpaper_core.xml 2026-01-29 16:50:46.000000000 +0100 +++ new/hyprpaper-0.8.4/hw-protocols/hyprpaper_core.xml 2026-04-29 22:21:53.000000000 +0200 @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<protocol name="hyprpaper_core" version="1"> +<protocol name="hyprpaper_core" version="2"> <copyright> BSD 3-Clause License @@ -31,7 +31,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. </copyright> - <object name="hyprpaper_core_manager" version="1"> + <object name="hyprpaper_core_manager" version="2"> <description summary="manager object"> This is the core manager object for hyprpaper operations </description> @@ -62,6 +62,13 @@ Destroys this object. Children remain alive until destroyed. </description> </c2s> + + <c2s name="get_status_object" since="2"> + <description summary="Get a status object"> + Creates a status object + </description> + <returns iface="hyprpaper_status"/> + </c2s> </object> <enum name="wallpaper_fit_mode"> @@ -136,6 +143,27 @@ </s2c> <c2s name="destroy" destructor="true"> + <description summary="Destroy this object"> + Destroys this object. + </description> + </c2s> + </object> + + <object name="hyprpaper_status" version="2"> + <description summary="status object"> + This is an object which will emit various status updates. + </description> + + <s2c name="active_wallpaper"> + <description summary="Active wallpaper state"> + Sends the active wallpaper for a given monitor. This will be emitted + immediately after binding, and then every time the path changes. + </description> + <arg name="monitor" type="varchar" summary="monitor name"/> + <arg name="path" type="varchar" summary="wallpaper path"/> + </s2c> + + <c2s name="destroy" destructor="true"> <description summary="Destroy this object"> Destroys this object. </description> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.8.3/nix/default.nix new/hyprpaper-0.8.4/nix/default.nix --- old/hyprpaper-0.8.3/nix/default.nix 2026-01-29 16:50:46.000000000 +0100 +++ new/hyprpaper-0.8.4/nix/default.nix 2026-04-29 22:21:53.000000000 +0200 @@ -22,6 +22,7 @@ libselinux, libsepol, libthai, + libXdmcp, libwebp, pango, pcre, @@ -30,7 +31,6 @@ wayland, wayland-protocols, wayland-scanner, - xorg, commit, debug ? false, version ? "git", @@ -50,10 +50,7 @@ pkg-config ]; - cmakeBuildType = - if debug - then "Debug" - else "Release"; + cmakeBuildType = if debug then "Debug" else "Release"; nativeBuildInputs = [ cmake @@ -83,12 +80,12 @@ libsepol libthai libwebp + libXdmcp pango pcre pcre2 wayland wayland-protocols - xorg.libXdmcp util-linux ]; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.8.3/nix/overlays.nix new/hyprpaper-0.8.4/nix/overlays.nix --- old/hyprpaper-0.8.3/nix/overlays.nix 1970-01-01 01:00:00.000000000 +0100 +++ new/hyprpaper-0.8.4/nix/overlays.nix 2026-04-29 22:21:53.000000000 +0200 @@ -0,0 +1,45 @@ +{ + lib, + inputs, + self, + ... +}: +let + mkDate = + longDate: + (lib.concatStringsSep "-" [ + (builtins.substring 0 4 longDate) + (builtins.substring 4 2 longDate) + (builtins.substring 6 2 longDate) + ]); + version = lib.removeSuffix "\n" (builtins.readFile ../VERSION); +in + +{ + default = self.overlays.hyprpaper; + + hyprpaper-with-deps = lib.composeManyExtensions [ + inputs.aquamarine.overlays.default + inputs.hyprgraphics.overlays.default + inputs.hyprlang.overlays.default + inputs.hyprutils.overlays.default + inputs.hyprwayland-scanner.overlays.default + inputs.hyprtoolkit.overlays.default + inputs.hyprwire.overlays.default + self.overlays.hyprpaper + ]; + + hyprpaper = final: prev: rec { + hyprpaper = final.callPackage ./default.nix { + stdenv = final.gcc15Stdenv; + version = + version + + "+date=" + + (mkDate (self.lastModifiedDate or "19700101")) + + "_" + + (self.shortRev or "dirty"); + commit = self.rev or ""; + }; + hyprpaper-debug = hyprpaper.override { debug = true; }; + }; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.8.3/src/config/ConfigManager.cpp new/hyprpaper-0.8.4/src/config/ConfigManager.cpp --- old/hyprpaper-0.8.3/src/config/ConfigManager.cpp 2026-01-29 16:50:46.000000000 +0100 +++ new/hyprpaper-0.8.4/src/config/ConfigManager.cpp 2026-04-29 22:21:53.000000000 +0200 @@ -2,6 +2,7 @@ #include <algorithm> #include <filesystem> #include <glob.h> +#include <random> #include <hyprlang.hpp> #include <hyprutils/path/Path.hpp> #include <hyprutils/string/String.hpp> @@ -63,6 +64,8 @@ m_config.addSpecialConfigValue("wallpaper", "path", Hyprlang::STRING{""}); m_config.addSpecialConfigValue("wallpaper", "fit_mode", Hyprlang::STRING{"cover"}); m_config.addSpecialConfigValue("wallpaper", "timeout", Hyprlang::INT{0}); + m_config.addSpecialConfigValue("wallpaper", "order", Hyprlang::STRING{"default"}); + m_config.addSpecialConfigValue("wallpaper", "recursive", Hyprlang::INT{0}); m_config.registerHandler(&handleSource, "source", Hyprlang::SHandlerOptions{}); @@ -118,7 +121,7 @@ return resolvePath(path); } -static std::expected<std::vector<std::string>, std::string> getFullPath(const std::string& sv) { +static std::expected<std::vector<std::string>, std::string> getFullPath(const std::string& sv, const bool recursive) { if (sv.empty()) return std::unexpected("empty path"); @@ -134,14 +137,27 @@ if (!std::filesystem::exists(resolvedPath)) return std::unexpected(std::format("File '{}' does not exist", resolvedPath)); - if (std::filesystem::is_directory(resolvedPath)) - for (const auto& entry : std::filesystem::directory_iterator(resolvedPath, std::filesystem::directory_options::skip_permission_denied)) { + if (std::filesystem::is_directory(resolvedPath)) { + auto processEntry = [&result](const auto& entry) { if (entry.is_regular_file() && isImage(entry.path())) result.push_back(entry.path()); + }; - if (result.size() >= maxImagesCount) - break; + if (recursive) { + for (const auto& entry : + std::filesystem::recursive_directory_iterator(resolvedPath, std::filesystem::directory_options::skip_permission_denied)) { + processEntry(entry); + if (result.size() >= maxImagesCount) + break; + } + } else { + for (const auto& entry : std::filesystem::directory_iterator(resolvedPath, std::filesystem::directory_options::skip_permission_denied)) { + processEntry(entry); + if (result.size() >= maxImagesCount) + break; + } } + } else if (isImage(resolvedPath)) result.push_back(resolvedPath); else @@ -157,20 +173,22 @@ result.reserve(keys.size()); for (auto& key : keys) { - std::string monitor, fitMode, path; - int timeout; + std::string monitor, fitMode, path, order; + int timeout, recursive; try { monitor = std::any_cast<Hyprlang::STRING>(m_config.getSpecialConfigValue("wallpaper", "monitor", key.c_str())); fitMode = std::any_cast<Hyprlang::STRING>(m_config.getSpecialConfigValue("wallpaper", "fit_mode", key.c_str())); path = std::any_cast<Hyprlang::STRING>(m_config.getSpecialConfigValue("wallpaper", "path", key.c_str())); timeout = std::any_cast<Hyprlang::INT>(m_config.getSpecialConfigValue("wallpaper", "timeout", key.c_str())); + order = std::any_cast<Hyprlang::STRING>(m_config.getSpecialConfigValue("wallpaper", "order", key.c_str())); + recursive = std::any_cast<Hyprlang::INT>(m_config.getSpecialConfigValue("wallpaper", "recursive", key.c_str())); } catch (...) { g_logger->log(LOG_ERR, "Failed parsing wallpaper for key {}", key); continue; } - const auto RESOLVE_PATH = getFullPath(path); + const auto RESOLVE_PATH = getFullPath(path, recursive != 0); if (!RESOLVE_PATH) { g_logger->log(LOG_ERR, "Failed to resolve path {}: {}", path, RESOLVE_PATH.error()); @@ -182,7 +200,22 @@ continue; } - result.emplace_back(SSetting{.monitor = std::move(monitor), .fitMode = std::move(fitMode), .paths = RESOLVE_PATH.value(), .timeout = timeout}); + auto resolvedPaths = RESOLVE_PATH.value(); + + if (resolvedPaths.size() > 1) { + if (order != "default" && order != "random" && order != "random-shuffle") { + g_logger->log(LOG_WARN, "Invalid order value '{}', falling back to default", order); + order = "default"; + } + + if (order == "random" || order == "random-shuffle") { + std::random_device rd; + std::mt19937 g(rd()); + std::shuffle(resolvedPaths.begin(), resolvedPaths.end(), g); + } + } + + result.emplace_back(SSetting{.monitor = std::move(monitor), .fitMode = std::move(fitMode), .paths = std::move(resolvedPaths), .order = std::move(order), .timeout = timeout}); } return result; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.8.3/src/config/ConfigManager.hpp new/hyprpaper-0.8.4/src/config/ConfigManager.hpp --- old/hyprpaper-0.8.3/src/config/ConfigManager.hpp 2026-01-29 16:50:46.000000000 +0100 +++ new/hyprpaper-0.8.4/src/config/ConfigManager.hpp 2026-04-29 22:21:53.000000000 +0200 @@ -16,6 +16,7 @@ struct SSetting { std::string monitor, fitMode; std::vector<std::string> paths; + std::string order = "default"; int timeout = 0; uint32_t id = 0; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.8.3/src/config/WallpaperMatcher.cpp new/hyprpaper-0.8.4/src/config/WallpaperMatcher.cpp --- old/hyprpaper-0.8.3/src/config/WallpaperMatcher.cpp 2026-01-29 16:50:46.000000000 +0100 +++ new/hyprpaper-0.8.4/src/config/WallpaperMatcher.cpp 2026-04-29 22:21:53.000000000 +0200 @@ -65,6 +65,8 @@ std::optional<CWallpaperMatcher::rw<const CConfigManager::SSetting>> CWallpaperMatcher::matchSetting(const std::string_view& monName, const std::string_view& monDesc) { // match explicit for (const auto& s : m_settings) { + if (isWildcard(s.monitor)) + continue; if (s.monitor != monName && !("desc:"s + std::string{monDesc}).starts_with(s.monitor)) continue; return s; @@ -96,7 +98,7 @@ auto& activeState = getState(name); if (!STATE) - activeState = {.name = name, .desc = desc}; + activeState = {.name = name, .desc = desc, .currentID = CConfigManager::SETTING_INVALID}; else { activeState.name = name; activeState.desc = desc; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.8.3/src/ipc/IPC.cpp new/hyprpaper-0.8.4/src/ipc/IPC.cpp --- old/hyprpaper-0.8.3/src/ipc/IPC.cpp 2026-01-29 16:50:46.000000000 +0100 +++ new/hyprpaper-0.8.4/src/ipc/IPC.cpp 2026-04-29 22:21:53.000000000 +0200 @@ -8,7 +8,8 @@ using namespace IPC; using namespace std::string_literals; -constexpr const char* SOCKET_NAME = ".hyprpaper.sock"; +constexpr const char* SOCKET_NAME = ".hyprpaper.sock"; +constexpr const size_t HP_PROTO_VERSION = 2; static SP<CHyprpaperCoreImpl> g_coreImpl; @@ -114,7 +115,7 @@ if (!m_socket) return; - g_coreImpl = makeShared<CHyprpaperCoreImpl>(1, [this](SP<Hyprwire::IObject> obj) { + g_coreImpl = makeShared<CHyprpaperCoreImpl>(HP_PROTO_VERSION, [this](SP<Hyprwire::IObject> obj) { auto manager = m_managers.emplace_back(makeShared<CHyprpaperCoreManagerObject>(std::move(obj))); manager->setDestroy([this, weak = WP<CHyprpaperCoreManagerObject>{manager}] { std::erase(m_managers, weak); }); @@ -127,6 +128,18 @@ m_wallpaperObjects.emplace_back(makeShared<CWallpaperObject>( makeShared<CHyprpaperWallpaperObject>(m_socket->createObject(weak->getObject()->client(), weak->getObject(), "hyprpaper_wallpaper", id)))); }); + + manager->setGetStatusObject([this, weak = WP<CHyprpaperCoreManagerObject>{manager}](uint32_t id) { + if (!weak) + return; + + auto x = + m_statusObjects.emplace_back(makeShared<CHyprpaperStatusObject>(m_socket->createObject(weak->getObject()->client(), weak->getObject(), "hyprpaper_status", id))); + + for (const auto& m : g_ui->targets()) { + x->sendActiveWallpaper(m->m_monitorName.c_str(), m->m_lastPath.c_str()); + } + }); }); m_socket->addImplementation(g_coreImpl); @@ -145,3 +158,9 @@ m->sendRemoveMonitor(sv.c_str()); } } + +void CSocket::onWallpaperChanged(const std::string& mon, const std::string& path) { + for (const auto& so : m_statusObjects) { + so->sendActiveWallpaper(mon.c_str(), path.c_str()); + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.8.3/src/ipc/IPC.hpp new/hyprpaper-0.8.4/src/ipc/IPC.hpp --- old/hyprpaper-0.8.3/src/ipc/IPC.hpp 2026-01-29 16:50:46.000000000 +0100 +++ new/hyprpaper-0.8.4/src/ipc/IPC.hpp 2026-04-29 22:21:53.000000000 +0200 @@ -30,6 +30,7 @@ void onNewDisplay(const std::string& sv); void onRemovedDisplay(const std::string& sv); + void onWallpaperChanged(const std::string& mon, const std::string& path); private: SP<Hyprwire::IServerSocket> m_socket; @@ -38,6 +39,7 @@ std::vector<SP<CHyprpaperCoreManagerObject>> m_managers; std::vector<SP<CWallpaperObject>> m_wallpaperObjects; + std::vector<SP<CHyprpaperStatusObject>> m_statusObjects; friend class CWallpaperObject; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.8.3/src/ui/UI.cpp new/hyprpaper-0.8.4/src/ui/UI.cpp --- old/hyprpaper-0.8.3/src/ui/UI.cpp 2026-01-29 16:50:46.000000000 +0100 +++ new/hyprpaper-0.8.4/src/ui/UI.cpp 2026-04-29 22:21:53.000000000 +0200 @@ -6,6 +6,8 @@ #include "../ipc/IPC.hpp" #include "../config/WallpaperMatcher.hpp" +#include <algorithm> +#include <random> #include <hyprtoolkit/core/Output.hpp> #include <hyprutils/string/String.hpp> @@ -24,14 +26,23 @@ class CWallpaperTarget::CImagesData { public: - CImagesData(Hyprtoolkit::eImageFitMode fitMode, const std::vector<std::string>& images, const int timeout = 0) : - fitMode(fitMode), images(images), timeout(timeout > 0 ? timeout : 30) {} + CImagesData(Hyprtoolkit::eImageFitMode fitMode, std::vector<std::string> images, const int timeout = 0, std::string order = "default") : + fitMode(fitMode), images(std::move(images)), order(std::move(order)), timeout(timeout > 0 ? timeout : 30) {} const Hyprtoolkit::eImageFitMode fitMode; - const std::vector<std::string> images; + std::vector<std::string> images; + const std::string order; const int timeout; std::string nextImage() { + if (order == "random-shuffle" && current + 1 >= images.size()) { + std::random_device rd; + std::mt19937 g(rd()); + std::shuffle(images.begin(), images.end(), g); + current = 0; + return images[current]; + } + current = (current + 1) % images.size(); return images[current]; } @@ -41,7 +52,7 @@ }; CWallpaperTarget::CWallpaperTarget(SP<Hyprtoolkit::IBackend> backend, SP<Hyprtoolkit::IOutput> output, const std::vector<std::string>& path, Hyprtoolkit::eImageFitMode fitMode, - const int timeout) : m_monitorName(output->port()), m_backend(backend) { + const int timeout, const std::string& order) : m_monitorName(output->port()), m_backend(backend) { static const auto SPLASH_REPLY = HyprlandSocket::getFromSocket("/splash"); static const auto PENABLESPLASH = Hyprlang::CSimpleConfigValue<Hyprlang::INT>(g_config->hyprlang(), "splash"); @@ -73,11 +84,13 @@ ->fitMode(fitMode) ->commence(); + m_lastPath = path.front(); + m_image->setPositionMode(Hyprtoolkit::IElement::HT_POSITION_ABSOLUTE); m_image->setPositionFlag(Hyprtoolkit::IElement::HT_POSITION_FLAG_CENTER, true); if (path.size() > 1) { - m_imagesData = makeUnique<CImagesData>(fitMode, path, timeout); + m_imagesData = makeUnique<CImagesData>(fitMode, std::vector<std::string>(path), timeout, order); m_timer = m_backend->addTimer(std::chrono::milliseconds(std::chrono::seconds(m_imagesData->timeout)), [this](ASP<Hyprtoolkit::CTimer> self, void*) { onRepeatTimer(); }, nullptr); } @@ -115,8 +128,10 @@ ASSERT(m_imagesData); + m_lastPath = m_imagesData->nextImage(); + m_image->rebuild() - ->path(m_imagesData->nextImage()) + ->path(std::string{m_lastPath}) ->size({Hyprtoolkit::CDynamicSize::HT_SIZE_PERCENT, Hyprtoolkit::CDynamicSize::HT_SIZE_PERCENT, {1.F, 1.F}}) ->sync(true) ->fitMode(m_imagesData->fitMode) @@ -124,6 +139,8 @@ m_timer = m_backend->addTimer(std::chrono::milliseconds(std::chrono::seconds(m_imagesData->timeout)), [this](ASP<Hyprtoolkit::CTimer> self, void*) { onRepeatTimer(); }, nullptr); + + IPC::g_IPCSocket->onWallpaperChanged(m_monitorName, m_lastPath); } void CUI::registerOutput(const SP<Hyprtoolkit::IOutput>& mon) { @@ -222,5 +239,9 @@ std::erase_if(m_targets, [&mon](const auto& e) { return e->m_monitorName == mon->port(); }); - m_targets.emplace_back(makeShared<CWallpaperTarget>(m_backend, mon, TARGET->get().paths, toFitMode(TARGET->get().fitMode), TARGET->get().timeout)); + m_targets.emplace_back(makeShared<CWallpaperTarget>(m_backend, mon, TARGET->get().paths, toFitMode(TARGET->get().fitMode), TARGET->get().timeout, TARGET->get().order)); +} + +const std::vector<SP<CWallpaperTarget>>& CUI::targets() { + return m_targets; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.8.3/src/ui/UI.hpp new/hyprpaper-0.8.4/src/ui/UI.hpp --- old/hyprpaper-0.8.3/src/ui/UI.hpp 2026-01-29 16:50:46.000000000 +0100 +++ new/hyprpaper-0.8.4/src/ui/UI.hpp 2026-04-29 22:21:53.000000000 +0200 @@ -17,14 +17,14 @@ class CWallpaperTarget { public: CWallpaperTarget(SP<Hyprtoolkit::IBackend> backend, SP<Hyprtoolkit::IOutput> output, const std::vector<std::string>& path, - Hyprtoolkit::eImageFitMode fitMode = Hyprtoolkit::IMAGE_FIT_MODE_COVER, const int timeout = 0); + Hyprtoolkit::eImageFitMode fitMode = Hyprtoolkit::IMAGE_FIT_MODE_COVER, const int timeout = 0, const std::string& order = "default"); ~CWallpaperTarget(); CWallpaperTarget(const CWallpaperTarget&) = delete; CWallpaperTarget(CWallpaperTarget&) = delete; CWallpaperTarget(CWallpaperTarget&&) = delete; - std::string m_monitorName; + std::string m_monitorName, m_lastPath; private: void onRepeatTimer(); @@ -46,8 +46,9 @@ CUI(); ~CUI(); - bool run(); - SP<Hyprtoolkit::IBackend> backend(); + bool run(); + SP<Hyprtoolkit::IBackend> backend(); + const std::vector<SP<CWallpaperTarget>>& targets(); private: void targetChanged(const SP<Hyprtoolkit::IOutput>& mon);
