How to set desktop wallpaper on NixOS

You! Yes, you! I’ve discovered something wonderful; NixOS let’s you set a background image and it’s easy as pie. Just place an image at $HOME/.background-image and you’ll be ready to rock! That’s the TLDR for those looking for the quick and dirty. But how did I figure this out? There’s no documentation, at least at the time of writing that I could find, that explains this. Well if you are just starting with NixOS this can be a frustrating experience so I thought well maybe I’ll just document my frustrating experience and maybe someone will get something out of it. Why not?

Before I figured this out I would login and run a command that would set my background for me:

feh --bg-fill "path/to/background.jpg"

But there must be a better way than manually setting it every time. Maybe a script that executes on login? No, there has to be some kind of configuration for this through the NixOS configuration. Every problem I’ve ran across so far had some kind elegant solution that was better than my hacks. The problem is that you can’t always search a phrase and get the results that you want, so you dig. But where should we start digging? How do we dig? Where do I import the dig function from?

The NixOS manual has a chapter on the X Window System that talks about how you can start configuring it. To enable it you simply need this line in your /etc/nixos/configuration.nix:

services.xserver.enable = true;

If you weren’t already aware, settings like these end up in a giant set that you can interactively poke around in with the help of nix repl:

$ nix repl
Welcome to Nix version 2.3.9. Type :? for help.

nix-repl> :l <nixpkgs/nixos>
Added 6 variables.

nix-repl> config

...long output

The :l <nixpkgs/nixos> loads your configuration into the repl shell. Everything in /etc/nixos/configuration.nix can be inspected through the config variable. So now we have a way to try and start digging for a way to set our background. I know from the documentation that you can switch desktop manager easily so there’s probably a way to save the desktop background somewhere so each one can re-use it. So I start by looking through the attributes in desktopManager

{ cde = { ... }; cinnamon = { ... }; default = null; e19 = { ... };
enlightenment = { ... }; gnome3 = { ... }; kde5 = { ... }; kodi = { ... };
lumina = { ... }; lxqt = { ... }; mate = { ... }; pantheon = { ... }; plasma5 =
{ ... }; session = [ ... ]; surf-display = { ... }; wallpaper = { ... }; xfce =
{ ... }; xfce4-14 = { ... }; xterm = { ... }; } is the same as the services.xserver options that you set in your /etc/nixos/configuration.nix

Browsing through the attributes we notice there is one called wallpaper. This seems as good a place as any to start:

{ combineScreens = false; mode = "scale"; }

Well this is kind of useful? Where’s the path? There should be a link to the picture somewhere. If I can find some information in the repl it’s a good hint at where to start looking in the code. Where do we start looking at the nix code? Why the [nixpkgs github repo] of course. I have it cloned locally as I end up grepping quite a bit for the things I want. This info will help us narrow our search down a bit.

$ cd nixpkgs/nixos
$ grep -rn 'wallpaper'
nixos/modules/services/x11/desktop-managers/default.nix:31:      wallpaper = {

Bingo. Let’s take a peak at some of the code.

wallpaper = {
  mode = mkOption {
    type = types.enum [ "center" "fill" "max" "scale" "tile" ];
    default = "scale";
    example = "fill";
    description = ''
      The file <filename>~/.background-image</filename> is used as a background image.

Well that solves it right there. It appears that we can just place an image at ~/.background-image and that will get picked up automatically at login. Now this is may all seem a little confusing but hopefully it helps highlights two important debugging tools for familiarizing yourself with NixOS. The interactive repl is great for looking through options to see what available, you can also search on the NixOS options search page. As well, nothing beats old fashioned text searches with your favourite pattern matching tool.