Skip to content

Roberth-Souza/wallfliper

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

61 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ–ΌοΈ Wallfliper

A minimalist, Rofi/yazi-style wallpaper selector for Wayland.

Borderless, dark, keyboard-first β€” the wallpapers are the content, the UI disappears. Pick a still image or a looping video, hit Enter, done.

License Python Toolkit Platform


DemonstraΓ§Γ£o do Wallfliper


✨ Features

  • Keyboard-first β€” arrow keys / hjkl / wasd to move, / to filter, Enter to apply. No mouse needed, but it works too (click to select, double-click to apply).
  • Images and video wallpapers β€” via swww, looping video via mpvpaper.
  • Smooth transitions β€” animated switches for both images and video
  • Live previews β€” selecting a video plays a short looping clip right on its thumbnail.
  • Audition mode β€” Space applies a wallpaper but keeps the picker open, so you can flip through options on your real desktop.
  • Lightweight & on-demand β€” launches when you call it, exits cleanly, and never idles in the background. Rendering is handed to detached daemons.
  • Restore on login β€” remembers your last wallpaper so a video survives a reboot.
  • Color-scheme integration β€” tells noctalia / matugen / wallust / pywal to re-theme your system from the new wallpaper.
  • Riced to taste β€” backdrop opacity, made for a layerrule = blur compositor.

πŸ–₯️ Supported compositors

Wallfliper draws its picker as a wlr-layer-shell overlay and delegates painting to swww/mpvpaper, so it targets compositors that implement wlr-layer-shell:

Hyprland Β· Sway Β· river Β· Wayfire Β· niri

Out of scope (no layer-shell, or only partial): KDE Plasma, GNOME, X11, Windows.

πŸ™ƒ Why this exists

Honestly? I just wanted to give Claude Code a try, and ended up enjoying it a little too much.

Wallfliper was built mostly "low-code" β€” most of the codebase was written with the help of AI tooling like Claude Code and Google Stitch, with me steering the design, scope and decisions.

πŸ“¦ Installation

Install from source β€” works on any supported compositor:

Important

Install PySide6 from your distribution, not pip. layer-shell-qt is a compiled Qt plugin loaded into the running process β€” its Qt version must match the Qt that PySide6 uses. Distro packages are all built against the same system Qt, so they always match. A pip install PySide6 bundles its own Qt and can mismatch the system layer-shell plugin, causing cryptic load failures.

1. Install the dependencies

Dependency Purpose Required?
pyside6 the Qt6 / QML runtime βœ… required
layer-shell-qt the overlay (org.kde.layershell QML module) βœ… required
swww or awww image wallpapers (auto-detected) image support
mpvpaper video wallpapers video support
ffmpeg video thumbnails, previews & color extraction video extras

On Arch / CachyOS β€” copy-paste:

sudo pacman -S pyside6 layer-shell-qt swww ffmpeg

paru -S mpvpaper

On other distros β€” install them with your package manager (names vary, e.g. python3-pyside6). swww and mpvpaper are usually not packaged outside Arch β€” build them from source (both have simple instructions):

2. Run it

git clone https://github.com/Roberth-Souza/wallfliper
cd wallfliper

python main.py --check        # βœ“/βœ— report of every dependency
python main.py                # launch

πŸ’‘ python main.py --check prints a per-dependency report with an install hint for whatever's missing β€” run it first if anything misbehaves.

⌨️ Usage

Recommended

Bind Wallfliper to a compositor hotkey. Pressing the hotkey again while it's open closes it β€” it's a toggle.

-- Hyprland (Lua config) β€” ~/.config/hypr/modules/keybinds.lua
hl.bind("SUPER + W", hl.dsp.exec_cmd("python /path/to/wallfliper/main.py"))
# Sway β€” ~/.config/sway/config
bindsym $mod+w exec python /path/to/wallfliper/main.py
# niri β€” ~/.config/niri/config.kdl
binds { Mod+W { spawn "python" "/path/to/wallfliper/main.py"; } }

Key Action
↑ ↓ ← β†’ Β· h j k l Β· w a s d Move selection
/ Start searching β€” then type to filter
Backspace Edit the filter (empty filter β†’ leave search)
i Β· v Toggle the image / video filter (also clickable buttons)
Enter Apply selected wallpaper and close
Space Apply but keep open (audition on your desktop)
Esc Close (or close the settings panel)
Double-click Apply and close
Click outside the panel Close
βš™ (gear) Open settings

Applying an image stops any running video wallpaper β€” there's only ever one wallpaper at a time.

βš™οΈ Settings

Click the gear (or it's keyboard-driven: j/k move Β· ←/β†’ change Β· Enter select Β· Esc close):

  • background β€” backdrop darkness / opacity
  • folder β€” choose your wallpaper directory (via your xdg-desktop-portal file chooser)

🌫️ Blur (optional, Hyprland)

Hyprland blurs windows by default, but not layer-shell surfaces β€” so Wallfliper starts out unblurred. To get the frosted-glass panel, add a layer rule for its wallfliper namespace:

hl.layer_rule({ name = "wallfliper", match = { namespace = "wallfliper" }, blur = true, ignore_alpha = 0.5 })

Lower the background opacity in Settings to actually see the blur through it.

Verify the namespace any time with hyprctl layers while Wallfliper is open.

Other wlr-layer-shell compositors expose their own blur mechanism (or none) β€” consult their docs; Wallfliper just provides the transparent surface for them to blur.

πŸ” Restore on login

Wallfliper saves the last-applied wallpaper to ~/.config/wallfliper/state.json. wallfliper --restore reads that and re-spawns swww/mpvpaper β€” so a video wallpaper survives a reboot. (Wallfliper itself doesn't stay running; it just hands the file back to the renderer and exits β€” mpvpaper is stateless and dies on reboot, so something has to re-launch it, and that's all --restore does.)

python /path/to/wallfliper/main.py --restore   # re-apply the saved wallpaper now

Run it on login from your compositor's autostart, wrapped in a short sleep so the compositor finishes bringing up your desktop first. Without the delay a video wallpaper can come up frozen on a low-res frame: mid-boot the wallpaper surface is briefly reported as "hidden", which trips mpvpaper's auto-pause (a known mpvpaper quirk). A few seconds' delay sidesteps it:

-- Hyprland (Lua config) β€” inside hl.on("hyprland.start", ...) in your autostart.lua
hl.exec_cmd("sh -c 'sleep 5 && python /path/to/wallfliper/main.py --restore'")
# Sway β€” ~/.config/sway/config
exec sh -c 'sleep 5 && python /path/to/wallfliper/main.py --restore'
# niri β€” ~/.config/niri/config.kdl
spawn-at-startup "sh" "-c" "sleep 5 && python /path/to/wallfliper/main.py --restore"
# Wayfire β€” ~/.config/wayfire.ini
[autostart]
wallfliper = sh -c 'sleep 5 && python /path/to/wallfliper/main.py --restore'

Uses system python (the same interpreter that runs the app) β€” no virtualenv, no activation. Once you install via a package (e.g. AUR), a real wallfliper command lands on PATH and every line above shortens to just wallfliper --restore.

Alternative: XDG autostart entry

wallfliper --install-autostart writes ~/.config/autostart/wallfliper-restore.desktop (the freedesktop standard). It works on sessions that honor XDG autostart β€” GNOME/KDE, or wlroots compositors launched via UWSM/systemd. A bare Hyprland/Sway/niri session won't read that folder, so on a plain setup use the compositor exec line above instead.

No background daemon of our own β€” rendering is handled by swww-daemon / mpvpaper.

🎨 Color-scheme integration

After applying a wallpaper, Wallfliper notifies external color tools so your system color scheme regenerates from it (best-effort, never blocks). It auto-detects noctalia-shell if running; for everything else set color_hook in ~/.config/wallfliper/config.json ({path} is substituted):

{
  "color_hook": "matugen image {path}"
}

Works with matugen / wallust / pywal / any command. For video wallpapers it themes from a still frame extracted with ffmpeg.

🩹 Troubleshooting

First step, always: wallfliper --check β€” it tells you exactly what's missing.

Symptom Cause & fix
ImportError / won't start PySide6 missing β€” install your distro's pyside6.
"failed to load QML UI" layer-shell-qt missing β€” install it (provides org.kde.layershell).
Overlay never appears Not on a wlr-layer-shell Wayland session β€” check your compositor.
⚠ "no wallpaper tool found" on apply Install swww (or awww) for images.
⚠ "mpvpaper is not installed" on apply Install mpvpaper for video wallpapers.
Video cards show β–Ά instead of a frame Install ffmpeg (thumbnails/previews are optional).
Settings folder picker doesn't open Install an xdg-desktop-portal backend (e.g. xdg-desktop-portal-gtk or -termfilechooser).

the app still runs and tells you in the status bar what to install.

πŸ“„ License

GPL-3.0. PySide6 is used under the LGPL.

Packages

 
 
 

Contributors