Skip to content

Repository files navigation

LinWallpaper

A small, honest GTK 4 + libadwaita app that sets a wallpaper across every screen of a Linux machine — the desktop (per monitor), the lock screen, and, with your password, the login greeter, the boot splash, and the GRUB boot menu. Open an image, pick a fit, see it in a simulated monitor, and apply. No daemon, no background process; desktop changes need no root, and the privileged screens ask for your password only when you apply to them.

Lives in linwallpaper/. It is a clean rewrite; the older GTK 3 project under src/ is superseded and kept only for history.

Quick Install (One Command)

git clone https://github.com/MensuraMedia/linwallpapers.git && bash linwallpapers/install.sh

Installs the runtime packages that are missing (asks for your password only then), checks GTK 4 and libadwaita load, and adds LinWallpaper to your applications menu. It runs from the cloned folder, so update with git -C linwallpapers pull, with no reinstall. Works on Debian, Ubuntu, Linux Mint, Pop!_OS and derivatives. Other options:

bash linwallpapers/install.sh --system        # all users: copy to /usr/local + a `linwallpaper` command
bash linwallpapers/install.sh --uninstall     # remove the menu entry (add --system for a system install)
bash linwallpapers/install.sh --no-deps       # skip the package step (non-Debian: see --help)

To put it in a particular folder, cd there first (for example cd ~/projects) and run the same line.

Install

The app installs with one script — linwallpaper/install.sh — which adds a menu entry and panel icon (user-level, no root). It uses your system Python and packages; there is nothing to build and no virtualenv.

# from a checkout (the one-command ./install.sh above also installs the packages first)
./linwallpaper/install.sh          # add the menu entry + icon (--uninstall to remove)
python3 -m linwallpaper.main       # or: ./linwallpaper/run.sh — run without installing

That's a user-level, run-from-checkout install (the menu entry points back at this tree). For a system install that copies the app out of the checkout, add --system:

sudo ./linwallpaper/install.sh --system                 # → /usr/local (or --prefix DIR)
# installs /usr/local/lib/linwallpaper, a `linwallpaper` launcher on PATH, and the menu entry + icons
sudo ./linwallpaper/install.sh --system --uninstall     # remove it

After installing, launch LinWallpaper from your applications menu (or the panel icon). See Install & run below for requirements, and Using it to get started.


What it does

  • Open any image the desktop can load — the file filter is built from the installed GdkPixbuf loaders at runtime (PNG, JPEG, WebP, TIFF, BMP, GIF, and AVIF/HEIF/JXL/SVG where their loader is installed), so it accepts exactly what your system accepts.
  • Simulated monitors that never distort. Each surface is previewed inside a fixed-aspect “monitor” (bezel + stand). Resizing the window never stretches the wallpaper — the monitor keeps its aspect and centres.
  • Fit modes — Fill (zoom + centre-crop), Fit (letterbox), Center, Stretch. The preview and the applied result come from the same transform, so what you see is what you get.
  • A Wallpaper library. The Wallpaper page is a tight thumbnail grid of your saved wallpapers. It ships with a built-in default (always there, can’t be removed), and you add your own with Add images… / Add folder…, or by right-clicking in your file manager (see below). From a tile you can Apply it to every screen or Use in Screens to place it per-surface. Originals are referenced, never copied or modified.
  • “Add to LinWallpaper” right-click. Turn on Settings → Integration and your file manager gets an Add to LinWallpaper entry on images and folders — they land in the Wallpaper library. When you click Image on a Screens card, that library appears first (with a Browse files… fallback).
  • The Screens page lists every surface as a monitor card:
    • a global bar at the top: a Fit control, Open image… (one image for everything), and Apply to all (applies to every desktop monitor + the lock screen in one click);
    • per-card Fit, Apply, and Open image… — so each screen can carry a different image.
  • Non-destructive & reversible. Desktop applies are a settings write with Undo. Privileged applies back up every file first and support --undo.

The five surfaces

Surface Needs root? How LinWallpaper sets it
Desktop (per monitor) No the desktop’s own setting (see backends below)
Lock screen No follows the desktop on Cinnamon; else the desktop setting
Login screen (greeter) Yes — password greeter config + a rendered background
Boot splash (Plymouth) Yes — password a Plymouth theme + initramfs rebuild
Boot menu (GRUB) Yes — password a GRUB background drop-in + update-grub

Clicking Apply on a privileged surface opens a password dialog; the change runs through a careful, reversible helper (linwallpaper/privileged/lw_privileged.py).


OS support

Desktop background (no root) — one backend per environment, chosen by evidence

Environment Mechanism Per-monitor Status on this build
Cinnamon gsettings org.cinnamon.desktop.background via composite ✅ live-tested
GNOME / Budgie gsettings org.gnome.desktop.background via composite 🟡 implemented, untested
MATE gsettings org.mate.background via composite 🟡 implemented, untested
Xfce xfconf-query -c xfce4-desktop native 🟡 implemented, untested
X11, any WM feh --bg-* (one image per output) native 🟡 implemented, untested
KDE Plasma / wlroots (sway, Hyprland) — — ⬜ not yet

The backend is picked by a confidence probe ($XDG_CURRENT_DESKTOP, the settings tool on PATH); no code branches on a distro name. On single-background desktops (GNOME/Cinnamon/MATE), “one screen” uses a spanning composite canvas so a single monitor can differ.

Privileged screens (password) — currently the Debian/Ubuntu/Mint family

Surface Mechanism Family it targets today
Login /etc/lightdm/slick-greeter.conf + a lightdm-gtk-greeter drop-in + rendered image LightDM greeters (Mint, Ubuntu, …)
Boot splash Plymouth theme + update-alternatives + update-initramfs -u -k all Debian / Ubuntu / Mint
Boot menu /etc/default/grub.d/ drop-in + update-grub Debian / Ubuntu / Mint

These reproduce the mechanism of reference/apply-08-screen-wallpaper.sh (backups, drop-ins only, idempotent, --undo). Fedora (dracut, grub2-mkconfig) and Arch (mkinitcpio) are not wired yet — the plan for making them universal is in docs/design/cross-distro-apply.md.

“Add to LinWallpaper” file-manager menu (no root) — a provider per file manager

File manager What it installs (user-level) Status on this build
Nemo (Cinnamon) a .nemo_action in ~/.local/share/nemo/actions/ ✅ live-tested
Nautilus (GNOME) a script in ~/.local/share/nautilus/scripts/ 🟡 implemented, untested
Thunar (Xfce) a custom action in ~/.config/Thunar/uca.xml 🟡 implemented, untested
Dolphin (KDE) a service menu in ~/.local/share/kio/servicemenus/ 🟡 implemented, untested

The active file manager is chosen by evidence (binary on PATH, $XDG_CURRENT_DESKTOP); every entry calls python3 -m linwallpaper.addcli. The design is in docs/design/wallpaper-collections.md.


Install & run

Requirements (from your distribution, not PyPI): python3-gi, gir1.2-gtk-4.0, gir1.2-adw-1, gir1.2-gdkpixbuf-2.0, python3-pil. For the privileged screens: pkexec/sudo and the relevant tools (lightdm/slick-greeter, plymouth + update-initramfs, grub + update-grub).

# run from a checkout
python3 -m linwallpaper.main        # or: ./linwallpaper/run.sh

# add a menu entry + icon (user-level, run-from-checkout; --uninstall to remove)
./linwallpaper/install.sh

# OR a system install (copies the app out of the checkout, adds a `linwallpaper` launcher on PATH)
sudo ./linwallpaper/install.sh --system            # --prefix DIR to change /usr/local; --uninstall to remove

Uses your system python3 (PyGObject/GTK/Pillow are system packages) — no virtualenv. Both install modes are the same script; --system copies linwallpaper/ to PREFIX/lib/linwallpaper and writes a launcher, so the app no longer depends on the checkout (the “Add to LinWallpaper” action installed from Settings points at the installed copy automatically).

Using it

  1. Screens page → up top, Open image… and pick a Fit, then Apply to all for the desktop + lock in one click; or give a single screen its own image with that card’s Open image….
  2. For Login / Boot splash / Boot menu, click that card’s Apply → enter your password. Backups are taken first; revert any surface with:
    sudo python3 linwallpaper/privileged/lw_privileged.py <login|splash|grub> --undo

Safety model

  • Nothing runs in the background. The app applies and exits cleanly; nothing is installed as a service or autostart. (On wlroots compositors, a wallpaper process is the platform’s own, not the app’s.)
  • Desktop = a reversible settings write (Undo in the toast).
  • Privileged = every file backed up to /var/backups/linwallpaper/<timestamp>/ with a manifest (path, mode, sha256, prior selection) before any write; drop-ins only (never edits a package conffile such as /etc/default/grub); idempotent (skips identical files); rolls back on error; --undo restores from the latest backup.

Layout

linwallpaper/
  main.py monitors.py imaging.py
  backends/   base.py cinnamon.py gnome.py mate.py xfce.py x11_feh.py (_gsettings.py)
  ui/         window.py sidebar.py state.py monitor_frame.py password_dialog.py style.css  pages/
  privileged/ lw_privileged.py  assets/{plymouth,grub.d}
  data/       io.mensuramedia.LinWallpaper.desktop  icons/hicolor/…
  tests/  run.sh  install.sh

Status & docs

  • Working & verified: the GTK 4 app, desktop apply on Cinnamon (read-back confirmed), the Screens page, the simulated monitors, the password dialog, and the privileged helper’s dry-run/backups. The live privileged apply (login/boot) is confirmed working — applied and verified across a reboot.
  • Design & reference: docs/design/wallpaper-collections.md (the Wallpaper library + “Add to LinWallpaper”), docs/design/minimal-gtk4-app.md (as-built), docs/design/cross-distro-apply.md (making the privileged apply universal), docs/STATUS.md (handoff), reference/ (the origin shell script).

License

Licensed under the PolyForm Noncommercial License 1.0.0. You may use, copy, modify and distribute it for any noncommercial purpose. Commercial use is prohibited without express written permission from the copyright holder — request one at https://github.com/MensuraMedia. Third-party components carry their own terms; see NOTICE.

About

lin-wallpapers is a simple desktop wallpaper manager across all screens

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages