A minimal Plasma 6 wallpaper with Sierpiński, Mandelbrot, Julia, and Lorenz visualizations. Sierpiński uses an exact symbolic child rebase. Mandelbrot and Julia move through curated bounded detail regions and crossfade back into the next root view, so no mode accumulates a large world-space coordinate.
The runtime is pure QML plus a precompiled Qt shader package. It creates no image frames, performs no polling, and writes no progress files. The symbolic branch address exists only in memory and starts over when Plasma reloads the wallpaper.
These short clips compress one full cycle of each zoom mode and the Lorenz orbit's 48-second rotation. The zoom speed is configurable in Plasma.
Sierpiński: The view zooms into a child triangle and rebases its symbolic address at the end of the cycle, keeping the image continuous.
Mandelbrot: The camera moves into a bounded detail region, then crossfades to the next root view.
Julia: A different bounded detail region and root view appear each cycle.
Lorenz: The orbit slowly rotates while its ribbon colours shift. This clip compresses one full rotation into a short loop.
Install the Plasma runtime, Qt Quick, Qt Shader Tools, KPackage, and build tools:
sudo pacman -S --needed plasma-workspace qt6-declarative qt6-shadertools kpackage make jq libxml2Qt's shader baker is installed as /usr/lib/qt6/bin/qsb on Arch. Override the
path if your Qt installation differs:
make QSB=/path/to/qsbmake
make check
make previewThe build creates a complete package at
build/io.github.gqgs.endlessfractal/, including the generated
contents/shaders/sierpinski.frag.qsb. The preview is a regular Qt Quick window
and does not modify Plasma's current wallpaper.
To regenerate the README animations from the built package in a graphical
desktop session, run python3 scripts/capture_readme.py. This also requires
ffmpeg.
ShaderEffect requires a hardware-supported Qt Quick scene graph backend. It
will not render with QT_QUICK_BACKEND=software.
Install or upgrade the wallpaper for the current user:
make installIf Endless Fractal was already active while upgrading, recreate Plasma's running QML instance after installation:
make reloadkpackagetool6 --upgrade replaces the package and refreshes its settings page,
but Plasma does not hot-reload an already-running wallpaper component. You can
alternatively switch to another wallpaper type, apply, then switch back.
kpackagetool6 installs it at:
~/.local/share/plasma/wallpapers/io.github.gqgs.endlessfractal/
Then:
- Right-click the desktop and choose Configure Desktop and Wallpaper.
- Select Endless Fractal from Wallpaper type.
- Choose the fractal, set Seconds per zoom cycle, and apply.
If a previously opened settings window does not discover the new plugin, close and reopen it. The equivalent explicit Plasma reload command is:
systemctl --user restart plasma-plasmashell.serviceFollow runtime messages with:
journalctl --user -u plasma-plasmashell.service -fRemove the installed copy with make uninstall. The source checkout and build
directory remain available for reinstalling it.
ZoomController.qmlowns the address and the current one-level transition.BranchPolicies.jsimplements the current uniform-random policy behind a smallselectNext(address, context)-style contract.FractalView.qmlselects one of three compiled shaders while exposing the same bounded local state to eachShaderEffect.sierpinski.fragperforms inverse-IFS traversal and level-aware coloring.mandelbrot.fragandjulia.fraguse escape-time rendering, bounded camera transforms, curated detail targets, and endpoint-matched crossfades.LorenzView.qmlintegrates the Lorenz system and renders its orbit as a slowly rotating, colour-shifting ribbon.
At a transition endpoint, sampling the selected child adds one inverse-IFS level. Committing that child adds one to the address depth, so the palette phase is unchanged across the coordinate reset. This makes the rebase visually continuous without retaining an absolute camera coordinate.
Mandelbrot and Julia are not exactly affine self-similar. Their cycles therefore finish by crossfading to the next bounded root scene; at the endpoint that scene exactly matches the frame after the controller resets its local progress.
GPL-2.0-or-later.



