Work / Tools & Open Source

Gladius

A keyboard-driven wallpaper picker for Windows. A hotkey drops a translucent strip of your wallpapers over the desktop; vim keys scroll it, Space sets one, and the app is gone.

Status
v1 built · source public · first packaged release not yet cut
Stack
Python · PySide6 (Qt) · Win32 · PyInstaller · GitHub Actions
Started
August 2026
Source
Open source · MIT
The Gladius overlay over a Windows desktop: a translucent, dimmed backdrop with a horizontal strip of wallpaper thumbnails sheared into leaning parallelograms, one tile outlined as the current selection.
The overlay: a strip of sheared wallpaper tiles over the dimmed desktop.

What it is

Gladius is a Windows port of hyprquickpaper, a wallpaper picker for the Hyprland desktop on Linux. It keeps the original's look, keys and idea and was rewritten from scratch: the original carries no license, so no code is shared, only behaviour.

It has no tray icon, no background process and no window to manage. It lives for a few seconds at a time: bound to a hotkey, it opens a fullscreen overlay, you pick a wallpaper with the keyboard or mouse, and it exits. A warm launch measured 0.30 seconds from process start to a visible window.

The whole application is one Python file with one runtime dependency, PySide6. Three bugs the original documents were fixed rather than ported: thumbnails that go stale after an edit, a blank strip on first run, and same-named images in different folders overwriting each other's thumbnails.

The source has been public since October 2026 and runs on Windows 10 or 11 with Python. A packaged build is ready and its winget manifests validate clean, but the first tagged release that publishes it has not been cut, and the winget listing will then need Microsoft's review. Until then, installing means running it from source.

What it does

  • Hotkey overlayBinds to any hotkey tool or a Windows shortcut; launching it twice cannot stack two overlays.
  • Keyboard firstJ and K step through wallpapers, D and U jump a screenful, Space or Enter sets one, Esc leaves the desktop untouched. Wheel, drag and click work too.
  • Settings in placePress S for a settings panel; every change applies to the open overlay and is saved for the next launch.
  • Random modeA command-line flag sets a random wallpaper with no window at all, safe to run unattended at logon.
  • Formats Windows refusesWebP, AVIF and GIF images are converted to PNG behind the scenes so they set like any other.
  • Tiling-friendlyFloats above tiling window managers such as komorebi with no rule or config change.

Build log

Built in a day, six weeks to go public

The record of how Gladius was made, from the first commit to today: the plan, the spikes, the build, the work of making it installable and the cleanup before the source went public. Dated, oldest first.

As of 4 Oct 2026, counted from the repository.

  1. Era I · 20 AugThe build
  2. Era II · 20 – 21 AugMaking it installable
  3. Era III · 2 OctGoing public

Era I · 20 Aug 2026

The build

One day from an approved plan to a working app that passed its acceptance run on the real machine: a design written first, two risky unknowns spiked, then the app built bottom-up one stage at a time.

  1. A plan before any code

    The first commit was a written spec, a staged build plan and the project's documentation, with no application code. Studying the original showed it was a single sheared horizontal strip, not the grid the brief had assumed. Highlighting a tile would never touch the desktop; only an explicit pick sets a wallpaper, which avoids registry churn and any restore logic.

    Brian's call A faithful port of the strip over a grid that might have been more practical for a large collection. Fidelity to the original was the product; a grid was parked as a later idea.

  2. Two unknowns spiked first

    Two questions could have forced design changes, so they were tested before the build. Windows' documented backdrop API reported success but painted a flat grey panel on this kind of window, so an older undocumented call that produces real blur won, with its tint lightened so the blur stays visible. A plain tool-window flag turned out to be enough to keep the komorebi tiling manager from grabbing the overlay, so Gladius edits no other tool's config.

    Method Blur was judged by measuring high-frequency detail in captured frames, not by return codes, because the losing API reports success.

  3. Built bottom-up, one stage per commit

    Config, then the folder scan and thumbnail cache, then the wallpaper setter, the command line, the strip, the overlay window and the settings panel, each in its own commit. The thumbnail cache was keyed by path, modification time and size, which fixed the original's stale-thumbnail, blank-first-run and filename-collision bugs at the root. The scroll and layout constants were carried over from the original because they are why the strip feels the same.

    Method Pure logic was written test-first; the GUI stages were checked by driving the real widgets with synthetic input events.

  4. Hardened for machines it never ran on

    Because strangers would run it on other hardware and heavily customised Windows setups, a pass beyond the planned scope covered failures that would be invisible on the build machine. Thumbnail resolution now tracks the display so 4K panels stay sharp, the hand-edited config file is treated as hostile input that degrades to defaults instead of failing, and an empty wallpaper folder shows a dialog instead of a hotkey that silently does nothing. Random mode stays dialog-free so an unattended logon task can never hang on a modal box.

  5. A wallpaper that reported success and never appeared

    During acceptance, converted images set under a Microsoft Store install of Python returned success while the desktop kept the old wallpaper. Store-packaged apps have some file writes redirected into a private folder, and Windows reads the wallpaper from outside that sandbox, so the path it was given pointed at nothing. Resolving the real path before handing it to Windows fixed it, at the cost of one call.

  6. Live acceptance under komorebi

    All eight acceptance criteria passed, with the overlay summoned by the real hotkey while komorebi was running. A warm launch measured 0.30 seconds against a 1.5-second budget, and a cold run generated 72 thumbnails behind placeholders. The record states which checks were driven by synthetic events and which were done live, since synthetic input cannot prove the system delivers real keystrokes to the window.

    Method Whether Windows actually took each image format was confirmed from Windows' own record of the file it last used, not the API's return value.

Era II · 20 – 21 Aug 2026

Making it installable

Later the same day, the answer to "how do I install this?" went from "clone the repo and have Python" to a packaged build, package-manager manifests and a release pipeline, while public release was held back for real-world use.

  1. Public release gated behind living with it

    With v1 complete, the planning documents were distilled into the permanent docs and deleted, each part checked to have a home first. A shakedown phase of daily use was added between acceptance and release, because a scripted run cannot judge how a wallpaper picker feels. Old commits still held machine-specific paths, so cleaning the history was recorded as a step before going public.

    Brian's call Hold the repository private until real-world use had shaken out the annoyances a test run cannot reach.

  2. A version, and an update check off the launch path

    Gladius had no version string at all, so one became the single source for the command line, the build and the update check. The overlay only reads a small cached file; the network check runs after the window is up, at most once a day, and can only affect the next launch. A newer version shows as one quiet footer line naming the right upgrade command, and Gladius never updates itself.

  3. One build for every channel

    The app is packaged as a zipped folder bundle rather than a single self-extracting exe, which would unpack itself on every launch and cost seconds. The bundle started in 0.26 seconds, faster than running the script directly, and needs neither Python nor admin rights. The same zip serves winget, Scoop and a manual download, which also puts it in UniGetUI; Chocolatey was skipped for now because its per-version moderation suits a settled release, not a v1 still in testing.

    Method The Scoop manifest is generated by the release pipeline from the hash of the file it just uploaded, so it cannot disagree with what people download.

  4. An icon taken from the app

    The packaged exe had a default icon and a blank Properties pane. The new icon is three tiles sheared at the same angle as the strip, the middle one selected in the default border colour, built as a real multi-size icon file, and the exe now carries product, version and licence details.

  5. The release pipeline, proven without a release

    The release workflow ran green twice on manual runs: tests, build, an exe smoke test and a 46 MB artifact matching the local build. Its actions were moved off a runtime the build servers were deprecating, so the problem would not surface on a release day. The tag-triggered half, which publishes the release and fills the Scoop bucket, cannot be rehearsed without cutting a real release and was recorded as the part to watch.

Era III · 2 Oct 2026

Going public

The deferred cleanup before the source could be opened, and where the release stands.

  1. History scrubbed, the source made public

    Every commit was rewritten to replace machine-specific paths with placeholders, and the repository was recreated so no pre-rewrite version is reachable; a secret scan over the full history came back clean. The pre-publish check had already separated the two kinds of name in the repo: the author's name on the licence and manifests is meant to be public, while machine paths had to be zero. The source went public under MIT. The first tagged release, a test on a second machine without Python and the winget submission are still ahead.