Add detailed comments to script and comprehensive README
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a46b21a763
commit
4c2b5052e3
2 changed files with 239 additions and 17 deletions
153
README.md
Normal file
153
README.md
Normal file
|
|
@ -0,0 +1,153 @@
|
||||||
|
# Motion Wallpaper - Omarchy
|
||||||
|
|
||||||
|
Animated video wallpapers for [Omarchy](https://omarchy.com) (Arch Linux + Hyprland).
|
||||||
|
|
||||||
|
Uses [mpvpaper](https://github.com/GhostNaN/mpvpaper) to play any video file as your desktop wallpaper, with a simple toggle to switch between video and your normal static wallpaper.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/28allday/Motion-Wallpaper-Omarchy.git
|
||||||
|
cd Motion-Wallpaper-Omarchy
|
||||||
|
chmod +x wallpaper.sh
|
||||||
|
./wallpaper.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
The installer handles all dependencies automatically.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- **OS**: [Omarchy](https://omarchy.com) (Arch Linux)
|
||||||
|
- **Compositor**: Hyprland
|
||||||
|
- **AUR Helper**: yay or paru (for mpvpaper)
|
||||||
|
|
||||||
|
## What It Installs
|
||||||
|
|
||||||
|
### Packages
|
||||||
|
|
||||||
|
| Package | Source | Purpose |
|
||||||
|
|---------|--------|---------|
|
||||||
|
| `mpv` | Official repos | Video player engine (decodes and renders video) |
|
||||||
|
| `jq` | Official repos | Parses monitor info from Hyprland |
|
||||||
|
| `zenity` | Official repos | GUI dialogs (file picker, confirmations) |
|
||||||
|
| `mpvpaper` | AUR | Wayland wallpaper daemon that uses mpv as its backend |
|
||||||
|
|
||||||
|
### Files Created
|
||||||
|
|
||||||
|
| Path | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| `~/.local/bin/motion-wallpaper-toggle` | Toggle script (on/off switch) |
|
||||||
|
| `~/.local/share/applications/motion-wallpaper-toggle.desktop` | App launcher entry |
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### From App Launcher
|
||||||
|
|
||||||
|
Search for **"Motion Wallpaper"** in Walker or your app launcher.
|
||||||
|
|
||||||
|
### From Terminal
|
||||||
|
|
||||||
|
```bash
|
||||||
|
motion-wallpaper-toggle
|
||||||
|
```
|
||||||
|
|
||||||
|
### With a Keybind
|
||||||
|
|
||||||
|
Add this to `~/.config/hypr/bindings.conf`:
|
||||||
|
|
||||||
|
```
|
||||||
|
bind = SUPER ALT, W, exec, ~/.local/bin/motion-wallpaper-toggle
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Note**: `SUPER+W` is already bound to "Close window" in Omarchy. Use `SUPER ALT+W` or another free combination.
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
The toggle script works as an on/off switch:
|
||||||
|
|
||||||
|
### Toggle ON (no video wallpaper running)
|
||||||
|
|
||||||
|
1. Detects your connected monitors via `hyprctl monitors -j`
|
||||||
|
2. If multiple monitors, shows a selection dialog
|
||||||
|
3. Opens a file picker to choose a video file
|
||||||
|
4. Stops `hyprpaper` and `swaybg` (Omarchy's default wallpaper daemons) so mpvpaper is visible
|
||||||
|
5. Starts `mpvpaper` in the background with GPU-accelerated looping playback
|
||||||
|
|
||||||
|
### Toggle OFF (video wallpaper is running)
|
||||||
|
|
||||||
|
1. Shows a confirmation dialog
|
||||||
|
2. Stops `mpvpaper`
|
||||||
|
3. Restarts `hyprpaper` to restore your normal static wallpaper
|
||||||
|
|
||||||
|
## Supported Video Formats
|
||||||
|
|
||||||
|
Any format mpv supports, including:
|
||||||
|
|
||||||
|
- `.mp4` (H.264, H.265)
|
||||||
|
- `.mkv` (Matroska)
|
||||||
|
- `.webm` (VP9, AV1)
|
||||||
|
- `.mov` (QuickTime)
|
||||||
|
- `.avi`
|
||||||
|
|
||||||
|
## Finding Video Wallpapers
|
||||||
|
|
||||||
|
Search for "live wallpaper" or "motion desktop" videos. Good sources include:
|
||||||
|
|
||||||
|
- YouTube (download with `yt-dlp`)
|
||||||
|
- [Wallpaper Engine](https://store.steampowered.com/app/431960/Wallpaper_Engine/) workshop (some can be extracted)
|
||||||
|
- Free stock video sites (Pexels, Pixabay)
|
||||||
|
|
||||||
|
**Tips for best results:**
|
||||||
|
|
||||||
|
- Match your monitor resolution (e.g. 3840x2160 for 4K)
|
||||||
|
- Seamless loops look best (no visible cut at the loop point)
|
||||||
|
- Shorter videos (10-30 seconds) use less memory
|
||||||
|
- H.264 `.mp4` has the best hardware decode support
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
mpvpaper uses GPU-accelerated rendering (`--vo=gpu`) so CPU usage is minimal. However:
|
||||||
|
|
||||||
|
- Video decoding does use some GPU resources
|
||||||
|
- Higher resolution videos use more VRAM
|
||||||
|
- If you notice performance impact in games, toggle the wallpaper off first
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
**Video wallpaper doesn't appear / shows black**
|
||||||
|
- Make sure hyprpaper and swaybg are not running: `pgrep hyprpaper && pkill hyprpaper`
|
||||||
|
- Try a different video file to rule out codec issues
|
||||||
|
|
||||||
|
**File picker doesn't open**
|
||||||
|
- Check zenity is installed: `pacman -Qi zenity`
|
||||||
|
|
||||||
|
**"No monitors detected" error**
|
||||||
|
- Make sure you're running Hyprland: `echo $XDG_CURRENT_DESKTOP`
|
||||||
|
- Check hyprctl works: `hyprctl monitors`
|
||||||
|
|
||||||
|
**Normal wallpaper doesn't come back after toggling off**
|
||||||
|
- Manually restart hyprpaper: `hyprctl dispatch exec hyprpaper`
|
||||||
|
|
||||||
|
## Uninstalling
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Remove the toggle script
|
||||||
|
rm -f ~/.local/bin/motion-wallpaper-toggle
|
||||||
|
|
||||||
|
# Remove the app launcher entry
|
||||||
|
rm -f ~/.local/share/applications/motion-wallpaper-toggle.desktop
|
||||||
|
|
||||||
|
# Optionally remove packages
|
||||||
|
sudo pacman -Rns mpvpaper zenity
|
||||||
|
```
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
- [Omarchy](https://omarchy.com) - The Arch Linux distribution this was built for
|
||||||
|
- [mpvpaper](https://github.com/GhostNaN/mpvpaper) - Wayland video wallpaper daemon
|
||||||
|
- [mpv](https://mpv.io/) - The video player engine
|
||||||
|
- [Hyprland](https://hyprland.org/) - Wayland compositor
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is provided as-is for the Omarchy community.
|
||||||
103
wallpaper.sh
103
wallpaper.sh
|
|
@ -1,23 +1,59 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
# ==============================================================================
|
||||||
|
# Motion Wallpaper Installer for Omarchy / Hyprland
|
||||||
|
#
|
||||||
|
# This script sets up animated video wallpapers on an Omarchy (Arch Linux +
|
||||||
|
# Hyprland) desktop. It uses mpvpaper, which is a Wayland wallpaper program
|
||||||
|
# that plays a video file on the desktop background layer using mpv.
|
||||||
|
#
|
||||||
|
# What this installer does:
|
||||||
|
# 1. Installs dependencies (mpv, jq, zenity, mpvpaper)
|
||||||
|
# 2. Creates a toggle script at ~/.local/bin/motion-wallpaper-toggle
|
||||||
|
# 3. Creates a .desktop entry so it appears in your app launcher
|
||||||
|
#
|
||||||
|
# The toggle script works as an on/off switch:
|
||||||
|
# - If no video wallpaper is running: opens a file picker, starts playback
|
||||||
|
# - If a video wallpaper IS running: stops it, restores normal wallpaper
|
||||||
|
#
|
||||||
|
# Dependencies:
|
||||||
|
# - mpv: Video player engine (does the actual video decoding/rendering)
|
||||||
|
# - mpvpaper: Wayland-native wallpaper daemon that uses mpv as its backend
|
||||||
|
# (AUR package — renders video on the wl_surface background layer)
|
||||||
|
# - jq: JSON parser — used to read monitor info from hyprctl
|
||||||
|
# - zenity: GTK dialog toolkit — provides the file picker and confirmation
|
||||||
|
# dialogs so the script works without a terminal
|
||||||
|
# - hyprctl: Hyprland's CLI tool — used to detect connected monitors
|
||||||
|
# (comes with Hyprland, no separate install needed)
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
echo "=== Motion wallpaper installer for Omarchy / Hyprland ==="
|
echo "=== Motion wallpaper installer for Omarchy / Hyprland ==="
|
||||||
|
|
||||||
# 1) Check for required commands
|
# Sanity check — this script uses pacman for package installation, so it
|
||||||
|
# only works on Arch-based systems. Omarchy is built on Arch Linux.
|
||||||
if ! command -v pacman >/dev/null 2>&1; then
|
if ! command -v pacman >/dev/null 2>&1; then
|
||||||
echo "This script expects a pacman-based system (Arch/Omarchy). Aborting."
|
echo "This script expects a pacman-based system (Arch/Omarchy). Aborting."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 2) Install required packages from official repos
|
# Install core dependencies from the official Arch repos.
|
||||||
|
# --needed skips packages that are already installed, so this is safe
|
||||||
|
# to run multiple times without reinstalling anything unnecessarily.
|
||||||
|
# - mpv: the video player that mpvpaper uses under the hood
|
||||||
|
# - jq: parses the JSON output from "hyprctl monitors -j"
|
||||||
|
# - zenity: provides GUI dialogs (file picker, yes/no prompts)
|
||||||
echo "Installing required packages: mpv jq zenity"
|
echo "Installing required packages: mpv jq zenity"
|
||||||
sudo pacman -S --needed mpv jq zenity
|
sudo pacman -S --needed mpv jq zenity
|
||||||
|
|
||||||
# 3) Install mpvpaper from AUR
|
# Install mpvpaper from the AUR (Arch User Repository).
|
||||||
|
# mpvpaper is not in the official repos because it's a smaller community
|
||||||
|
# project. It needs an AUR helper (yay or paru) to build and install.
|
||||||
echo
|
echo
|
||||||
echo "Installing mpvpaper from AUR..."
|
echo "Installing mpvpaper from AUR..."
|
||||||
|
|
||||||
# Check for AUR helper
|
# Look for an AUR helper — yay and paru are the two most common ones.
|
||||||
|
# Omarchy ships with yay by default.
|
||||||
AUR_HELPER=""
|
AUR_HELPER=""
|
||||||
if command -v yay >/dev/null 2>&1; then
|
if command -v yay >/dev/null 2>&1; then
|
||||||
AUR_HELPER="yay"
|
AUR_HELPER="yay"
|
||||||
|
|
@ -43,23 +79,32 @@ else
|
||||||
read -p "Press Enter after installing mpvpaper to continue..."
|
read -p "Press Enter after installing mpvpaper to continue..."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Verify mpvpaper is installed
|
# Final check — if mpvpaper still isn't installed at this point (e.g. user
|
||||||
|
# skipped the AUR step or the build failed), we can't continue because the
|
||||||
|
# toggle script depends on it.
|
||||||
if ! command -v mpvpaper >/dev/null 2>&1; then
|
if ! command -v mpvpaper >/dev/null 2>&1; then
|
||||||
echo "ERROR: mpvpaper is not installed. Cannot continue."
|
echo "ERROR: mpvpaper is not installed. Cannot continue."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 4) Create ~/.local/bin if it doesn't exist
|
# Create the directory for user scripts. ~/.local/bin is the standard
|
||||||
|
# location for user-installed scripts on Linux (follows the XDG spec).
|
||||||
mkdir -p "$HOME/.local/bin"
|
mkdir -p "$HOME/.local/bin"
|
||||||
|
|
||||||
# 5) Create the toggle script
|
# Create the toggle script — this is the main script users interact with.
|
||||||
|
# It's a self-contained on/off switch for video wallpapers.
|
||||||
|
# When toggled ON: picks a video file via GUI, stops hyprpaper, starts mpvpaper
|
||||||
|
# When toggled OFF: stops mpvpaper, restarts hyprpaper to restore normal wallpaper
|
||||||
cat << 'EOF' > "$HOME/.local/bin/motion-wallpaper-toggle"
|
cat << 'EOF' > "$HOME/.local/bin/motion-wallpaper-toggle"
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
APP_NAME="Motion Wallpaper"
|
APP_NAME="Motion Wallpaper"
|
||||||
|
|
||||||
# Helper to show an error dialog (falls back to echo)
|
# Zenity helper functions — these wrap zenity dialogs so the script can
|
||||||
|
# show GUI pop-ups for errors, info, and yes/no questions. If zenity isn't
|
||||||
|
# available (shouldn't happen since we install it), they fall back to
|
||||||
|
# plain text output in the terminal.
|
||||||
zen_err() {
|
zen_err() {
|
||||||
if command -v zenity >/dev/null 2>&1; then
|
if command -v zenity >/dev/null 2>&1; then
|
||||||
zenity --error --title="$APP_NAME" --text="$1" || true
|
zenity --error --title="$APP_NAME" --text="$1" || true
|
||||||
|
|
@ -86,7 +131,9 @@ zen_question() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# 1) If mpvpaper is already running, offer to stop it (toggle OFF)
|
# Toggle logic — check if mpvpaper is already running.
|
||||||
|
# If it is, this is a "toggle OFF" action: stop the video wallpaper
|
||||||
|
# and bring back the normal static wallpaper by restarting hyprpaper.
|
||||||
if pgrep -x mpvpaper >/dev/null 2>&1; then
|
if pgrep -x mpvpaper >/dev/null 2>&1; then
|
||||||
if zen_question "Motion wallpaper is currently running.\n\nDo you want to stop it and return to your normal wallpaper?"; then
|
if zen_question "Motion wallpaper is currently running.\n\nDo you want to stop it and return to your normal wallpaper?"; then
|
||||||
pkill mpvpaper || true
|
pkill mpvpaper || true
|
||||||
|
|
@ -97,15 +144,21 @@ if pgrep -x mpvpaper >/dev/null 2>&1; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 2) No mpvpaper → toggle ON
|
# If we get here, mpvpaper is NOT running — this is a "toggle ON" action.
|
||||||
|
# We need to: detect monitors → let user pick one → let user pick a video
|
||||||
|
# → stop hyprpaper → start mpvpaper.
|
||||||
|
|
||||||
# 2a) Check hyprctl
|
# Make sure we're actually running inside Hyprland — hyprctl is how we
|
||||||
|
# talk to the compositor to find out which monitors are connected.
|
||||||
if ! command -v hyprctl >/dev/null 2>&1; then
|
if ! command -v hyprctl >/dev/null 2>&1; then
|
||||||
zen_err "hyprctl not found. Are you running Hyprland?"
|
zen_err "hyprctl not found. Are you running Hyprland?"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 2b) Get monitor list
|
# Get monitor list from Hyprland as JSON. The -j flag outputs structured
|
||||||
|
# JSON data which we parse with jq to extract monitor names (e.g. HDMI-A-1,
|
||||||
|
# DP-1, eDP-1). mpvpaper needs the exact monitor name to know where to
|
||||||
|
# render the wallpaper.
|
||||||
MON_JSON="$(hyprctl monitors -j 2>/dev/null || true)"
|
MON_JSON="$(hyprctl monitors -j 2>/dev/null || true)"
|
||||||
if [ -z "$MON_JSON" ]; then
|
if [ -z "$MON_JSON" ]; then
|
||||||
zen_err "Could not get monitor info from hyprctl."
|
zen_err "Could not get monitor info from hyprctl."
|
||||||
|
|
@ -125,7 +178,9 @@ fi
|
||||||
|
|
||||||
MON_COUNT="$(printf '%s\n' "$MONITORS" | wc -l)"
|
MON_COUNT="$(printf '%s\n' "$MONITORS" | wc -l)"
|
||||||
|
|
||||||
# 2c) Choose monitor (if more than one)
|
# If there's only one monitor, use it automatically. If there are multiple
|
||||||
|
# monitors, show a selection dialog so the user can pick which one gets
|
||||||
|
# the video wallpaper.
|
||||||
SELECTED_MON=""
|
SELECTED_MON=""
|
||||||
if [ "$MON_COUNT" -eq 1 ]; then
|
if [ "$MON_COUNT" -eq 1 ]; then
|
||||||
SELECTED_MON="$MONITORS"
|
SELECTED_MON="$MONITORS"
|
||||||
|
|
@ -144,7 +199,8 @@ if [ -z "${SELECTED_MON:-}" ]; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 2d) Choose video file
|
# Open a file picker dialog for the user to choose their video wallpaper.
|
||||||
|
# Filters to common video formats. If the user clicks Cancel, exit cleanly.
|
||||||
if ! command -v zenity >/dev/null 2>&1; then
|
if ! command -v zenity >/dev/null 2>&1; then
|
||||||
zen_err "Zenity is not installed but is required for file selection."
|
zen_err "Zenity is not installed but is required for file selection."
|
||||||
exit 1
|
exit 1
|
||||||
|
|
@ -172,7 +228,15 @@ pkill -x hyprpaper 2>/dev/null || true
|
||||||
pkill -x swaybg 2>/dev/null || true
|
pkill -x swaybg 2>/dev/null || true
|
||||||
sleep 0.3
|
sleep 0.3
|
||||||
|
|
||||||
# 2f) Start mpvpaper
|
# Start mpvpaper with optimised playback settings:
|
||||||
|
# --loop: Loop the video forever (it's a wallpaper, not a movie)
|
||||||
|
# --no-audio: Don't play audio (you don't want wallpaper sounds)
|
||||||
|
# --vo=gpu: Use GPU-accelerated rendering for minimal CPU usage
|
||||||
|
# --profile=high-quality: Use mpv's high quality rendering profile
|
||||||
|
# --keep-open=yes: Keep the window open when video reaches end (before loop)
|
||||||
|
#
|
||||||
|
# nohup + & runs it in the background detached from the terminal, so
|
||||||
|
# closing the terminal won't kill the wallpaper.
|
||||||
nohup mpvpaper -o "--loop --no-audio --vo=gpu --profile=high-quality --keep-open=yes" \
|
nohup mpvpaper -o "--loop --no-audio --vo=gpu --profile=high-quality --keep-open=yes" \
|
||||||
"$SELECTED_MON" "$VIDEO" >/dev/null 2>&1 &
|
"$SELECTED_MON" "$VIDEO" >/dev/null 2>&1 &
|
||||||
|
|
||||||
|
|
@ -181,7 +245,10 @@ EOF
|
||||||
|
|
||||||
chmod +x "$HOME/.local/bin/motion-wallpaper-toggle"
|
chmod +x "$HOME/.local/bin/motion-wallpaper-toggle"
|
||||||
|
|
||||||
# 6) Create desktop entry for app menu
|
# Create a .desktop entry so "Motion Wallpaper" appears in app launchers
|
||||||
|
# (Walker, Elephant, etc.). This follows the freedesktop.org Desktop Entry
|
||||||
|
# spec. The Categories and Keywords fields help the launcher index it
|
||||||
|
# properly so users can find it by searching "wallpaper", "video", etc.
|
||||||
mkdir -p "$HOME/.local/share/applications"
|
mkdir -p "$HOME/.local/share/applications"
|
||||||
|
|
||||||
cat << EOF > "$HOME/.local/share/applications/motion-wallpaper-toggle.desktop"
|
cat << EOF > "$HOME/.local/share/applications/motion-wallpaper-toggle.desktop"
|
||||||
|
|
@ -203,7 +270,9 @@ echo
|
||||||
echo "✓ Motion Wallpaper has been added to your application menu"
|
echo "✓ Motion Wallpaper has been added to your application menu"
|
||||||
echo " Search for 'Motion Wallpaper' in your app launcher"
|
echo " Search for 'Motion Wallpaper' in your app launcher"
|
||||||
|
|
||||||
# Check if ~/.local/bin is in PATH
|
# Check if ~/.local/bin is in PATH — if it's not, the user won't be able
|
||||||
|
# to run "motion-wallpaper-toggle" directly from the terminal. The .desktop
|
||||||
|
# entry uses the full path so the app launcher will always work regardless.
|
||||||
if [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then
|
if [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then
|
||||||
echo
|
echo
|
||||||
echo "⚠️ NOTE: ~/.local/bin is not in your PATH."
|
echo "⚠️ NOTE: ~/.local/bin is not in your PATH."
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue