Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DISCUSSION] Best way to change wallpaper with hyprpaper? #108

Open
zft9xgy opened this issue Nov 16, 2023 · 19 comments
Open

[DISCUSSION] Best way to change wallpaper with hyprpaper? #108

zft9xgy opened this issue Nov 16, 2023 · 19 comments

Comments

@zft9xgy
Copy link

zft9xgy commented Nov 16, 2023

Hello everyone, I'm opening this topic to discuss what is the best way to change wallpaper in hyprpaper:

This is how I do it right now, basically reset the hyprpaper.conf file and then overwrite it with the new info. is this the best way to change the wallpaper?

echo '' > /.config/hypr/hyprpaper.conf
echo "preload = /new-wallpaper-path/" >>  /.config/hypr/hyprpaper.conf
echo "wallpaper =,/new-wallpaper-path/" >>  /.config/hypr/hyprpaper.conf

TL;DR

Basically i use this to change wallpaper with hyprper and i use it in 3 different scripts, which are:

  • random-wall.sh, it takes a random wallpaper from my wallpapers folder and place it,
  • select-wall.sh, use wofi to list all the wallpapers from my wall folders.
  • set-wallpaper.sh, which sets the wallpaper that is passed as the first parameter.

With the set-wallpaper.sh script I have made a setting in Thunar, which allows me to set an image as wallpaper by right clicking.

@vaxerski
Copy link
Member

vaxerski commented Nov 16, 2023

hyprctl hyprpaper ... is better

@zft9xgy
Copy link
Author

zft9xgy commented Nov 16, 2023

It seem easy, but, if you want to use hyprctl hyprpaper wallpaper "DP-1,~/Pictures/myepicpng.png" the wallpaper need to be preloaded, so i think i will stick to my scrips, which it works.

Buy thank you!!

@vaxerski
Copy link
Member

you can make two calls, one for preload and one for wallpaper

@zft9xgy
Copy link
Author

zft9xgy commented Nov 23, 2023

Hi again, sorry for the delay. Still didnt make it work with hyperctl.

So just as example:
My wallpaper folder got around 100 differents wallpapers, and the names are "wallpapaer-1" with out .png or .jpg, with out forrmat sufix.

Trying you way will be:

hyprctl hyprpaper preload "~/wallpapers/wallpaper-1"
hyprctl hyprpaper monitor ",~/wallpapers/wallpaper-1"

For me this didnt work. Error: File not found, could be because of sufix ?

Thanks for the help

@vaxerski
Copy link
Member

what if you specify the monitor explicitly in monitor?

@zft9xgy
Copy link
Author

zft9xgy commented Nov 24, 2023

Sorry it was a mistake: writting the post:

hyprctl hyprpaper preload "~/wallpapers/wallpaper-1" 
hyprctl hyprpaper wallpaper ",~/wallpapers/wallpaper-1"

But, is not working for me. Thanks again.

@keithbowes
Copy link

hyprctl hyprpaper ... is better

Or for those of us using hyprpaper with another compositor:
printf ... | socat UNIX-CONNECT:/tmp/hypr/.hyperpaper.sock -

Unfortunately, only one user is permitted at a time that way. It should go to /tmp/hypr-${USER} instead.

@simonwiles
Copy link

simonwiles commented Dec 13, 2023

what if you specify the monitor explicitly in monitor?

(for me, at least) it does work when specifying the monitor explicitly, but it doesn't if I use hyprctl hyprpaper wallpaper ",~/wallpapers/wallpaper-1"; which is a shame, because that's what I actually want to do. Is this intended/expected behaviour, or does it constitute a bug?

@askdkc
Copy link

askdkc commented Jan 16, 2024

@simonwiles

Just created a bash script which randomly changes background image.
It automatically gets monitor name by running hyprctl monitors | grep Monitor | awk '{print $2}'

#!/bin/bash

directory=~/YOUR_BACKGROUND/IMAGE/DIRECTORY
monitor=`hyprctl monitors | grep Monitor | awk '{print $2}'`

if [ -d "$directory" ]; then
    random_background=$(ls $directory/*.jpg | shuf -n 1)

    hyprctl hyprpaper unload all
    hyprctl hyprpaper preload $random_background
    hyprctl hyprpaper wallpaper "$monitor, $random_background"

fi

@grapeofwrath
Copy link

grapeofwrath commented Feb 17, 2024

@simonwiles

Just created a bash script which randomly changes background image. It automatically gets monitor name by running hyprctl monitors | grep Monitor | awk '{print $2}'

#!/bin/bash

directory=~/YOUR_BACKGROUND/IMAGE/DIRECTORY
monitor=`hyprctl monitors | grep Monitor | awk '{print $2}'`

if [ -d "$directory" ]; then
    random_background=$(ls $directory/*.jpg | shuf -n 1)

    hyprctl hyprpaper unload all
    hyprctl hyprpaper preload $random_background
    hyprctl hyprpaper wallpaper "$monitor, $random_background"

fi

Took your idea with a lil inspiration from ZaneyOS and made a script that changes the wallpaper for all monitors every 15m. It's for a Nix config but one can easily make it a normal script if necessary.

{ pkgs, username, wallpaperDir, wallpaperGit }:

pkgs.writeShellScriptBin "wallpaper" ''
  monitor=(`hyprctl monitors | grep Monitor | awk '{print $2}'`)
  wal=$(find ${wallpaperDir} -name '*' | awk '!/.git/' | tail -n +2 | shuf -n 1)
  cache=""

  if [ -d ${wallpaperDir} ]; then
    cd ${wallpaperDir}
    git pull
  else
    ${pkgs.git}/bin/git clone ${wallpaperGit} ${wallpaperDir}
    chown -R ${username}:users ${wallpaperDir}
  fi

  while true; do
    if [[ $cache == $wal ]]; then
      wal=$(find ${wallpaperDir} -name '*' | awk '!/.git/' | tail -n +2 | shuf -n 1)
    else
      cache=$wal
      hyprctl hyprpaper unload all
      hyprctl hyprpaper preload $wal
      for m in ''${monitor[@]}; do
        hyprctl hyprpaper wallpaper "$m,$wal"
      done
    fi
    sleep 900
  done
''

@askdkc
Copy link

askdkc commented Feb 17, 2024

@grapeofwrath

Nice work!!
Love seeing OSS synergy.

@ertugrulgacal
Copy link

ertugrulgacal commented May 5, 2024

Here is the bash script I use to change the wallpaper on all my monitors.

#!/bin/bash

# Check if a file argument was provided
if [ -z "$1" ]; then
    echo "Error: Please provide a wallpaper file as an argument."
    exit 1
fi

# Check if the file exists
if [ ! -f "$1" ]; then
    echo "Error: File not found: $1"
    exit 1
fi

# Path to your hyprpaper configuration file
hyprpaper_config_file="$HOME/.config/hypr/hyprpaper.conf"

# Update the config file with the new wallpaper path 
sed -i -e "s|^preload = .*$|preload = $1|" \
       -e "s|^wallpaper = .*$|wallpaper = ,$1|" \
       "$hyprpaper_config_file"

# Reload hyprpaper
killall -e hyprpaper & 
sleep 1; 
hyprpaper &

# Let the user know it's done
echo "Wallpaper settings in hyprpaper.conf updated successfully."

usage:
./change_wallpaper.sh /path/to/your/wallpaper

@ecarlson94
Copy link

ecarlson94 commented May 13, 2024

I created a home-manager module that sets up hyprpaper and a systemd user service to randomize the wallpaper on an interval. Additionally, it uses lutgen to theme all images within a directory local to the nix configuration. So, no matter the image, it will always be on brand!

{
  pkgs,
  lib,
  ...
}:
with lib;
with builtins; let
  theme = {
    name = "catppuccin-mocha"; # Run `nix-shell -p lutgen --command 'lutgen apply -p ""` to see supported color palettes
    wallpapers = ./some/local/directory/of/images;
  };

  themedWallpaper = wallpaper:
    pkgs.stdenv.mkDerivation rec {
      name = "${theme.name}-${baseNameOf wallpaper}";
      nativeBuildInputs = [pkgs.lutgen];

      phases = ["buildPhase" "installPhase"];

      buildPhase = ''
        cp ${wallpaper} ./${name}
        lutgen apply -p ${theme.name} ${name} -o themed
      '';

      installPhase = ''
        cp themed/${name} $out
      '';
    };

  wallpapers = filesystem.listFilesRecursive theme.wallpapers;
  themedWallpapers = listToAttrs (map (wallpaper: {
      name = "${baseNameOf wallpaper}";
      value = themedWallpaper wallpaper;
    })
    wallpapers);

  wallpaperBashArray = "(\"${strings.concatStrings (strings.intersperse "\" \"" (map (wallpaper: "${wallpaper}") (attrValues themedWallpapers)))}\")";
  wallpaperRandomizer = pkgs.writeShellScriptBin "wallpaperRandomizer" ''
    wallpapers=${wallpaperBashArray}
    rand=$[$RANDOM % ''${#wallpapers[@]}]
    wallpaper=''${wallpapers[$rand]}

    monitor=(`hyprctl monitors | grep Monitor | awk '{print $2}'`)
    hyprctl hyprpaper unload all
    hyprctl hyprpaper preload $wallpaper
    for m in ''${monitor[@]}; do
      hyprctl hyprpaper wallpaper "$m,$wallpaper"
    done
  '';
in {
  home.packages = [wallpaperRandomizer];

  services.hyprpaper = {
    enable = true;

    settings = {
      ipc = "on";
      splash = false;
      splash_offset = 2.0;
    };
  };

  systemd.user = {
    services.wallpaperRandomizer = {
      Install = {WantedBy = ["graphical-session.target"];};

      Unit = {
        Description = "Set random desktop background using hyprpaper";
        After = ["graphical-session-pre.target"];
        PartOf = ["graphical-session.target"];
      };

      Service = {
        Type = "oneshot";
        ExecStart = "${wallpaperRandomizer}/bin/wallpaperRandomizer";
        IOSchedulingClass = "idle";
      };
    };

    timers.wallpaperRandomizer = {
      Unit = {Description = "Set random desktop background using hyprpaper on an interval";};

      Timer = {OnUnitActiveSec = "1h";};

      Install = {WantedBy = ["timers.target"];};
    };
  };
}

You can also manually trigger it by running wallpaperRandomizer in a shell. I know this is very nix specific, but if that is your use case, you're in luck.

@ecarlson94
Copy link

Here is a version without lutgen for those who just want something simple:

{
  pkgs,
  lib,
  ...
}:
with lib; let
  theme = {
    name = "catppuccin-mocha"; # Run `nix-shell -p lutgen --command 'lutgen apply -p ""` to see supported color palettes
    wallpapers = ./some/local/directory/of/images;
  };

  wallpapers = filesystem.listFilesRecursive theme.wallpapers;

  wallpaperBashArray = "(\"${strings.concatStrings (strings.intersperse "\" \"" (map (wallpaper: "${wallpaper}") wallpapers))}\")";
  wallpaperRandomizer = pkgs.writeShellScriptBin "wallpaperRandomizer" ''
    wallpapers=${wallpaperBashArray}
    rand=$[$RANDOM % ''${#wallpapers[@]}]
    wallpaper=''${wallpapers[$rand]}

    monitor=(`hyprctl monitors | grep Monitor | awk '{print $2}'`)
    hyprctl hyprpaper unload all
    hyprctl hyprpaper preload $wallpaper
    for m in ''${monitor[@]}; do
      hyprctl hyprpaper wallpaper "$m,$wallpaper"
    done
  '';
in {
  home.packages = [wallpaperRandomizer];

  services.hyprpaper = {
    enable = true;

    settings = {
      ipc = "on";
      splash = false;
      splash_offset = 2.0;
    };
  };

  systemd.user = {
    services.wallpaperRandomizer = {
      Install = {WantedBy = ["graphical-session.target"];};

      Unit = {
        Description = "Set random desktop background using hyprpaper";
        After = ["graphical-session-pre.target"];
        PartOf = ["graphical-session.target"];
      };

      Service = {
        Type = "oneshot";
        ExecStart = "${wallpaperRandomizer}/bin/wallpaperRandomizer";
        IOSchedulingClass = "idle";
      };
    };

    timers.wallpaperRandomizer = {
      Unit = {Description = "Set random desktop background using hyprpaper on an interval";};

      Timer = {OnUnitActiveSec = "1h";};

      Install = {WantedBy = ["timers.target"];};
    };
  };
}

@ebiscaia
Copy link

Hi all,

Came up a similar version of the script with some modifications to make sure that my wallpaper orientation would match the orientation of the screen

!/bin/bash

while true; do
    killall hyprpaper
    FOLDER=~/.config/hypr

    # Overwrite config file with a blank version of it
    cp $FOLDER/hyprpaper.conf.bak $FOLDER/hyprpaper.conf

    # Start with blank values for preload and load variables
    PRELOAD=""
    LOAD=""

    # Loop accross all monitors
    for MONITOR in $(hyprctl monitors | awk '/^Monitor/ {print $2}'); do

        PATHPIC="$HOME/Pictures/Wallpapers/" # Determine the screen orientation

        # Get the value of orientation from hyprctl monitor
        ORIENTATION=$(hyprctl monitors | awk '/'"$MONITOR"'/{c=15} c&&c--' | awk '/transform/{print$2}')

        if ((ORIENTATION % 2 == 0)); then
            ORIENTATION="Landscape"
        else
            ORIENTATION="Portrait"
        fi

        # Append the screen orientation to the path
        PATHPIC+="$ORIENTATION/"

        # Now get a random file name and append to the path
        IMAGE=$(find "$PATHPIC" -name "*" -type f | shuf -n 1)

        PRELOAD+="preload = $IMAGE\n"
        LOAD+="wallpaper = $MONITOR,$IMAGE\n"

    done

    # Append the file name with the preload and load commands
    sed -i "/\# Preloads/a $PRELOAD" $FOLDER/hyprpaper.conf
    sed -i "/\# Wallpaper/a $LOAD" $FOLDER/hyprpaper.conf
    sed -i "s/^[{}]//" $FOLDER/hyprpaper.conf

    # Execute hyprpaper
    hyprpaper --config ~/.config/hypr/hyprpaper.conf &

    sleep 3600
done

That's all and good. However, if I try to use my user crontab (instead of looping and sleeping), I have got the following message:

[LOG] Welcome to hyprpaper!
built from commit  ()
[LOG] Using config location /home/eddie/.config/hypr/hyprpaper.conf.
[LOG] Cleaned old hyprpaper preloads (6), removing 75.6MB
[CRITICAL] No wayland compositor running!

Any idea why?

@rofe33
Copy link

rofe33 commented Jun 22, 2024

Hello all,

Thoughts on pyprpaper? It's a python script that randomly change wallpapers from a given directory or directories. I use the socket module, so there's no need to have hyprland installed.

For now the script randomly choose the wallpapers. If you have any other implementations to add, I would love to add them.

My current setup:

The hyprpaper.conf file is:

splash = off

I have a exec-once in the hyprland.conf:

exec-once = pyprpaper -m $(hyprctl -j monitors | jq -r '.[].name' | tr '\n' ' ') -- /path/to/directory

Note: You can create a cron job or a systemd timer to change periodically the wallpaper.

@rofe33
Copy link

rofe33 commented Jun 29, 2024

Note: You can create a cron job or a systemd timer to change periodically the wallpaper.

Hello,

I updated pyprpaper to include a --timer option, then we will be able to change the wallpaper each n seconds.

Now there is no need to use cron jobs or systemd timer.

@0x15BA88FF
Copy link

Hello everyone,

I use this simple script to slideshow my hyprpapers but after a while is becomes plain color instead of rendering images

#!/bin/bash

interval=300
walldir=~/.local/share/wallpapers/
monitor=`hyprctl monitors | grep Monitor | awk '{print $2}'`

while true; do
    find $walldir -type f | shuf | while read -r img; do
        wal --cols16 -n -i  $img -p theme
        ln -f "$img" ~/.local/share/wallpapers/background

        hyprctl hyprpaper unload all
        hyprctl hyprpaper preload $img
        hyprctl hyprpaper wallpaper "$monitor, $img"

        sleep $interval
    done
done

I think it might have something to do with cache but im still yet to find out
hopefully this is handy to someone :)

@0x15BA88FF
Copy link

I took a look a round and realized that hyprpaper wasn't even running so the problem was probably because an unsupported wallpaper image format was used but i'm yet to check the logs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests