diff --git a/DECISIONS.md b/DECISIONS.md index 96e831f..91cf7a8 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -1,5 +1,30 @@ # Decisions +## 2026-10-07 – Nix fetches the DisplayLink driver itself + +- **Who**: Dominik, ClaudeCode +- **Why**: nixpkgs builds `displaylink` with `requireFile`. Because Synaptics + forbids redistribution, nixpkgs does not download the archive itself + (nixpkgs 48291b066d, NixOS/nixpkgs#28279). The 6.2.0-30 -> 6.3.0-48 bump + therefore stopped the system build until the zip was put into the store by + hand. The earlier comment claimed this was needed once per machine, but it is + needed for every driver version. +- **Tradeoffs**: + - Considered pinning URL and hash in the flake, but that means maintenance on + every version. + - Considered keeping the manual download. + - Considered a nixpkgs PR switching to `fetchurl`, which runs into the + licence argument. + - Considered a different dock, but foreign docks are used on the road. + - Chosen: read the URL with a regex from the `requireFile` message, where + nixpkgs keeps it current. This depends on the message wording. If the line + disappears, evaluation stops with an error. +- **How**: + - `pkgs/displaylink.nix` is an overlay that replaces `requireFile` with + `fetchurl`. It takes name and hash from nixpkgs. + - It is applied for all hosts in `nixosModules.moonarch`, because the NixOS + module reads `pkgs.displaylink` directly. + ## 2026-09-30 – xdg-open goes through the portal, so FHS sandboxes get Firefox - **Who**: Dominik, ClaudeCode diff --git a/flake.nix b/flake.nix index bfe75cd..872555b 100644 --- a/flake.nix +++ b/flake.nix @@ -125,6 +125,9 @@ ./modules/zed.nix ]; + # Lets Nix fetch the DisplayLink driver itself, see pkgs/displaylink.nix. + nixpkgs.overlays = [ (import ./pkgs/displaylink.nix) ]; + _module.args = { moonarchSrc = inputs.moonarch; moonarchPkgs = moonarchPackages; diff --git a/hosts/thinkpad/default.nix b/hosts/thinkpad/default.nix index 3b48d02..6d14c52 100644 --- a/hosts/thinkpad/default.nix +++ b/hosts/thinkpad/default.nix @@ -125,9 +125,9 @@ # displaylink.nix, which pulls in evdi, the service and the udev rules; the # option is read on its own and does not start an X server. # - # pkgs.displaylink is unfree and fetched with requireFile, because Synaptics - # forbids redistribution. The archive has to be placed in the store by hand - # once per machine, see DECISIONS.md. + # pkgs.displaylink is unfree and nixpkgs fetches it with requireFile, because + # Synaptics forbids redistribution. The overlay in pkgs/displaylink.nix lets + # Nix download the archive itself, for every new driver version. services.xserver.videoDrivers = [ "displaylink" "modesetting" ]; services.fstrim.enable = true; diff --git a/pkgs/displaylink.nix b/pkgs/displaylink.nix new file mode 100644 index 0000000..7b89988 --- /dev/null +++ b/pkgs/displaylink.nix @@ -0,0 +1,26 @@ +# ABOUTME: Overlay that lets Nix fetch the DisplayLink driver itself. +# ABOUTME: Swaps nixpkgs' requireFile for fetchurl, with name, hash and URL taken from nixpkgs. + +# nixpkgs builds displaylink with requireFile, so every new driver version +# stops the build until the archive is put into the store by hand. nixpkgs keeps +# name, hash and download URL current, but the URL only appears inside the +# requireFile message ("nix-prefetch-url --name "). Reading it from +# there means nothing in this flake has to be maintained per version. Should +# nixpkgs drop that line, evaluation stops here instead of falling back to the +# manual step. +final: prev: { + displaylink = prev.displaylink.override { + requireFile = + args: + let + url = builtins.match ".*nix-prefetch-url --name [^ ]+ (https://[^[:space:]]+).*" args.message; + in + if url == null then + throw "displaylink: the nixpkgs requireFile message has no direct-download URL any more, see pkgs/displaylink.nix" + else + final.fetchurl { + inherit (args) name hash; + url = builtins.head url; + }; + }; +}