7.9 KiB
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 Pywal’s 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 image’s average color and sorts by HSV. Renames files to:
NN_Wallpaper_<hex>.ext. - Supported extensions: .png, .jpg, .jpeg
- Optional progress bar with tqdm.
- Analyzes each image’s average color and sorts by HSV. Renames files to:
-
wallpapersync.sh
- Runs the sorter and then rsyncs wallpapers from a source directory to a destination repo directory.
- Uses
--deleteto mirror source to destination.
-
pywal/update-waybar-theme.sh
- Given an image path, runs
wal -ito generate a color scheme, copies Pywal’s Waybar CSS, and reloads Waybar.
- Given an image path, runs
-
pywal/wallpapermenu.sh
- Opens an nsxiv selection window, runs wal on the chosen image, sets swaybg, and triggers the glue script
pywal16.sh.
- Opens an nsxiv selection window, runs wal on the chosen image, sets swaybg, and triggers the glue script
-
pywal/pywal16.sh
- Helper run by wal’s
-ohook. Updates Waybar theme, nudges apps (nwg-look, qutebrowser), shows a notification, runs walcord, and sets RGB with pywal-openrgb.
- Helper run by wal’s
-
pywal/pywal-openrgb.py
- Picks a Pywal palette color from
~/.cache/wal/colors.jsonand updates OpenRGB using theopenrgbCLI.
- Picks a Pywal palette color from
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 distro’s 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, paddingNNto 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-runfirst 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
Repowith--deleteto mirror content
Warning:
--deleteremoves files in the destination that aren’t 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 -ito generate a scheme from the image - Copies
${HOME}/.cache/wal/colors-waybar.cssto${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 ispywal16.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 wal’s -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.jsongenerated by wal - Takes
color3and calls theopenrgbCLI: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/"
- Current:
-
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 useswal -1(digit one) which is likely a typo forwal -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
- In the
-
pywal/pywal-openrgb.py:
- Imports
OpenRGBClient/RGBColorbut currently uses theopenrgbCLI via subprocess. You can either remove unused imports or switch to the Python API for direct control if desired. colors_fileis hardcoded; preferPath(os.environ["HOME"]) / ".cache/wal/colors.json"for portability.
- Imports
-
wallpapersync.sh:
- Uses absolute paths. Consider parameterizing (flags/env) or converting to
$HOME-based defaults. --deleteis destructive if misconfigured; add a--dry-runoption for rsync (e.g.,-n) for safety.
- Uses absolute paths. Consider parameterizing (flags/env) or converting to
-
Python typing:
- The script uses
tuple[int, int, int] | Nonewhich requires Python 3.10+. For older versions, switch toOptional[Tuple[int,int,int]].
- The script uses
Tips
- Preview renames first:
python sort_images_by_color.py "$HOME/Pictures/Wallpapers" --dry-run - Keep a backup or run inside a copy if you’re 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.