Omahub
← All plugins
W

Omarchy Wallpapers

by Wolfgang Rittner

Browse photos from Unsplash in the bar and set them as your Omarchy background.

Security review

No obvious issues detected

Deterministic scan — not a security guarantee

None
Risk level
None
Analyzed commit
5efa547
Scanned
1 month ago

No potentially dangerous behavior detected in the analyzed commit.

Automated analysis only — not a security guarantee.

AI advisory review

No obvious issues detected

Language-model assessment · ~deepseek/deepseek-v4-flash-latest — advisory only

Low
AI risk level
Low
Recommendation
install
Model
~deepseek/deepseek-v4-flash-latest
Analyzed commit
5efa547
Reviewed
1 month ago

The plugin is a well-structured Unsplash wallpaper browser with careful input validation, no install-time code execution, and no hidden destructive behavior. The only notable risk is that it downloads and applies remote images as wallpapers, which is the plugin's stated purpose and requires explicit user action.

  • The plugin downloads images from Unsplash and applies them as wallpapers; this is the intended function, but remote content is inherently untrusted. The code mitigates this by validating hosts and image format, though the ImageMagick check is optional.
  • The access key is stored in plaintext in ~/.local/state/omarchy/settings/omarchy-wallpapers.json (mode 0600), which is acceptable but worth noting.
  • The plugin shells out to curl, jq, xdg-open, and omarchy-theme-bg-set; all invocations appear properly validated and constrained to expected hosts/paths.
How this check works

This review combines the deterministic scan (the rule-based results above) with an independent look at the plugin's code by a language model. The model reads a trimmed sample of the repository's files, the manifest, and the README, then gives a plain-language risk level and a recommendation: install (no notable danger), review (look closer first), or avoid (clearly dangerous).

It runs on the same analyzed commit as the deterministic scan and is strictly advisory — it is not a security guarantee and never blocks a plugin by itself. A human moderator still reviews plugins before they are listed.

AI advisory only — automated analysis, not a security guarantee.

Install
$ omarchy plugin add https://github.com/wolfgangrittner/omarchy-wallpapers --enable
Appearance #bar #quickshell

Omarchy Wallpapers

A wallpaper browser in the Omarchy bar. Draw a random photo from the collections you pick, set it as your wallpaper. An Omarchy shell plugin, powered by Unsplash.

Not affiliated with or endorsed by Unsplash. The API guidelines forbid using their name in an application name or their logo as an app icon, so this is "Omarchy Wallpapers"; every photo credits its photographer and Unsplash, both linked.

Drawing and applying are separate — click the photo as often as you like; nothing reaches your desktop until you press Set as wallpaper.

Requirements

Omarchy 4 (the Quickshell-based shell). Beyond that it shells out to a handful of commands, all standard on an Omarchy install:

curl API requests and photo downloads
jq reading and writing the JSON config, history, and lookups
xdg-open opening a photo or photographer on unsplash.com
omarchy-theme-bg-set applying the wallpaper (ships with Omarchy)
omarchy-notification-send the "wallpaper set" toast; falls back to notify-send, and is skipped if neither exists
identify (ImageMagick) optional — sanity-checks that a download decoded as an image; skipped when not installed

No other runtime, package, or network service is required, and nothing is installed on your behalf.

Install

omarchy plugin add https://github.com/wolfgangrittner/omarchy-wallpapers.git --enable --yes

Then add an access key (below).

Uninstall: omarchy plugin remove wolfgangrittner.omarchy-wallpapers

Access key

The API needs a free key of your own — there is no unauthenticated endpoint.

  1. Go to https://unsplash.com/oauth/applications and sign in, creating an Unsplash account if you need one.
  2. New Application. Accept the API terms and guidelines, then give it any name and description — the key is yours, nothing is reviewed or published.
  3. Copy the Access Key from the application page. Not the Secret key — this app never needs it.
  4. In the panel, open settings (⚙), paste it in, press Save.

New applications run in Demo mode: 50 requests an hour. Only calls to api.unsplash.com count; the photos themselves come from images.unsplash.com and are free.

Action Requests
Curated grid discovery 6, once ever — cached in config
New photo 1
Set as wallpaper 1 — the download ping the guidelines require
Collection search 1 — the default browse list caches for 30 minutes

A draw-and-set cycle is 2, so roughly 25 wallpaper changes an hour. If you do spend the hour, the panel says so and leaves the desktop alone: your wallpaper, History, and re-applying an old photo keep working, because those come from the image CDN. Only new draws and searches wait for the reset.

Apply for Production in the same dashboard raises the limit to 1,000/hour; nothing here needs to change.

Panes

Home Collections History
Home Collections History
The photo on show. Click it — or the ⟳ over it — to draw another; Set as wallpaper applies it and closes the panel. Six curated collections in a 3×2 grid, plus search for any other public collection. Tick any mix; Wallpapers is on out of the box, and unticking everything draws from all of Unsplash. Every photo shown, applied or not. Click one to set it again.

Mouse

Left-click icon Open/close
Right-click icon Open and draw a photo
Click photo Draw another
Click a collection Select/deselect as a source
Click history thumb Set it, close
Right-click history thumb Open on unsplash.com

Keys

1 2 3 Home / Collections / History
n Draw a photo
Enter Apply and close (Collections: toggle)
←↓↑→ hjkl Move cursor
/ Search collections
r Reload collections
o Open on unsplash.com
Esc Close

Config

bin/ow-config set <key> <value> · setstdin <key> · unset <key>... · get

Key Default
orientation landscape landscape, portrait, squarish (also a button in ⚙)
keep 10 Downloaded wallpapers to keep
historyMax 200 History entries to keep
minPhotos 10 Hide collections offering fewer usable photos than this
curated discovered The six grid collections. Resolved on first run, cached here. Rebuild from ⚙.
collections Wallpapers Which collections photos are drawn from

The curated grid

Collection ids are never hardcoded. On first run bin/ow-curated searches Unsplash for each of the six names and keeps the largest match, counted in photos a free API key can actually fetch — total_photos minus total_plus.

That last part matters: the biggest "wallpapers" collection is entirely Unsplash+ premium, and /photos/random answers 404 for it, so ranking on the raw count picks a collection that silently returns nothing. It prefers collections with at least 50 usable photos, falling back to the largest usable one so a thin search term still yields a tile. Results are cached in curated; Rebuild curated in ⚙ re-runs the lookup.

The same count drives the browse list: collections with fewer than minPhotos fetchable photos are hidden, which removes Unsplash+ collections (0 usable) and near-empty ones in a single rule. The pane says how many it hid.

Config lives in ~/.local/state/omarchy/settings/omarchy-wallpapers.json (mode 0600) — outside ~/.config so the access key stays out of dotfiles repos.

Two more live on the bar widget itself in ~/.config/omarchy/shell.json, since they are layout rather than behaviour: columns (history/curated grid width, default 3) and perPage (collection search results, default 20).

Files

Wallpapers download at your screen's native width to ~/.config/omarchy/backgrounds/<theme>/unsplash-<id>.jpg, so omarchy theme bg next cycles them too. Only photos you apply are downloaded. The keep newest are kept; older unsplash-*.jpg in that directory are deleted, nothing else.

State, all in ~/.local/state/omarchy/settings/:

omarchy-wallpapers.json          key, orientation, collections, curated, limits
omarchy-wallpapers-current.json  photo currently applied
omarchy-wallpapers-history.json  every photo shown

Source:

Panel.qml              bar button + three-pane popup
CuratedCell.qml        one tile in the curated grid
SourceRow.qml          one row in the search/browse list
Model.js               endpoints, parsing, config, grid math
bin/ow-api             authenticated Unsplash requests
bin/ow-lib.sh          shared checks on ids and URLs
bin/ow-config          read/write config
bin/ow-curated         resolve the six curated collections
bin/ow-history         record photos shown
bin/ow-set-wallpaper   download, apply, prune

Handling the access key and remote input

The access key is never passed as a command-line argument, because /proc/<pid>/cmdline is world-readable and would expose it to every process on the machine for the life of the request. bin/ow-api reads the key from the config itself and hands it to curl in a config file on stdin; the panel calls ow-api with only a request path, so no caller can aim a credentialed request at another host. Saving the key from ⚙ goes over stdin too (ow-config setstdin). Redirects are never followed on a request carrying the key, so a 302 cannot replay it elsewhere.

Ids and URLs in an API response are treated as untrusted: a photo id has to match [A-Za-z0-9_-]{1,128} before it becomes a filename, image downloads must be https from images.unsplash.com or plus.unsplash.com, the download ping must be api.unsplash.com, and anything handed to xdg-open must be unsplash.com. The rules live in Model.js for the panel and bin/ow-lib.sh for the scripts, so each holds even when a script is run on its own. History rows are re-checked when read back, not trusted for having come off local disk.

IPC

omarchy-shell wallpapers toggle|open|close
omarchy-shell wallpapers next          # draw a photo
omarchy-shell wallpapers set           # apply the one on show
omarchy-shell wallpapers showPane home|collections|history

Bind in ~/.config/hypr/bindings.lua:

o.bind("SUPER CTRL", "U", "omarchy-shell wallpapers toggle")

next then set on a systemd timer gives you rotation.

Attribution

Every photo credits its photographer and Unsplash, both linked with the required utm_source/utm_medium referral parameters; images are hotlinked from the API's own URLs, and the download endpoint is pinged on apply — per the Unsplash API Guidelines.

License

MIT