wallr 0.6.1

The wallpaper engine for Wayland - GPU transitions, video wallpapers, and theme pipeline integration.
<div align="center">

# Wallr

GPU-accelerated wallpaper engine for Wayland, rendered natively with `wgpu` on `wlr-layer-shell`.

<a href="https://github.com/programmersd21/wallr">
  <img src="https://raw.githubusercontent.com/programmersd21/wallr/main/assets/demo.gif" alt="Wallr demo" width="800">
</a>

<p align="center">
  <a href="https://github.com/programmersd21/wallr/stargazers"><img src="https://img.shields.io/github/stars/programmersd21/wallr?style=for-the-badge&logo=github&logoColor=f9e2af&labelColor=11111b&color=f9e2af" alt="GitHub stars"></a>
  <a href="https://github.com/programmersd21/wallr/releases/latest"><img src="https://img.shields.io/github/v/release/programmersd21/wallr?style=for-the-badge&logo=github&logoColor=a6e3a1&labelColor=11111b&color=a6e3a1" alt="Latest release"></a>
  <a href="https://aur.archlinux.org/packages/wallr-bin"><img src="https://img.shields.io/aur/version/wallr-bin?style=for-the-badge&logo=archlinux&logoColor=cba6f7&labelColor=11111b&color=cba6f7" alt="AUR version"></a>
  <a href="https://aur.archlinux.org/packages/wallr-bin"><img src="https://img.shields.io/aur/votes/wallr-bin?style=for-the-badge&logo=archlinux&logoColor=f5c2e7&labelColor=11111b&color=f5c2e7" alt="AUR votes"></a>
  <a href="https://crates.io/crates/wallr"><img src="https://img.shields.io/crates/v/wallr?style=for-the-badge&logo=rust&logoColor=fab387&labelColor=11111b&color=fab387" alt="Crates.io version"></a>
  <a href="https://www.rust-lang.org"><img src="https://img.shields.io/badge/MSRV-1.85-94e2d5?style=for-the-badge&logo=rust&logoColor=94e2d5&labelColor=11111b&color=94e2d5" alt="Minimum supported Rust version"></a>
</p>

</div>

Wallr renders its own background surface on `wlr-layer-shell` compositors. It does not shell out to `hyprpaper`, `swaybg`, or `swww`.

## Features

- Static, GIF, and video wallpapers (MP4, WebM, MKV) with hardware-accelerated decode
- 6 transitions: fade, wipe, slide, wave, grow, outer
- Per-monitor wallpapers and scaling modes
- Background daemon over a Unix socket
- Optional post-apply theming via Matugen, Wallust, or Pywal
- Near-zero idle overhead: static wallpapers render once and sleep; video and GIFs pace to frame boundaries
- Zero-duration static sets can use a low-memory `wl_shm` compositor buffer; GPU rendering remains available for transitions and live media
- Performance harness for live Wayland measurements against `awww` (`scripts/benchmark-wallpapers.sh`)

## Screenshots

<p align="center">
  <img src="https://raw.githubusercontent.com/programmersd21/wallr/main/assets/rice_1.png" alt="Terminal rice with audio visualizer and fetch widget over a Catppuccin Mocha sunset" width="49%">
  &nbsp;
  <img src="https://raw.githubusercontent.com/programmersd21/wallr/main/assets/rice_2.png" alt="System monitor and lazygit over a Catppuccin Mocha sunset" width="49%">
  <br>
  <em>Catppuccin Mocha sunset: audio visualizer and fetch widget (left), system monitor and git workflow (right)</em>
</p>

## Install

```bash
cargo install wallr
```

```bash
yay -S wallr-bin
```

```bash
nix run github:programmersd21/wallr
```

```bash
#First, install the Terra Repository (terrapkg.com)
sudo dnf install --nogpgcheck --repofrompath 'terra,https://repos.fyralabs.com/terra$releasever' terra-release

#Then, install wallr with dnf
sudo dnf install wallr
```

## Usage

```bash
# Basic wallpaper change
wallr set wallpaper.jpg

# Smooth transitions with ergonomic short flags
wallr set wallpaper.jpg -e grow -o center -d 850ms
wallr set wallpaper.jpg -e wipe -a 45 -d 800ms
wallr set video.mp4 -e wave -d 900ms

# Instant switch for scripts
wallr set wallpaper.jpg --duration 0 --no-theme
```

`wallr set` starts the daemon automatically if it isn't already running. Full flag reference: [`docs/cli-reference.md`](docs/cli-reference.md).

## Configuration

`~/.config/wallr/config.yaml`:

```yaml
wallpaper:
  default: "~/Pictures/Wallpapers/default.png"
  mode: "fill"

theme:
  provider: "matugen"

reload:
  - "waybar"
  - "dunst"
```

Full schema: [`docs/config-reference.md`](docs/config-reference.md).

## Requirements

| | |
|---|---|
| Compositor | Hyprland, Sway, niri (layer rule required), or KDE Plasma 6: any `wlr-layer-shell` implementation. GNOME/Mutter is unsupported. |
| Rust | stable, for building from source |
| FFmpeg | required only when building from source, for video wallpapers. Prebuilt release binaries statically link FFmpeg. |

## Building from source

```bash
# Arch
sudo pacman -S rust wayland wayland-protocols pkg-config ffmpeg

# Fedora
sudo dnf install rust cargo wayland-devel wayland-protocols-devel pkg-config ffmpeg-devel

# Ubuntu/Debian
sudo apt install rustc cargo libwayland-dev wayland-protocols pkg-config libavcodec-dev libavformat-dev libavutil-dev libswscale-dev
```

```bash
git clone https://github.com/programmersd21/wallr.git
cd wallr
cargo install --path wallr
```

## Architecture

The `wallr` CLI talks to `wallr daemon` over a Unix socket. The daemon owns the layer-shell surface, the `wgpu` renderer, and the transition engine. Wallpaper changes render as GPU transitions from the previous image; GIFs continue playing after the transition ends, and video is decoded by FFmpeg with hardware acceleration where available.

Details: [`docs/architecture.md`](docs/architecture.md).

### Performance measurements

Wallr is optimized around event-driven static rendering and bounded live
playback. Use the included harness to measure the daemon on your compositor:

```bash
scripts/benchmark-wallpapers.sh
```

It requires a running Wayland session, `hyperfine`, `awww`, and release-built
Wallr. Comparisons are machine- and workload-specific; do not interpret one
run as a universal ranking.

## Troubleshooting

**`error while loading shared libraries: libavutil.so.58`**: the installed binary was built against an older FFmpeg ABI. Reinstall the latest release (statically linked), or rebuild from source:

```bash
cargo install --path wallr --force
```

**Wallpaper intercepts input**: it shouldn't; the surface runs on `Layer::Background` with `KeyboardInteractivity::None` and an empty input region. If it happens: confirm your compositor is supported, check compositor logs for layer-shell errors, restart the daemon (`pkill wallr && wallr daemon`), and on niri add a layer-shell rule permitting Wallr on the background layer.

## Documentation

[Changelog](CHANGELOG.md) · [CLI reference](docs/cli-reference.md) · [Config reference](docs/config-reference.md) · [Architecture](docs/architecture.md) · [Matugen integration](docs/matugen-integration.md) · [Video wallpapers](docs/video-wallpaper.md)

Last wallpaper per output is stored at `~/.cache/wallr/last_wallpaper/<OUTPUT>`; see [CLI reference](docs/cli-reference.md) and [Architecture](docs/architecture.md).

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md).

## Credits

Sample wallpapers in `samples/` are taken from:

- [zhichaoh/catppuccin-wallpapers]https://github.com/zhichaoh/catppuccin-wallpapers

All rights belong to their respective owners; thanks to the original authors for sharing their work.

## License

MIT; see [LICENSE](LICENSE).