NixOS DWM Help with configuration

I want to know how to install and customize dwm.

1 Like

Welcome :wave:

You can find this information in the DWM wiki page.

For example, if you have a local dwm repo, this can be as easy as:

services.xserver.windowManager.dwm = {
  enable = true;
  package = pkgs.dwm.overrideAttrs {
    src = ./path/to/dwm/source/tree;
  };
};

You might want to commit the contents of the repo or use a git submodule if you’re using flakes, or you can also fetch the source from a remote repo.

Hello,

Thanks for the reply! I have added that into configuration.nix and ran the command "sudo nixos-rebuild switch’ and it errors out. I cloned dwm repo to my home folder and in conf.nix I placed src = ./home/jan/dwm. What did I do wrong? I can send a picture if needed.

It rebuilt successfully now, but on login in it says failed to start session.

I think it’s because it doesn’t find the dwm repo from the src. It can either be:

  • an absolute path (without the dot at the beginning): src=/home/jan/dwm
  • or a relative path to the file you’re currently editing: src=./dwm

For the second option, assuming you’re editing /etc/nixos/configuration.nix, you’d have the following structure:

/etc/nixos/
├── configuration.nix
└── dwm/

Remember, if you’re using flakes, you need to commit the dwm folder to the git project (don’t worry about it if you’re not). If your dwm config is already hosted in a remote repo, you can just specify that directly:

  services.xserver.windowManager.dwm = {
    enable = true;
    package = pkgs.dwm.overrideAttrs rec {
      pname = "dwm";
      version = "6.5";
      src = pkgs.fetchurl {
        url = "https://dl.suckless.org/dwm/${pname}-${version}.tar.gz";
        hash = "sha256-Ideev6ny+5MUGDbCZmy4H0eExp1k5/GyNS+blwuglyk=";
      };
    };
  };

In the above example, I’m using the default config from nixpkgs, so you just replace it with yours. You should of course replace pkgs.fetchurl with the fetcher that corresponds best with your source.

For example, if the config is hosted on GitHub, you do:

    src = pkgs.fetchFromGitHub {
      repo = "repo";
      owner = "owner";
      version = "...";
      rev = "...";
      hash = "...";
    };
  • Fill out all the repo information, but keep the hash empty.
  • Run nixos-rebuild build and wait for it to fail.
  • Copy the got: sha256-... hash it prints out to the hash attribute
  • Run sudo nixos-rebuild switch
Click this for a real example of a real dwm repo I found on GitHub
  services.xserver.windowManager.dwm = {
    enable = true;
    package = pkgs.dwm.overrideAttrs {
      src = pkgs.fetchFromGitHub {
        owner = "saloniamatteo";
        repo = "dwm";
        rev = "bb9b61617f40c46c441953758cf99e770ad02c55";
        hash = "sha256-4Yc2XHND3uiClaC9SgoukbWEV/Y2/XzSABXtuylacV0=";
      };
    };
  };

I built this on my system and it succeeded. Although I haven’t tested it.

Tip: Prepending an attribute set with rec allows you to access its elements from within the set. In the first example, we’ve used it to reuse the pname and version inside the source url.

If you want another example, click here.

Edit: I’ve just realized this, but the way dwm was defined is wrong:

- services.xserver.windowManager.dwm.package = {
+ services.xserver.windowManager.dwm = {

There is no dwm.package.enable or dwm.package.package.

Using the example from the Wiki, this is how to define the attributes:

Separate
services.xserver.windowManager.dwm.enable = true;
services.xserver.windowManager.dwm.package = pkgs.dwm.overrideAttrs {
  src = ./path/to/dwm/source/tree;
};
Nested
services.xserver.windowManager.dwm = {
  enable = true;
  package = pkgs.dwm.overrideAttrs {
    src = ./path/to/dwm/source/tree;
  };
};

Hello,
Thanks a lot for the fix, I got DWM to work now! But I also want to know how I can customize DWM with config.h

1 Like

Glad it’s working, now. I’ve never used dwm before, so I can’t help you with that unfortunately.

Still, thanks a lot!
If anyone can help about configuration it would be much appreciated!

1 Like

Just to clarify a bit, I want to link config.h and make it apply changes to that file.

If you mean applying patches, then according to the Wiki you can either include them as files or fetch them remotely:

  services.xserver.windowManager.dwm = {
    enable = true;
    package =
      (pkgs.dwm.overrideAttrs rec {
        pname = "dwm";
        version = "6.5";
        src = pkgs.fetchurl {
          url = "https://dl.suckless.org/dwm/${pname}-${version}.tar.gz";
          hash = "sha256-Ideev6ny+5MUGDbCZmy4H0eExp1k5/GyNS+blwuglyk=";
        };
      }).override
        {
          patches = [
            # for local patch files, replace with relative path to patch file
            ./path/to/local.patch
            # for external patches
            (pkgs.fetchpatch {
              # replace with actual URL
              url = "https://dwm.suckless.org/patches/path/to/patch.diff";
              # replace hash with the value from `nix-prefetch-url "https://dwm.suckless.org/patches/path/to/patch.diff" | xargs nix hash to-sri --type sha256`
              # or just leave it blank, rebuild, and use the hash value from the error
              hash = "";
            })
          ];
        };
  };

This way, you can also apply your own patches as well. Else, can’t you just directly edit config.h? Unless I’m misunderstanding something and that’s not how dwm is supposed to be configured.

I will try this solution. Editing config.h directly is not possible because DWM has to be compiled with “sudo make install” and that errors out, so we have to use another solution

As I understand from the Wiki, if you specify the whole repo as a source, then it will always compile it with your changes applied:

Using custom sources

If you have a locally stored source tree for dwm with changes already applied, you can use that instead:

However, use this if you’d like to go the patches route as I think it’s a bit cleaner compared to the previous example:

  services.xserver.windowManager.dwm = {
    enable = true;
    package = pkgs.dwm.overrideAttrs rec {
      pname = "dwm";
      version = "6.5";
      src = pkgs.fetchurl {
        url = "https://dl.suckless.org/dwm/${pname}-${version}.tar.gz";
        hash = "sha256-Ideev6ny+5MUGDbCZmy4H0eExp1k5/GyNS+blwuglyk=";
      };
      patches = [
        (pkgs.fetchpatch {
          url = "https://dwm.suckless.org/patches/alt-tab/dwm-alttab-6.4.diff";
          hash = "sha256-MiIFczEsIsK+lc07vZOeJHXphC9BdkEHgXJHQ/yPB/U=";
        })
        (pkgs.fetchpatch {
          url = "https://dwm.suckless.org/patches/autoresize/dwm-autoresize-6.1.diff";
          hash = "sha256-RIYw0Is9/H5yhWbH/HiOQdhDIs/IJAaGQIvP36QcUJM=";
        })
      ];
    };
  };

I included some example patches as well to give you an idea of how that would look.

I also found a solution from Chris Titus Tech’s GitHub page and it includes adding this to configuration.nix: nixpkgs.overlays = [
(final: prev: {
dwm = prev.dwm.overrideAttrs (old: {src = /home/jan/Downloads/dwm-6.5;}); #FIX ME: Update with path to your dwm folder
})
];
I add that, make changes to config.h, run “nixos-rebuild switch” it rebuilds successfully but does not make changes to DWM, I watched CTT’s video and on his system it did work

Using an overlay is not very different from the method above, you’re just replacing the src for dwm in all cases.

  nixpkgs.overlays = [
    (final: prev: {
      dwm = prev.dwm.overrideAttrs rec {
        pname = "dwm";
        version = "6.5";
        src = pkgs.fetchurl {
          url = "https://dl.suckless.org/dwm/${pname}-${version}.tar.gz";
          hash = "sha256-Ideev6ny+5MUGDbCZmy4H0eExp1k5/GyNS+blwuglyk=";
        };
        patches = [
          (pkgs.fetchpatch {
            url = "https://dwm.suckless.org/patches/alt-tab/dwm-alttab-6.4.diff";
            hash = "sha256-MiIFczEsIsK+lc07vZOeJHXphC9BdkEHgXJHQ/yPB/U=";
          })
          (pkgs.fetchpatch {
            url = "https://dwm.suckless.org/patches/autoresize/dwm-autoresize-6.1.diff";
            hash = "sha256-RIYw0Is9/H5yhWbH/HiOQdhDIs/IJAaGQIvP36QcUJM=";
          })
        ];
      };
    })
  ];

  services.xserver.windowManager.dwm = {
    enable = true;
  };

What’s different here is that in the dwm service, you don’t need to modify the package as by default it uses the system dwm, which you’re now overlaying to include your changes.

Solution found - These are the steps:
Get DWM
Copy DWM folder to /etc/nixos/
Go into that DWM folder and run “sudo cp config.def.h config.h”
Make changes to config.h
Add this into configuration.nix: services.xserver.windowManager.dwm.package = pkgs.dwm.overrideAttrs {
src = ./path/to/dwm/source/tree; #Place path to DWM source folder (here in my case it is ./dwm)
};
Run “nixos-rebuild switch” everytime you make changes to config.h
Reboot
Changes will be applied

Thanks for all the help!

2 Likes