development log
FF00 VWM alpha.1: from an X11 workaround to a packaged application
The first public FF00 VWM release turns a manual video-wallpaper process into a bounded Rust application, publishes reproducible Nix packaging, and begins registration with NUR.
FF00 VWM began with a narrow irritation: playing a video is easy, but making
that video behave as a wallpaper on an X11 desktop is a collection of small,
failure-prone decisions. A command has to identify the correct display
geometry, create a window at the desktop layer, attach mpv, choose a scaling
mode, survive the configuration window closing, and later stop only the
processes it owns. Doing that once in a terminal is manageable. Doing it for
multiple monitors after every login is no longer a useful ritual.
The first public preview, 0.1.0-alpha.1, packages that process as a GTK4 and
Rust application. This is not a claim that X11 wallpaper management is solved.
It is a documented foundation with an intentionally small support boundary:
Linux x86_64, an X11 session, local video files, XRandR display names, and mpv
as the media engine.
What alpha.1 contains
The interface discovers connected XRandR outputs and presents one assignment card for each display. A user can select a local video with the native file chooser, choose Fit, Fill, Stretch, or Center, and apply the configuration. Each output can have an independent source and presentation mode.
The configuration window is not the wallpaper owner. It starts a dedicated renderer process, waits for that renderer to report readiness, and then allows the GUI to close. That separation matters: closing a settings window should not unexpectedly remove the wallpaper it configured.
The renderer creates an X11 wallpaper window directly and passes its numeric
window identifier to mpv. It does not require xwinwrap, and it does not ask
i3 to reinterpret an ordinary application window as a desktop object. The
process relationship is deliberately explicit:
GTK configuration interface
│
├── starts one FF00 VWM renderer per assigned output
│ │
│ ├── creates the X11 wallpaper window
│ └── starts mpv attached to that exact window ID
│
└── may close after readiness is confirmed
Saved assignments can be restored at X11 login, but autostart remains opt-in.
The application records enough runtime identity to stop the renderer groups it
created while leaving unrelated mpv sessions alone. Paths are passed as
arguments rather than assembled into shell command strings, so filenames with
spaces do not become quoting problems and media filenames are not interpreted
as shell syntax.
The release includes seventeen automated tests around configuration, dependency parsing, display geometry, renderer arguments, process identity, runtime state, and autostart quoting. Manual release checks additionally cover the real X11 behaviour that a unit test cannot prove on its own.
Why the first release remains an alpha
The support boundary is honest because the rough edges are real. XRandR output names can change when hardware or docks change. Display hot-plugging is not yet a live reconciliation system. The current per-monitor Apply control passes through the shared saved-configuration path, so applying one card can restart all configured connected outputs even though the status message names the card that initiated the operation. That behaviour is documented rather than hidden, and it should be refined in a later interface pass.
There is also no image renderer yet. The current application is a video wallpaper manager, not a general promise about every wallpaper source or every desktop environment. Wayland, network streams, playlists, audio playback, and animated image formats remain outside this release.
Reproducible packaging before convenience claims
The upstream repository contains a Nix flake with a locked dependency graph.
The package builds the Rust source, installs the desktop entry and application
icon, wraps the GTK environment, and supplies mpv on the application runtime
path. On a flake-enabled Nix system, the direct project route is:
nix profile install 'github:crimsonvariable/ff00-vwm?ref=v0.1.0-alpha.1'
That installation path is already independent of NUR. It follows the project repository directly and remains the fastest way to obtain a newly tagged release.
For broader discovery, a separate
crimsonvariable/nur-packages
repository now exposes the release through a conventional NUR package set. The
NUR expression does not package a mutable local checkout. It fetches the
immutable v0.1.0-alpha.1 Git tag, verifies the source hash, vendors the exact
Cargo dependency graph, runs all seventeen tests, and wraps the resulting
binary with its runtime dependency.
That package repository can also be used directly before registry acceptance:
nix profile install github:crimsonvariable/nur-packages#ff00-vwm
On 3 August 2026, the crimsonvariable repository was submitted for NUR
registration in
nix-community/NUR#1190.
The wording is important: the submission is open and under NUR review. FF00 VWM
must not be described as available through NUR until that pull request is
merged and NUR has indexed the repository.
Once registration is complete, the package attribute will be:
environment.systemPackages = [
pkgs.nur.repos.crimsonvariable.ff00-vwm
];
NUR is an appropriate home for this phase because it can index prereleases and smaller-audience packages without presenting them as reviewed nixpkgs packages. A future nixpkgs contribution remains a separate milestone with a separate review standard.
The public release boundary
Forgejo remains the canonical source of truth. GitHub is the public mirror and release surface. The tagged release carries source history, release notes, an x86_64 archive, and checksums. The application is public under AGPL-3.0-or-later, with contribution and copyright terms recorded in the repository and through crimsonvariable.com.
Private media paths, personal configuration, detected display state, and VPS operations are not part of the public project. The public repository explains how the system works without turning one machine’s runtime state into example data.
This development log is the first entry in the site’s Field Notes collection. The entry exists once, in chronological order, and is associated with FF00 VWM, the Nix configuration, and the portfolio website through metadata. Those project pages can surface the record without maintaining three separate blogs or duplicating the text.
Next: harden ownership, then add images
Before the renderer gains another source type, the first update will harden the
existing lifecycle. Independent GUI, command-line, and login-restore processes
must serialize changes through a dedicated runtime lock. Startup reconciliation
must safely remove stale records and recover an orphaned FF00 VWM renderer only
when application-specific evidence proves ownership. The mpv child will also be
started with --no-config, keeping unrelated user or system mpv configuration
outside the wallpaper-renderer contract.
This work is ordered before image support because adding another renderer path should not multiply a known lifecycle race. It preserves the existing rule that FF00 VWM never identifies ownership through a broad process-name match and never signals an unrelated mpv session.
The following development phase is static-image support.
The next development phase is static-image support. The goal is not to become an image editor and not to modify a downloaded wallpaper on disk. The renderer should treat rotation and mirroring as presentation instructions:
decode source
→ honour embedded orientation
→ apply user rotation
→ apply horizontal or vertical mirroring
→ calculate fit, fill, stretch, center, or tile
→ render to the assigned X11 background region
The first guaranteed image formats should include PNG, JPEG, WebP, and SVG, with additional modern formats included where the pinned Nix decoder closure can support and test them consistently. A downloaded WebP should be selectable directly. Rotating it by 90 degrees should affect only its presentation on the chosen display. The original file should remain byte-for-byte unchanged.
This changes the product description in a useful but controlled way: FF00 VWM
becomes a per-monitor image and video wallpaper manager for X11. Video remains
backed by mpv; images gain a purpose-built rendering path. The same assignment
model, configuration boundary, and per-output presentation controls can serve
both.
The alpha therefore closes with a working release rather than a declaration of completion. The manual workaround has become a packaged, testable application. NUR registration is in review. Lifecycle hardening is the first update; ordinary and modern image files become first-class sources after that foundation is closed, without forcing users to convert or destructively edit them beforehand.