Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package hyprpaper for openSUSE:Factory checked in at 2024-06-07 15:03:09 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/hyprpaper (Old) and /work/SRC/openSUSE:Factory/.hyprpaper.new.24587 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "hyprpaper" Fri Jun 7 15:03:09 2024 rev:4 rq:1178995 version:0.7.0 Changes: -------- --- /work/SRC/openSUSE:Factory/hyprpaper/hyprpaper.changes 2024-04-02 16:45:00.438711731 +0200 +++ /work/SRC/openSUSE:Factory/.hyprpaper.new.24587/hyprpaper.changes 2024-06-07 15:03:33.288183759 +0200 @@ -1,0 +2,26 @@ +Thu Jun 6 10:00:17 UTC 2024 - Joshua Smith <smolsheep@opensuse.org> + +- Simplify install to just cmake +- Remove now-unneeded make protocols +- Update to version 0.7.0: + Fixes + * Fixed IPC with wildcards + * Added unload unused + * Moved socket to match hyprland 0.40.0 + MRs + * Disable splash message by default + * readme: fix typos + * ipc: Added listloaded and listactive requests + * Fix error checking while changing wallpaper. + * Updated link to reflect arch package movement from community to + extra + * Nix: add home-manager module + * Set standard exclusively for c++ + * Add OpenSuse to the installer method list + * hyprpaper: add splash_color configuration option + * Added missing hyprlang-devel dependency for Fedora + * Remove comma from monitor description + * Fix typo in hm-module.nix + * Move socket to XDG_RUNTIME_DIR + +------------------------------------------------------------------- Old: ---- hyprpaper-0.6.0.tar.gz New: ---- hyprpaper-0.7.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ hyprpaper.spec ++++++ --- /var/tmp/diff_new_pack.oxCsdy/_old 2024-06-07 15:03:33.816202995 +0200 +++ /var/tmp/diff_new_pack.oxCsdy/_new 2024-06-07 15:03:33.816202995 +0200 @@ -19,7 +19,7 @@ %global __builder ninja Name: hyprpaper Summary: Wayland wallpaper utility with IPC controls -Version: 0.6.0 +Version: 0.7.0 Release: 0 License: BSD-3-Clause URL: https://github.com/hyprwm/hyprpaper @@ -51,14 +51,11 @@ %autosetup %build -# Necessary to allow build -make protocols - %cmake %cmake_build %install -install -Dm0755 -t "%{buildroot}%{_bindir}" "%{_builddir}/%{name}-%{version}/build/%{name}" +%cmake_install %files %_bindir/hyprpaper ++++++ hyprpaper-0.6.0.tar.gz -> hyprpaper-0.7.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.6.0/CMakeLists.txt new/hyprpaper-0.7.0/CMakeLists.txt --- old/hyprpaper-0.6.0/CMakeLists.txt 2024-01-02 22:22:34.000000000 +0100 +++ new/hyprpaper-0.7.0/CMakeLists.txt 2024-04-28 23:25:36.000000000 +0200 @@ -35,8 +35,38 @@ # # +find_program(WaylandScanner NAMES wayland-scanner) +message(STATUS "Found WaylandScanner at ${WaylandScanner}") +execute_process( + COMMAND pkg-config --variable=pkgdatadir wayland-protocols + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE WAYLAND_PROTOCOLS_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE) +message(STATUS "Found wayland-protocols at ${WAYLAND_PROTOCOLS_DIR}") + +function(protocol protoPath protoName external) + if (external) + execute_process( + COMMAND ${WaylandScanner} client-header ${protoPath} ${protoName}-protocol.h + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) + execute_process( + COMMAND ${WaylandScanner} private-code ${protoPath} ${protoName}-protocol.c + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) + target_sources(hyprpaper PRIVATE ${protoName}-protocol.h ${protoName}-protocol.c) + else() + execute_process( + COMMAND ${WaylandScanner} client-header ${WAYLAND_PROTOCOLS_DIR}/${protoPath} ${protoName}-protocol.h + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) + execute_process( + COMMAND ${WaylandScanner} private-code ${WAYLAND_PROTOCOLS_DIR}/${protoPath} ${protoName}-protocol.c + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) + target_sources(hyprpaper PRIVATE ${protoName}-protocol.h ${protoName}-protocol.c) + endif() +endfunction() + include_directories(.) -add_compile_options(-std=c++2b -DWLR_USE_UNSTABLE ) +set(CMAKE_CXX_STANDARD 23) +add_compile_options(-DWLR_USE_UNSTABLE) add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-unused-value -Wno-missing-field-initializers -Wno-narrowing) find_package(Threads REQUIRED) @@ -47,6 +77,11 @@ add_executable(hyprpaper ${SRCFILES}) +protocol("protocols/wlr-layer-shell-unstable-v1.xml" "wlr-layer-shell-unstable-v1" true) +protocol("stable/xdg-shell/xdg-shell.xml" "xdg-shell" false) +protocol("stable/viewporter/viewporter.xml" "viewporter" false) +protocol("staging/fractional-scale/fractional-scale-v1.xml" "fractional-scale-v1" false) + target_compile_definitions(hyprpaper PRIVATE "-DGIT_COMMIT_HASH=\"${GIT_COMMIT_HASH}\"") target_compile_definitions(hyprpaper PRIVATE "-DGIT_BRANCH=\"${GIT_BRANCH}\"") target_compile_definitions(hyprpaper PRIVATE "-DGIT_COMMIT_MESSAGE=\"${GIT_COMMIT_MESSAGE}\"") @@ -66,10 +101,6 @@ pthread magic ${CMAKE_THREAD_LIBS_INIT} - ${CMAKE_SOURCE_DIR}/wlr-layer-shell-unstable-v1-protocol.o - ${CMAKE_SOURCE_DIR}/xdg-shell-protocol.o - ${CMAKE_SOURCE_DIR}/fractional-scale-v1-protocol.o - ${CMAKE_SOURCE_DIR}/viewporter-protocol.o wayland-cursor ) @@ -78,3 +109,5 @@ SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg -no-pie -fno-builtin") SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pg -no-pie -fno-builtin") ENDIF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG) + +install(TARGETS hyprpaper) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.6.0/Makefile new/hyprpaper-0.7.0/Makefile --- old/hyprpaper-0.6.0/Makefile 2024-01-02 22:22:34.000000000 +0100 +++ new/hyprpaper-0.7.0/Makefile 1970-01-01 01:00:00.000000000 +0100 @@ -1,74 +0,0 @@ -PREFIX ?= /usr -CFLAGS ?= -g -Wall -Wextra -Werror -Wno-unused-parameter -Wno-sign-compare -Wno-unused-function -Wno-unused-variable -Wno-unused-result -Wdeclaration-after-statement - -CFLAGS += -I. -DWLR_USE_UNSTABLE -std=c99 - -WAYLAND_PROTOCOLS=$(shell pkg-config --variable=pkgdatadir wayland-protocols) -WAYLAND_SCANNER=$(shell pkg-config --variable=wayland_scanner wayland-scanner) - -PKGS = wlroots wayland-server -CFLAGS += $(foreach p,$(PKGS),$(shell pkg-config --cflags $(p))) -LDLIBS += $(foreach p,$(PKGS),$(shell pkg-config --libs $(p))) - -wlr-layer-shell-unstable-v1-protocol.h: - $(WAYLAND_SCANNER) client-header \ - protocols/wlr-layer-shell-unstable-v1.xml $@ - -wlr-layer-shell-unstable-v1-protocol.c: - $(WAYLAND_SCANNER) private-code \ - protocols/wlr-layer-shell-unstable-v1.xml $@ - -wlr-layer-shell-unstable-v1-protocol.o: wlr-layer-shell-unstable-v1-protocol.h - -xdg-shell-protocol.h: - $(WAYLAND_SCANNER) client-header \ - $(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@ - -xdg-shell-protocol.c: - $(WAYLAND_SCANNER) private-code \ - $(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@ - -xdg-shell-protocol.o: xdg-shell-protocol.h - -fractional-scale-v1-protocol.h: - $(WAYLAND_SCANNER) client-header \ - $(WAYLAND_PROTOCOLS)/staging/fractional-scale/fractional-scale-v1.xml $@ - -fractional-scale-v1-protocol.c: - $(WAYLAND_SCANNER) private-code \ - $(WAYLAND_PROTOCOLS)/staging/fractional-scale/fractional-scale-v1.xml $@ - -fractional-scale-v1-protocol.o: fractional-scale-v1-protocol.h - -viewporter-protocol.h: - $(WAYLAND_SCANNER) client-header \ - $(WAYLAND_PROTOCOLS)/stable/viewporter/viewporter.xml $@ - -viewporter-protocol.c: - $(WAYLAND_SCANNER) private-code \ - $(WAYLAND_PROTOCOLS)/stable/viewporter/viewporter.xml $@ - -viewporter-protocol.o: viewporter-protocol.h - -protocols: wlr-layer-shell-unstable-v1-protocol.o xdg-shell-protocol.o fractional-scale-v1-protocol.o viewporter-protocol.o - -clear: - rm -rf build - rm -f *.o *-protocol.h *-protocol.c - -release: - mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -H./ -B./build -G Ninja - cmake --build ./build --config Release --target all -j 10 - -debug: - mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -H./ -B./build -G Ninja - cmake --build ./build --config Debug --target all -j 10 - -all: - make clear - make protocols - make release - -install: - make all - cp ./build/hyprpaper $(PREFIX)/bin -f diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.6.0/README.md new/hyprpaper-0.7.0/README.md --- old/hyprpaper-0.6.0/README.md 2024-01-02 22:22:34.000000000 +0100 +++ new/hyprpaper-0.7.0/README.md 2024-04-28 23:25:36.000000000 +0200 @@ -11,7 +11,9 @@ # Installation -[Arch Linux](https://archlinux.org/packages/community/x86_64/hyprpaper/): `pacman -S hyprpaper` +[Arch Linux](https://archlinux.org/packages/extra/x86_64/hyprpaper/): `pacman -S hyprpaper` + +[OpenSuse Linux](https://software.opensuse.org/package/hyprpaper): `zypper install hyprpaper` ## Manual: @@ -34,7 +36,7 @@ To install all of these in Fedora, run this command: ``` -sudo dnf install wayland-devel wayland-protocols-devel pango-devel cairo-devel file-devel libglvnd-devel libglvnd-core-devel libjpeg-turbo-devel libwebp-devel gcc-c++ +sudo dnf install wayland-devel wayland-protocols-devel hyprlang-devel pango-devel cairo-devel file-devel libglvnd-devel libglvnd-core-devel libjpeg-turbo-devel libwebp-devel gcc-c++ ``` On Arch: @@ -49,13 +51,18 @@ ### Building -``` -git clone https://github.com/hyprwm/hyprpaper -cd hyprpaper -make all +Building is done via CMake: + +```sh +cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -S . -B ./build +cmake --build ./build --config Release --target hyprpaper -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF` ``` -*the output binary will be in `./build/`, copy it to your PATH, e.g. `/usr/bin`* +Install with: + +```sh +cmake --install ./build +``` # Usage @@ -68,14 +75,22 @@ preload = /path/to/next_image.png # .. more preloads -#set the default wallpaper(s) seen on inital workspace(s) --depending on the number of monitors used +#set the default wallpaper(s) seen on initial workspace(s) --depending on the number of monitors used wallpaper = monitor1,/path/to/image.png #if more than one monitor in use, can load a 2nd image wallpaper = monitor2,/path/to/next_image.png # .. more monitors + +#enable splash text rendering over the wallpaper +splash = true + +#fully disable ipc +# ipc = off + + ``` -Preload will tell Hyprland to load a particular image (supported formats: png, jpg, jpeg, webp). Wallpaper will apply the wallpaper to the selected output (`monitor` is the monitor's name, easily can be retrieved with `hyprctl monitors`. You can leave it empty for a wildcard (aka fallback). You can also use `desc:` followed by the monitor's description without the (PORT) at the end) +Preload will tell Hyprland to load a particular image (supported formats: png, jpg, jpeg, webp). Wallpaper will apply the wallpaper to the selected output (`monitor` is the monitor's name, easily can be retrieved with `hyprctl monitors`. You can leave it empty to set all monitors without an active wallpaper. You can also use `desc:` followed by the monitor's description without the (PORT) at the end) You may add `contain:` before the file path in `wallpaper=` to set the mode to contain instead of cover: @@ -120,7 +135,7 @@ #yes use quotes around desired monitor and wallpaper #... continued with desired amount ``` -With the varibles created we can now "exec" the actions. +With the variables created we can now "exec" the actions. Remember in Hyprland we can bind more than one action to a key so in the case where we'd like to change the wallpaper when we switch workspace we have to ensure that the actions are bound to the same key such as... @@ -144,6 +159,13 @@ bind=SUPERSHIFT,1,exec,$w1 #SuperKey + Shift + 1 switches to wallpaper $w1 on DP-1 as defined in the variable ``` +## Getting information from hyprpaper +You can also use `hyprctl hyprpaper` to get information about the state of hyprpaper using the following commands: +``` +listloaded - lists the wallpapers that are currently preloaded (useful for dynamically preloading and unloading) +listactive - prints the active wallpapers hyprpaper is displaying, along with its accociated monitor +``` + # Battery life Since the IPC has to tick every now and then, and poll in the background, battery life might be a tiny bit worse with IPC on. If you want to fully disable it, use ``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.6.0/flake.lock new/hyprpaper-0.7.0/flake.lock --- old/hyprpaper-0.6.0/flake.lock 2024-01-02 22:22:34.000000000 +0100 +++ new/hyprpaper-0.7.0/flake.lock 2024-04-28 23:25:36.000000000 +0200 @@ -2,14 +2,15 @@ "nodes": { "hyprlang": { "inputs": { - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs", + "systems": "systems" }, "locked": { - "lastModified": 1704230242, - "narHash": "sha256-S8DM+frECqmAdaUb3y5n3RjY73ajZcL5rnmx5YO+CkY=", + "lastModified": 1711250455, + "narHash": "sha256-LSq1ZsTpeD7xsqvlsepDEelWRDtAhqwetp6PusHXJRo=", "owner": "hyprwm", "repo": "hyprlang", - "rev": "db5e1399b90d5a339330bdd49c5bca6fe58d6f60", + "rev": "b3e430f81f3364c5dd1a3cc9995706a4799eb3fa", "type": "github" }, "original": { @@ -20,11 +21,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1702645756, - "narHash": "sha256-qKI6OR3TYJYQB3Q8mAZ+DG4o/BR9ptcv9UnRV2hzljc=", - "owner": "nixos", + "lastModified": 1708475490, + "narHash": "sha256-g1v0TsWBQPX97ziznfJdWhgMyMGtoBFs102xSYO4syU=", + "owner": "NixOS", "repo": "nixpkgs", - "rev": "40c3c94c241286dd2243ea34d3aef8a488f9e4d0", + "rev": "0e74ca98a74bc7270d28838369593635a5db3260", "type": "github" }, "original": { @@ -36,11 +37,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1703637592, - "narHash": "sha256-8MXjxU0RfFfzl57Zy3OfXCITS0qWDNLzlBAdwxGZwfY=", + "lastModified": 1711163522, + "narHash": "sha256-YN/Ciidm+A0fmJPWlHBGvVkcarYWSC+s3NTPk/P+q3c=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "cfc3698c31b1fb9cdcf10f36c9643460264d0ca8", + "rev": "44d0940ea560dee511026a53f0e2e2cde489b4d4", "type": "github" }, "original": { @@ -53,7 +54,38 @@ "root": { "inputs": { "hyprlang": "hyprlang", - "nixpkgs": "nixpkgs_2" + "nixpkgs": "nixpkgs_2", + "systems": "systems_2" + } + }, + "systems": { + "locked": { + "lastModified": 1689347949, + "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", + "owner": "nix-systems", + "repo": "default-linux", + "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default-linux", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1689347949, + "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", + "owner": "nix-systems", + "repo": "default-linux", + "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default-linux", + "type": "github" } } }, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.6.0/flake.nix new/hyprpaper-0.7.0/flake.nix --- old/hyprpaper-0.6.0/flake.nix 2024-01-02 22:22:34.000000000 +0100 +++ new/hyprpaper-0.7.0/flake.nix 2024-04-28 23:25:36.000000000 +0200 @@ -5,40 +5,53 @@ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; hyprlang.url = "github:hyprwm/hyprlang"; + + systems.url = "github:nix-systems/default-linux"; }; outputs = { self, nixpkgs, + systems, ... } @ inputs: let inherit (nixpkgs) lib; - genSystems = lib.genAttrs [ - # Add more systems if they are supported - "x86_64-linux" - "aarch64-linux" - ]; - pkgsFor = nixpkgs.legacyPackages; + eachSystem = lib.genAttrs (import systems); + + pkgsFor = eachSystem (system: + import nixpkgs { + localSystem.system = system; + overlays = with self.overlays; [hyprpaper]; + }); mkDate = longDate: (lib.concatStringsSep "-" [ - (__substring 0 4 longDate) - (__substring 4 2 longDate) - (__substring 6 2 longDate) + (builtins.substring 0 4 longDate) + (builtins.substring 4 2 longDate) + (builtins.substring 6 2 longDate) ]); in { - overlays.default = _: prev: rec { - hyprpaper = prev.callPackage ./nix/default.nix { - stdenv = prev.gcc13Stdenv; - version = "0.pre" + "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty"); - inherit (prev.xorg) libXdmcp; - inherit (inputs.hyprlang.packages.${prev.system}) hyprlang; + overlays = { + default = self.overlays.hyprpaper; + hyprpaper = final: prev: rec { + hyprpaper = final.callPackage ./nix/default.nix { + stdenv = final.gcc13Stdenv; + version = "0.pre" + "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty"); + inherit (final.xorg) libXdmcp; + inherit (inputs.hyprlang.packages.${final.system}) hyprlang; + }; + hyprpaper-debug = hyprpaper.override {debug = true;}; }; - hyprpaper-debug = hyprpaper.override {debug = true;}; }; - packages = genSystems (system: - (self.overlays.default null pkgsFor.${system}) - // {default = self.packages.${system}.hyprpaper;}); + packages = eachSystem (system: { + default = self.packages.${system}.hyprpaper; + inherit (pkgsFor.${system}) hyprpaper hyprpaper-debug; + }); + + homeManagerModules = { + default = self.homeManagerModules.hyprpaper; + hyprpaper = import ./nix/hm-module.nix self; + }; - formatter = genSystems (system: pkgsFor.${system}.alejandra); + formatter = eachSystem (system: pkgsFor.${system}.alejandra); }; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.6.0/nix/default.nix new/hyprpaper-0.7.0/nix/default.nix --- old/hyprpaper-0.6.0/nix/default.nix 2024-01-02 22:22:34.000000000 +0100 +++ new/hyprpaper-0.7.0/nix/default.nix 2024-04-28 23:25:36.000000000 +0200 @@ -3,7 +3,6 @@ stdenv, pkg-config, cmake, - ninja, cairo, expat, file, @@ -30,11 +29,16 @@ stdenv.mkDerivation { pname = "hyprpaper" + lib.optionalString debug "-debug"; inherit version; + src = ../.; + cmakeBuildType = + if debug + then "Debug" + else "Release"; + nativeBuildInputs = [ cmake - ninja pkg-config ]; @@ -61,33 +65,6 @@ util-linux ]; - configurePhase = '' - runHook preConfigure - - make protocols - - runHook postConfigure - ''; - - buildPhase = '' - runHook preBuild - - make release - - runHook postBuild - ''; - - installPhase = '' - runHook preInstall - - mkdir -p $out/{bin,share/licenses} - - install -Dm755 build/hyprpaper -t $out/bin - install -Dm644 LICENSE -t $out/share/licenses/hyprpaper - - runHook postInstall - ''; - meta = with lib; { homepage = "https://github.com/hyprwm/hyprpaper"; description = "A blazing fast wayland wallpaper utility with IPC controls"; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.6.0/nix/hm-module.nix new/hyprpaper-0.7.0/nix/hm-module.nix --- old/hyprpaper-0.6.0/nix/hm-module.nix 1970-01-01 01:00:00.000000000 +0100 +++ new/hyprpaper-0.7.0/nix/hm-module.nix 2024-04-28 23:25:36.000000000 +0200 @@ -0,0 +1,102 @@ +self: { + config, + pkgs, + lib, + ... +}: let + inherit (builtins) toString; + inherit (lib.types) bool float listOf package str; + inherit (lib.modules) mkIf; + inherit (lib.options) mkOption mkEnableOption; + inherit (lib.meta) getExe; + + boolToString = x: + if x + then "true" + else "false"; + cfg = config.services.hyprpaper; +in { + options.services.hyprpaper = { + enable = mkEnableOption "Hyprpaper, Hyprland's wallpaper utility"; + + package = mkOption { + description = "The hyprpaper package"; + type = package; + default = self.packages.${pkgs.stdenv.hostPlatform.system}.hyprpaper; + }; + + ipc = mkOption { + description = "Whether to enable IPC"; + type = bool; + default = true; + }; + + splash = mkOption { + description = "Enable rendering of the hyprland splash over the wallpaper"; + type = bool; + default = false; + }; + + splash_offset = mkOption { + description = "How far (in % of height) up should the splash be displayed"; + type = float; + default = 2.0; + }; + + preloads = mkOption { + description = "List of paths to images that will be loaded into memory."; + type = listOf str; + example = [ + "~/Images/wallpapers/forest.png" + "~/Images/wallpapers/desert.png" + ]; + }; + + wallpapers = mkOption { + description = "The wallpapers"; + type = listOf str; + example = [ + "eDP-1,~/Images/wallpapers/forest.png" + "DP-7,~/Images/wallpapers/desert.png" + ]; + }; + }; + + config = mkIf cfg.enable { + xdg.configFile."hypr/hyprpaper.conf".text = '' + ipc = ${ + if cfg.ipc + then "on" + else "off" + } + splash = ${boolToString cfg.splash} + splash_offset = ${toString cfg.splash_offset} + + ${ + builtins.concatStringsSep "\n" + ( + map (preload: "preload = ${preload}") cfg.preloads + ) + } + ${ + builtins.concatStringsSep "\n" + ( + map (wallpaper: "wallpaper = ${wallpaper}") cfg.wallpapers + ) + } + ''; + + systemd.user.services.hyprpaper = { + Unit = { + Description = "Hyprland wallpaper daemon"; + PartOf = ["graphical-session.target"]; + }; + + Service = { + ExecStart = "${getExe cfg.package}"; + Restart = "on-failure"; + }; + Install.WantedBy = ["graphical-session.target"]; + }; + }; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.6.0/src/Hyprpaper.cpp new/hyprpaper-0.7.0/src/Hyprpaper.cpp --- old/hyprpaper-0.6.0/src/Hyprpaper.cpp 2024-01-02 22:22:34.000000000 +0100 +++ new/hyprpaper-0.7.0/src/Hyprpaper.cpp 2024-04-28 23:25:36.000000000 +0200 @@ -15,11 +15,6 @@ removeOldHyprpaperImages(); - g_pConfigManager = std::make_unique<CConfigManager>(); - g_pIPCSocket = std::make_unique<CIPCSocket>(); - - g_pConfigManager->parse(); - m_sDisplay = (wl_display*)wl_display_connect(nullptr); if (!m_sDisplay) { @@ -27,25 +22,36 @@ exit(1); } + // run + wl_registry* registry = wl_display_get_registry(m_sDisplay); + wl_registry_add_listener(registry, &Events::registryListener, nullptr); + + wl_display_roundtrip(m_sDisplay); + + while (m_vMonitors.size() < 1 || m_vMonitors[0]->name.empty()) { + wl_display_dispatch(m_sDisplay); + } + + g_pConfigManager = std::make_unique<CConfigManager>(); + g_pIPCSocket = std::make_unique<CIPCSocket>(); + + g_pConfigManager->parse(); + preloadAllWallpapersFromConfig(); if (std::any_cast<Hyprlang::INT>(g_pConfigManager->config->getConfigValue("ipc"))) g_pIPCSocket->initialize(); - // run - wl_registry* registry = wl_display_get_registry(m_sDisplay); - wl_registry_add_listener(registry, &Events::registryListener, nullptr); - - while (wl_display_dispatch(m_sDisplay) != -1) { + do { std::lock_guard<std::mutex> lg(m_mtTickMutex); tick(true); - } + } while (wl_display_dispatch(m_sDisplay) != -1); unlockSingleInstance(); } void CHyprpaper::tick(bool force) { - bool reload = g_pIPCSocket->mainThreadParseRequest(); + bool reload = g_pIPCSocket && g_pIPCSocket->mainThreadParseRequest(); if (!reload && !force) return; @@ -453,6 +459,10 @@ void CHyprpaper::renderWallpaperForMonitor(SMonitor* pMonitor) { static auto* const PRENDERSPLASH = reinterpret_cast<Hyprlang::INT* const*>(g_pConfigManager->config->getConfigValuePtr("splash")->getDataStaticPtr()); static auto* const PSPLASHOFFSET = reinterpret_cast<Hyprlang::FLOAT* const*>(g_pConfigManager->config->getConfigValuePtr("splash_offset")->getDataStaticPtr()); + + if (!m_mMonitorActiveWallpaperTargets[pMonitor]) + recheckMonitor(pMonitor); + const auto PWALLPAPERTARGET = m_mMonitorActiveWallpaperTargets[pMonitor]; const auto CONTAIN = m_mMonitorWallpaperRenderData[pMonitor->name].contain; @@ -522,7 +532,11 @@ const auto FONTSIZE = (int)(DIMENSIONS.y / 76.0 / scale); cairo_set_font_size(PCAIRO, FONTSIZE); - cairo_set_source_rgba(PCAIRO, 1.0, 1.0, 1.0, 0.32); + static auto* const PSPLASHCOLOR = reinterpret_cast<Hyprlang::INT* const*>(g_pConfigManager->config->getConfigValuePtr("splash_color")->getDataStaticPtr()); + + Debug::log(LOG, "Splash color: %x", **PSPLASHCOLOR); + + cairo_set_source_rgba(PCAIRO, ((**PSPLASHCOLOR >> 16) & 0xFF) / 255.0, ((**PSPLASHCOLOR >> 8) & 0xFF) / 255.0, (**PSPLASHCOLOR & 0xFF) / 255.0, ((**PSPLASHCOLOR >> 24) & 0xFF) / 255.0); cairo_text_extents_t textExtents; cairo_text_extents(PCAIRO, SPLASH.c_str(), &textExtents); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.6.0/src/config/ConfigManager.cpp new/hyprpaper-0.7.0/src/config/ConfigManager.cpp --- old/hyprpaper-0.6.0/src/config/ConfigManager.cpp 2024-01-02 22:22:34.000000000 +0100 +++ new/hyprpaper-0.7.0/src/config/ConfigManager.cpp 2024-04-28 23:25:36.000000000 +0200 @@ -40,6 +40,20 @@ g_pHyprpaper->m_mMonitorActiveWallpapers[MONITOR] = WALLPAPER; g_pHyprpaper->m_mMonitorWallpaperRenderData[MONITOR].contain = contain; + if (MONITOR.empty()) { + for (auto& m : g_pHyprpaper->m_vMonitors) { + if (!m->hasATarget || m->wildcard) { + g_pHyprpaper->clearWallpaperFromMonitor(m->name); + g_pHyprpaper->m_mMonitorActiveWallpapers[m->name] = WALLPAPER; + g_pHyprpaper->m_mMonitorWallpaperRenderData[m->name].contain = contain; + } + } + } else { + const auto PMON = g_pHyprpaper->getMonitorFromName(MONITOR); + if (PMON) + PMON->wildcard = false; + } + return result; } @@ -70,17 +84,18 @@ std::vector<std::string> toUnload; for (auto& [name, target] : g_pHyprpaper->m_mWallpaperTargets) { - - bool exists = false; - for (auto& [mon, target2] : g_pHyprpaper->m_mMonitorActiveWallpaperTargets) { - if (&target == target2) { - exists = true; - break; + if (VALUE == "unused") { + bool exists = false; + for (auto& [mon, target2] : g_pHyprpaper->m_mMonitorActiveWallpaperTargets) { + if (&target == target2) { + exists = true; + break; + } } - } - if (exists) - continue; + if (exists) + continue; + } toUnload.emplace_back(name); } @@ -96,7 +111,7 @@ const std::string VALUE = V; auto WALLPAPER = VALUE; - if (VALUE == "all") + if (VALUE == "all" || VALUE == "unused") return handleUnloadAll(C, V); if (WALLPAPER[0] == '~') { @@ -118,9 +133,10 @@ config = std::make_unique<Hyprlang::CConfig>(configPath.c_str(), Hyprlang::SConfigOptions{.allowMissingConfig = true}); - config->addConfigValue("ipc", {1L}); - config->addConfigValue("splash", {1L}); - config->addConfigValue("splash_offset", {2.F}); + config->addConfigValue("ipc", Hyprlang::INT{1L}); + config->addConfigValue("splash", Hyprlang::INT{0L}); + config->addConfigValue("splash_offset", Hyprlang::FLOAT{2.F}); + config->addConfigValue("splash_color", Hyprlang::INT{0x55ffffff}); config->registerHandler(&handleWallpaper, "wallpaper", {.allowFlags = false}); config->registerHandler(&handleUnload, "unload", {.allowFlags = false}); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.6.0/src/events/Events.cpp new/hyprpaper-0.7.0/src/events/Events.cpp --- old/hyprpaper-0.6.0/src/events/Events.cpp 2024-01-02 22:22:34.000000000 +0100 +++ new/hyprpaper-0.7.0/src/events/Events.cpp 2024-04-28 23:25:36.000000000 +0200 @@ -1,72 +1,76 @@ #include "Events.hpp" #include "../Hyprpaper.hpp" -void Events::geometry(void *data, wl_output *output, int32_t x, int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, const char *make, const char *model, int32_t transform) { +void Events::geometry(void* data, wl_output* output, int32_t x, int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, const char* make, const char* model, int32_t transform) { // ignored } -void Events::mode(void *data, wl_output *output, uint32_t flags, int32_t width, int32_t height, int32_t refresh) { +void Events::mode(void* data, wl_output* output, uint32_t flags, int32_t width, int32_t height, int32_t refresh) { const auto PMONITOR = (SMonitor*)data; PMONITOR->size = Vector2D(width, height); } -void Events::done(void *data, wl_output *wl_output) { +void Events::done(void* data, wl_output* wl_output) { const auto PMONITOR = (SMonitor*)data; PMONITOR->readyForLS = true; std::lock_guard<std::mutex> lg(g_pHyprpaper->m_mtTickMutex); - g_pHyprpaper->tick(true); + if (g_pConfigManager) // don't tick if this is the first roundtrip + g_pHyprpaper->tick(true); } -void Events::scale(void *data, wl_output *wl_output, int32_t scale) { +void Events::scale(void* data, wl_output* wl_output, int32_t scale) { const auto PMONITOR = (SMonitor*)data; PMONITOR->scale = scale; } -void Events::name(void *data, wl_output *wl_output, const char *name) { +void Events::name(void* data, wl_output* wl_output, const char* name) { const auto PMONITOR = (SMonitor*)data; PMONITOR->name = name; } -void Events::description(void *data, wl_output *wl_output, const char *description) { +void Events::description(void* data, wl_output* wl_output, const char* description) { const auto PMONITOR = (SMonitor*)data; + // remove comma character from description. This allow monitor specific rules to work on monitor with comma on their description + std::string m_description = description; + std::erase(m_description, ','); - PMONITOR->description = description; + PMONITOR->description = m_description; } -void Events::handleCapabilities(void *data, wl_seat *wl_seat, uint32_t capabilities) { +void Events::handleCapabilities(void* data, wl_seat* wl_seat, uint32_t capabilities) { if (capabilities & WL_SEAT_CAPABILITY_POINTER) { wl_pointer_add_listener(wl_seat_get_pointer(wl_seat), &pointerListener, wl_seat); } } -void Events::handlePointerLeave(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface) { +void Events::handlePointerLeave(void* data, struct wl_pointer* wl_pointer, uint32_t serial, struct wl_surface* surface) { // ignored wl_surface_commit(surface); g_pHyprpaper->m_pLastMonitor = nullptr; } -void Events::handlePointerAxis(void *data, wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) { +void Events::handlePointerAxis(void* data, wl_pointer* wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) { // ignored } -void Events::handlePointerMotion(void *data, struct wl_pointer *wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { +void Events::handlePointerMotion(void* data, struct wl_pointer* wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { // ignored if (g_pHyprpaper->m_pLastMonitor) { wl_surface_commit(g_pHyprpaper->m_pLastMonitor->pCurrentLayerSurface->pSurface); } } -void Events::handlePointerButton(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t button_state) { +void Events::handlePointerButton(void* data, struct wl_pointer* wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t button_state) { // ignored } -void Events::handlePointerEnter(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y) { +void Events::handlePointerEnter(void* data, struct wl_pointer* wl_pointer, uint32_t serial, struct wl_surface* surface, wl_fixed_t surface_x, wl_fixed_t surface_y) { for (auto& mon : g_pHyprpaper->m_vMonitors) { if (mon->pCurrentLayerSurface->pSurface == surface) { g_pHyprpaper->m_pLastMonitor = mon.get(); @@ -79,7 +83,7 @@ } } -void Events::ls_configure(void *data, zwlr_layer_surface_v1 *surface, uint32_t serial, uint32_t width, uint32_t height) { +void Events::ls_configure(void* data, zwlr_layer_surface_v1* surface, uint32_t serial, uint32_t width, uint32_t height) { const auto PLAYERSURFACE = (CLayerSurface*)data; PLAYERSURFACE->m_pMonitor->size = Vector2D(width, height); @@ -91,7 +95,7 @@ Debug::log(LOG, "configure for %s", PLAYERSURFACE->m_pMonitor->name.c_str()); } -void Events::handleLSClosed(void *data, zwlr_layer_surface_v1 *zwlr_layer_surface_v1) { +void Events::handleLSClosed(void* data, zwlr_layer_surface_v1* zwlr_layer_surface_v1) { const auto PLAYERSURFACE = (CLayerSurface*)data; for (auto& m : g_pHyprpaper->m_vMonitors) { @@ -107,18 +111,18 @@ } } -void Events::handleGlobal(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { +void Events::handleGlobal(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version) { if (strcmp(interface, wl_compositor_interface.name) == 0) { - g_pHyprpaper->m_sCompositor = (wl_compositor *)wl_registry_bind(registry, name, &wl_compositor_interface, 4); + g_pHyprpaper->m_sCompositor = (wl_compositor*)wl_registry_bind(registry, name, &wl_compositor_interface, 4); } else if (strcmp(interface, wl_shm_interface.name) == 0) { - g_pHyprpaper->m_sSHM = (wl_shm *)wl_registry_bind(registry, name, &wl_shm_interface, 1); + g_pHyprpaper->m_sSHM = (wl_shm*)wl_registry_bind(registry, name, &wl_shm_interface, 1); } else if (strcmp(interface, wl_output_interface.name) == 0) { g_pHyprpaper->m_mtTickMutex.lock(); const auto PMONITOR = g_pHyprpaper->m_vMonitors.emplace_back(std::make_unique<SMonitor>()).get(); PMONITOR->wayland_name = name; PMONITOR->name = ""; - PMONITOR->output = (wl_output *)wl_registry_bind(registry, name, &wl_output_interface, 4); + PMONITOR->output = (wl_output*)wl_registry_bind(registry, name, &wl_output_interface, 4); wl_output_add_listener(PMONITOR->output, &Events::outputListener, PMONITOR); g_pHyprpaper->m_mtTickMutex.unlock(); @@ -133,7 +137,7 @@ } } -void Events::handleGlobalRemove(void *data, struct wl_registry *registry, uint32_t name) { +void Events::handleGlobalRemove(void* data, struct wl_registry* registry, uint32_t name) { for (auto& m : g_pHyprpaper->m_vMonitors) { if (m->wayland_name == name) { Debug::log(LOG, "Destroying output %s", m->name.c_str()); @@ -144,10 +148,10 @@ } } -void Events::handlePreferredScale(void *data, wp_fractional_scale_v1* fractionalScaleInfo, uint32_t scale) { +void Events::handlePreferredScale(void* data, wp_fractional_scale_v1* fractionalScaleInfo, uint32_t scale) { const double SCALE = scale / 120.0; - CLayerSurface *const pLS = (CLayerSurface*)data; + CLayerSurface* const pLS = (CLayerSurface*)data; Debug::log(LOG, "handlePreferredScale: %.2lf for %lx", SCALE, pLS); @@ -157,4 +161,3 @@ g_pHyprpaper->tick(true); } } - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.6.0/src/helpers/Monitor.hpp new/hyprpaper-0.7.0/src/helpers/Monitor.hpp --- old/hyprpaper-0.6.0/src/helpers/Monitor.hpp 2024-01-02 22:22:34.000000000 +0100 +++ new/hyprpaper-0.7.0/src/helpers/Monitor.hpp 2024-04-28 23:25:36.000000000 +0200 @@ -1,8 +1,8 @@ #pragma once #include "../defines.hpp" -#include "PoolBuffer.hpp" #include "../render/LayerSurface.hpp" +#include "PoolBuffer.hpp" struct SMonitor { std::string name = ""; @@ -15,6 +15,8 @@ bool readyForLS = false; bool hasATarget = true; + bool wildcard = true; + uint32_t configureSerial = 0; SPoolBuffer buffer; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprpaper-0.6.0/src/ipc/Socket.cpp new/hyprpaper-0.7.0/src/ipc/Socket.cpp --- old/hyprpaper-0.6.0/src/ipc/Socket.cpp 2024-01-02 22:22:34.000000000 +0100 +++ new/hyprpaper-0.7.0/src/ipc/Socket.cpp 2024-04-28 23:25:36.000000000 +0200 @@ -11,6 +11,7 @@ #include <sys/types.h> #include <sys/un.h> #include <unistd.h> +#include <pwd.h> void CIPCSocket::initialize() { std::thread([&]() { @@ -24,12 +25,14 @@ sockaddr_un SERVERADDRESS = {.sun_family = AF_UNIX}; const auto HISenv = getenv("HYPRLAND_INSTANCE_SIGNATURE"); + const std::string USERID = std::to_string(getpwuid(getuid())->pw_uid); - std::string socketPath = HISenv ? "/tmp/hypr/" + std::string(HISenv) + "/.hyprpaper.sock" : "/tmp/hypr/.hyprpaper.sock"; + const auto USERDIR = "/run/user/" + USERID + "/hypr/"; - if (!HISenv) { - mkdir("/tmp/hypr", S_IRWXU | S_IRWXG); - } + std::string socketPath = HISenv ? USERDIR + std::string(HISenv) + "/.hyprpaper.sock" : USERDIR + ".hyprpaper.sock"; + + if (!HISenv) + mkdir(USERDIR.c_str(), S_IRWXU); unlink(socketPath.c_str()); @@ -90,34 +93,75 @@ std::string copy = m_szRequest; - // now we can work on the copy - if (copy == "") return false; + // now we can work on the copy + Debug::log(LOG, "Received a request: %s", copy.c_str()); - // parse + // set default reply + m_szReply = "ok"; + m_bReplyReady = true; + m_bRequestReady = false; + + // config commands if (copy.find("wallpaper") == 0 || copy.find("preload") == 0 || copy.find("unload") == 0) { const auto RESULT = g_pConfigManager->config->parseDynamic(copy.substr(0, copy.find_first_of(' ')).c_str(), copy.substr(copy.find_first_of(' ') + 1).c_str()); if (RESULT.error) { m_szReply = RESULT.getError(); - m_bReplyReady = true; - m_bRequestReady = false; return false; } - } else { - m_szReply = "invalid command"; - m_bReplyReady = true; - m_bRequestReady = false; - return false; + + return true; } - m_szReply = "ok"; - m_bReplyReady = true; - m_bRequestReady = false; + if (copy.find("listloaded") == 0) { + + const auto numWallpapersLoaded = g_pHyprpaper->m_mWallpaperTargets.size(); + Debug::log(LOG, "numWallpapersLoaded: %d", numWallpapersLoaded); + + if (numWallpapersLoaded == 0) { + m_szReply = "no wallpapers loaded"; + return false; + } + + m_szReply = ""; + long unsigned int i = 0; + for (auto& [name, target] : g_pHyprpaper->m_mWallpaperTargets) { + m_szReply += name; + i++; + if (i < numWallpapersLoaded) + m_szReply += '\n'; // dont add newline on last entry + } + + return true; + } + + if (copy.find("listactive") == 0) { + + const auto numWallpapersActive = g_pHyprpaper->m_mMonitorActiveWallpapers.size(); + Debug::log(LOG, "numWallpapersActive: %d", numWallpapersActive); + + if (numWallpapersActive == 0) { + m_szReply = "no wallpapers active"; + return false; + } + + m_szReply = ""; + long unsigned int i = 0; + for (auto& [mon, path1] : g_pHyprpaper->m_mMonitorActiveWallpapers) { + m_szReply += mon + " = " + path1; + i++; + if (i < numWallpapersActive) + m_szReply += '\n'; // dont add newline on last entry + } + + return true; + } - return true; + m_szReply = "invalid command"; + return false; }