Status: pre-alpha, design stage — no module exists yet
No line of this has touched a running scroll session yet
Unlike nixniri, which
is moving already-running code out of nixdesktop,
nixscroll starts from zero: nixdesktop never
supported scroll, so there is no existing module to extract.
Everything described on this page is the intended option
surface, not yet verified against a live compositor. Treat it
as a design document, not a changelog.
The split this repo exists to test
nixdesktop's shared policy and chrome layer (role policy, waybar, mako, swaylock, nwg-bar, eww, the idle/lock service) was written against niri first. Whether that layer is actually compositor-neutral, and not just designed with that intention, only gets settled once a second compositor plugs into it for real — that's the actual job this repo exists to do, not a side effect of it.
Packaging is explicitly out of scope
scroll isn't in nixpkgs. Consumers currently reach
it through the community package flake
scroll-flake.
nixscroll won't declare that as its own flake
input, for the same reason nixdesktop keeps noctalia out of
its inputs: a flake input is fetched on every evaluation, so
bundling a whole compositor-packaging flake would put it in
the closure of every consumer — including anyone who
already has scroll installed some other way.
What it will generate
A real sway-syntax config — not KDL
scroll is a fork of sway, so its config keeps sway/i3's classic directive syntax, not niri's KDL. Worth calling out plainly: nixscroll and nixniri do the identical job for sibling compositors, but render two structurally different file formats from two structurally different option shapes — this module can't just reuse nixniri's KDL renderer.
Installs nothing
Same contract as every config-generation module in this
family: this module will assume the scroll
binary already exists and never name a package or an absolute
binary path itself. Getting scroll onto the box — via
scroll-flake, a platform backend, or however else — is
explicitly someone else's job.
Software-rendering profile
A planned opt-in profile setting whatever this fork actually needs to fall back to software rendering (llvmpipe/pixman) instead of a GPU render node — for a VM or a genuinely GPU-less box. The same instinct behind nixdesktop's CPU-side toolkit defaults, one layer further down the stack, at the renderer itself rather than the toolkit above it. Not yet measured against a real GPU-less machine — see Status.
Escape hatches, matching family convention
Planned raw-passthrough options for anything the structured
surface doesn't model yet, following the same "structure for
the common case, an escape hatch for everything else" pattern
as nixniri's extraStartup/extraWindowRules/extraBinds/extraTopLevel.
Compositor-neutral policy stays upstream
nixdesktop keeps the role policy and the compositor-agnostic chrome — waybar, mako, swaylock, nwg-bar, eww. This repo will own exactly one thing: scroll's own config file.
Mechanism public, values private
No default will point at a specific hostname, monitor name, or personal keybind layout. Every default is meant to be a sensible one for any user — scroll's own upstream defaults where they exist, not this author's own setup.
The shape this will take
Matching nixniri's own module shape — not a tested example yet; see Status above.
1. Add the flake input
inputs.nixscroll.url = "github:julian-corbet/nixscroll-corbet-ch";
2. Import and configure
imports = [ inputs.nixscroll.homeManagerModules.scroll ];
nixscroll.scroll = {
enable = true;
softwareRendering = true; # no GPU on this box
};
3. Provide the binary yourself
This module never installs scroll. Add
scroll-flake
as your own input, or resolve it through whatever platform
backend your host already uses, and import both.
Where this fits
1. Compositor config — nixscroll / nixniri
Generates the compositor's own config file. Nothing else. Doesn't know or care what bar you run, what notification daemon you have, or what a "role" is.
2. Policy + shared chrome — nixdesktop
Which roles a session wants filled (file manager, polkit agent, notification daemon, bar), plus the compositor-agnostic pieces: waybar, mako, swaylock, nwg-bar, eww, and the idle/lock systemd service. Imports whichever compositor layer(s) a machine actually uses.
3. The hub
An actual machine's own config, importing nixdesktop plus exactly one compositor layer, resolved into real installed packages by a platform backend such as nixarch.
Roadmap (planned, not yet built)
Write the actual module
home/scroll.nix doesn't exist yet. This page
describes the target option surface; writing it against a real
running scroll session, on real hardware, is next.
Prove the software-rendering profile
Verified against a genuine GPU-less box, not assumed from scroll's own docs — the same discipline nixremote applied to hardware video encoding before calling it a default.
Settle the packaging story
Whether a platform backend ends up wrapping scroll-flake, or a consumer always adds it directly, is genuinely open.
Prove nixdesktop's neutrality claim
A real config importing both nixdesktop and nixscroll (not nixniri) side by side, confirming the shared chrome layer doesn't secretly assume niri anywhere.