Wallpaper Automation and Color Sync Scripts

Collection of small scripts to sort wallpapers by color and keep your Linux desktop theme in sync with the current wallpaper using Pywal. Includes helpers for Waybar, Sway background, OpenRGB, and simple wallpaper selection.

Tested on a Wayland/Sway setup. Adjust paths for your environment.

Repository Structure

.
├── sort_images_by_color.py        # Python: sort/rename images by average color
├── wallpapersync.sh               # Bash: resort and rsync wallpapers between folders
└── pywal/
    ├── pywal-openrgb.py           # Python: set OpenRGB color to Pywals palette color
    ├── pywal16.sh                 # Bash: glue script after wal to refresh apps/theme
    ├── update-waybar-theme.sh     # Bash: run wal on image and refresh Waybar CSS
    └── wallpapermenu.sh           # Bash: pick wallpaper with nsxiv, wal, swaybg

Summary of Scripts

  • sort_images_by_color.py

    • Analyzes each images average color and sorts by HSV. Renames files to: NN_Wallpaper_<hex>.ext.
    • Supported extensions: .png, .jpg, .jpeg
    • Optional progress bar with tqdm.
  • wallpapersync.sh

    • Runs the sorter and then rsyncs wallpapers from a source directory to a destination repo directory.
    • Uses --delete to mirror source to destination.
  • pywal/update-waybar-theme.sh

    • Given an image path, runs wal -i to generate a color scheme, copies Pywals Waybar CSS, and reloads Waybar.
  • pywal/wallpapermenu.sh

    • Opens an nsxiv selection window, runs wal on the chosen image, sets swaybg, and triggers the glue script pywal16.sh.
  • pywal/pywal16.sh

    • Helper run by wals -o hook. Updates Waybar theme, nudges apps (nwg-look, qutebrowser), shows a notification, runs walcord, and sets RGB with pywal-openrgb.
  • pywal/pywal-openrgb.py

    • Picks a Pywal palette color from ~/.cache/wal/colors.json and updates OpenRGB using the openrgb CLI.

Requirements

  • Python 3.10+ (PEP 604 style union types are used)
  • Python packages:
    • Pillow (required)
    • tqdm (optional; progress bar)
    • openrgb-python (imported but not strictly required by current implementation)
  • System/CLI tools:
    • pywal (wal)
    • nsxiv
    • swaybg
    • waybar
    • rsync
    • openrgb (CLI on PATH)
    • walcord (Discord theme updater)
    • nwg-look
    • qutebrowser (optional; for config reload)
    • libnotify/notify-send
    • killall

Install Python deps:

pip install Pillow tqdm openrgb-python

Install system tools via your distros package manager (names may vary):

# Arch examples
sudo pacman -S python-pillow python-pip rsync nsxiv swaybg waybar python-openrgb
paru -S pywal walcord nwg-look

Configuration

Several scripts contain hardcoded user-specific paths. Update these for your system:

  • wallpapersync.sh

    • Repo="/home/Nicholai/Pictures/Wallpapers"
    • Dir_Wallpapers="/home/Nicholai/Nextcloud/Mini-Arch/Wallpaper-Repo/"
    • Script_Resort="/home/Nicholai/scripts/sort_images_by_color.py"
  • pywal/pywal-openrgb.py

    • colors_file = "/home/Nicholai/.cache/wal/colors.json" (change to your $HOME)
  • pywal/pywal16.sh

    • Calls python /home/Nicholai/scripts/pywal/pywal-openrgb.py; change to your path
    • cp lines use "~" inside quotes which does not expand; see Known issues for the fix
  • pywal/wallpapermenu.sh

    • FOLDER=~/Pictures/Wallpapers
    • SCRIPT=~/scripts/pywal/pywal16.sh

Tip: Prefer $HOME over a literal absolute path for portability, e.g. "$HOME/.cache/wal/colors.json".

Usage

1) Sort and Rename Images by Average Color

python sort_images_by_color.py /path/to/wallpapers
# Dry run (no renames performed)
python sort_images_by_color.py /path/to/wallpapers --dry-run

What it does:

  • Reads .png/.jpg/.jpeg in the directory
  • Computes average color per image (1×1 downscale), converts to HSV
  • Sorts by HSV and renames to NN_Wallpaper_<hex>.ext, padding NN to list length

Example output (dry run):

Found 42 images. Analyzing colors...

Renaming 42 images...
--- DRY RUN --- (No files will be renamed)
  'img_1234.jpg' -> '01_Wallpaper_aabbcc.jpg'
  'beach.png'    -> '02_Wallpaper_334455.png'
...

Notes:

  • Corrupt/unsupported images are skipped.
  • If a target name already exists, it will skip that file.
  • Run with --dry-run first to preview results.

2) Sync Wallpapers Between Folders

Edit the top variables in wallpapersync.sh, then:

./wallpapersync.sh

What it does:

  • Runs the Python sorter on Dir_Wallpapers
  • rsyncs to Repo with --delete to mirror content

Warning:

  • --delete removes files in the destination that arent present in the source. Be sure paths are correct.

3) Apply Pywal theme and refresh Waybar

./pywal/update-waybar-theme.sh /path/to/image.jpg

What it does:

  • Runs wal -i to generate a scheme from the image
  • Copies ${HOME}/.cache/wal/colors-waybar.css to ${HOME}/.config/waybar/
  • Reloads Waybar via killall -SIGUSR2 waybar

4) Pick a Wallpaper via nsxiv and Apply Everywhere

./pywal/wallpapermenu.sh

What it does:

  • Launches nsxiv to pick an image from FOLDER
  • Runs wal -i "$CHOICE" -o $SCRIPT (SCRIPT is pywal16.sh)
  • Kills any running swaybg and sets the selection: swaybg -m fill -i "$CHOICE"

Also supports arguments (intended):

  • 1 arg mode: ./wallpapermenu.sh /path/to/image
  • 2 arg mode: ./wallpapermenu.sh /path/to/image some-theme (see Known issues for arg parsing quirks)

5) Post-wal glue script (apps/theme refresh)

pywal/pywal16.sh is meant to run as wals -o hook:

  • Updates Waybar theme CSS
  • Optional refresh signals for Waybar (commented)
  • Runs nwg-look -x
  • Reloads qutebrowser config if running
  • Notify user via notify-send
  • Runs walcord
  • Sets OpenRGB color via pywal-openrgb.py

6) Sync OpenRGB to Pywal color

python pywal/pywal-openrgb.py

What it does:

  • Reads ~/.cache/wal/colors.json generated by wal
  • Takes color3 and calls the openrgb CLI: openrgb --color <hex>

Requirements:

  • OpenRGB CLI on PATH (no server connection needed for this usage)

Known Issues and Suggested Improvements

  • pywal/pywal16.sh: ~ does not expand inside quotes for cp

    • Current:
      cp "~/.cache/wal/colors-waybar.css" "~/.config/waybar/"
      
    • Fix:
      cp "$HOME/.cache/wal/colors-waybar.css" "$HOME/.config/waybar/"
      
  • pywal/wallpapermenu.sh: argument handling

    • In the 1) case it references $CHOICE (undefined when called with 1 arg). It should use $1.
    • In the 2) case it uses wal -1 (digit one) which is likely a typo for wal -i.
    • A robust version would be:
      case "$#" in
        0) menu;;
        1) wal -i "$1" -o "$SCRIPT";;
        2) wal -i "$1" --theme "$2" -o "$SCRIPT";;
        *) exit 0 ;;
      esac
      
  • pywal/pywal-openrgb.py:

    • Imports OpenRGBClient/RGBColor but currently uses the openrgb CLI via subprocess. You can either remove unused imports or switch to the Python API for direct control if desired.
    • colors_file is hardcoded; prefer Path(os.environ["HOME"]) / ".cache/wal/colors.json" for portability.
  • wallpapersync.sh:

    • Uses absolute paths. Consider parameterizing (flags/env) or converting to $HOME-based defaults.
    • --delete is destructive if misconfigured; add a --dry-run option for rsync (e.g., -n) for safety.
  • Python typing:

    • The script uses tuple[int, int, int] | None which requires Python 3.10+. For older versions, switch to Optional[Tuple[int,int,int]].

Tips

  • Preview renames first:
    python sort_images_by_color.py "$HOME/Pictures/Wallpapers" --dry-run
    
  • Keep a backup or run inside a copy if youre unsure.
  • Consider a udev/systemd user service to re-run wal and pywal16.sh on login or on wallpaper change events.

License

Add a license if you plan to share/distribute. Common choices: MIT, Apache-2.0, GPL-3.0.

Credits

Description
A compilation of my scripts folder from my home directory
Readme 38 KiB
Languages
Python 83.8%
Shell 16.2%