Struggling with dwm

ive been trying to use dwm in nixos or a while now but i havent figured out how to link to a config.h and have it apply changes made to that file. I have gotten patches to work perfectly but i havent found any way to change things like font size or colors in dwm and st aswell. If anyone here uses dwm can you please tell me how you got it setup? thanks for any help

Looking at dwm’s source, this should work (caveat I’ve never used any of the suckless things myself):

{pkgs, ...}: {
  services.xserver.windowManager.dwm.package = pkgs.dwm.override {
    # Or alternatively `conf = ./config.def.h;`
    conf = ''
      static const char *fonts[]          = {
        "FiraCode Nerd Font Mono:size=16:antialias=true:autohint=true",
        "SauceCodePro Nerd Font Mono:size=16:antialias=true:autohint=true",
        "JetBrainsMono Nerd Font Mono:size=16:antialias=true:autohint=true",
        "RobotoMono Nerd Font:size=16:antialias=true:autohint=true",
        "Hack Nerd Font:size=16:antialias=true:autohint=true",
        "BlexMono Nerd Font Mono:size=16:antialias=true:autohint=true",
        "JoyPixels:size=12:antialias=true:autohint=true" };
    '';
  };
}

st has the same argument.

i added the conf = import ./config.def.h; and running nixos rebuild switch does show that it does read that file however i get an error:

error: syntax error, unexpected '=', expecting end of file

       at /etc/nixos/config.def.h:4:37:

            3| /* appearance */
            4| static const unsigned int borderpx  = 0;        /* border pixel of windows */
             |                                     ^
            5| static const unsigned int snap      = 32;       /* snap pixel */
(use '--show-trace' to show detailed location information)

I got the config straight from suckless so it isnt an actual error within the code

Argh, whoops, my bad, you don’t import it, just:

conf = ./config.def.h;

Foolish noob mistake on my part. I pay for my transgression in shame.

1 Like

thank you this works now, however im not sure how i can add patches now since i never did it using services.xserver.windowManager.dwm.package and also how i would do all of this for st

It also has a patches argument, presumably intended for exactly your use case:

{ pkgs, ... }: {
  services.xserver.windowManager.dwm.package = pkgs.dwm.override {
    conf = ./config.def.h;
    patches = [ ./my-fix.patch ]; # Or some `fetchPatch` thing
  };
}

As for st, you can do more or less the same:

{ pkgs, ... }: {
  environment.systemPackages = [
    (pkgs.st.override {
      conf = ./config.def.h;
      patches = [ ./my-fix.patch ]; # Or some `fetchPatch` thing
    })
  ];
}

st doesn’t need a special option like dwm because it’s much simpler to set up, so typically it’s just added to environment.systemPackages.

You can still use .override to your heart’s content, though, just don’t forget to put it in brackets or nix will think your arguments are a separate package.

i got patches on dwm working however when trying to add the config to st i get a bunch of errors about the file, im not sure if this is a problem with my nix config or with the st config. I got the config from st and didnt change anything except for font size.

      |                               int
/nix/store/p4q0pk9j5kzdlyl9c902iynhy297v2qn-libXft-2.3.6-dev/include/X11/Xft/Xft.h:266:34: note: expected 'XftDraw *' but argument is of type 'int'
  266 | XftDrawRect (XftDraw            *draw,
      |              ~~~~~~~~~~~~~~~~~~~~^~~~
x.c:1598:31: warning: passing argument 1 of 'XftDrawRect' makes pointer from integer without a cast [8;;https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wint-conversion-Wint-conversion8;;]
 1598 |                 XftDrawRect(xw.draw, &drawcol,
      |                             ~~^~~~~
      |                               |
      |                               int
/nix/store/p4q0pk9j5kzdlyl9c902iynhy297v2qn-libXft-2.3.6-dev/include/X11/Xft/Xft.h:266:34: note: expected 'XftDraw *' but argument is of type 'int'
  266 | XftDrawRect (XftDraw            *draw,
      |              ~~~~~~~~~~~~~~~~~~~~^~~~
x.c: In function 'xximspot':
x.c:1695:25: error: 'borderpx' undeclared (first use in this function)
 1695 |         xw.ime.spot.x = borderpx + x * win.cw;
      |                         ^~~~~~~~
x.c: In function 'xbell':
x.c:1761:13: error: 'bellvolume' undeclared (first use in this function)
 1761 |         if (bellvolume)
      |             ^~~~~~~~~~
x.c: In function 'match':
x.c:1792:56: error: 'ignoremod' undeclared (first use in this function)
 1792 |         return mask == XK_ANY_MOD || mask == (state & ~ignoremod);
      |                                                        ^~~~~~~~~
x.c: In function 'kmap':
x.c:1802:29: error: 'mappedkeys' undeclared (first use in this function)
 1802 |         for (i = 0; i < LEN(mappedkeys); i++) {
      |                             ^~~~~~~~~~
st.h:9:41: note: in definition of macro 'LEN'
    9 | #define LEN(a)                  (sizeof(a) / sizeof(a)[0])
      |                                         ^
x.c:1811:19: error: 'key' undeclared (first use in this function); did you mean 'Key'?
 1811 |         for (kp = key; kp < key + LEN(key); kp++) {
      |                   ^~~
      |                   Key
x.c: In function 'kpress':
x.c:1851:19: error: 'shortcuts' undeclared (first use in this function); did you mean 'Shortcut'?
 1851 |         for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) {
      |                   ^~~~~~~~~
      |                   Shortcut
x.c: In function 'run':
x.c:1937:34: error: 'shell' undeclared (first use in this function)
 1937 |         ttyfd = ttynew(opt_line, shell, opt_io, opt_cmd);
      |                                  ^~~~~
x.c:1988:36: error: 'maxlatency' undeclared (first use in this function)
 1988 |                         timeout = (maxlatency - TIMEDIFF(now, trigger)) \
      |                                    ^~~~~~~~~~
x.c:1989:50: error: 'minlatency' undeclared (first use in this function)
 1989 |                                   / maxlatency * minlatency;
      |                                                  ^~~~~~~~~~
x.c:1996:21: error: 'blinktimeout' undeclared (first use in this function)
 1996 |                 if (blinktimeout && tattrset(ATTR_BLINK)) {
      |                     ^~~~~~~~~~~~
x.c: In function 'main':
x.c:2032:20: error: 'cursorshape' undeclared (first use in this function); did you mean 'CursorShape'?
 2032 |         xsetcursor(cursorshape);
      |                    ^~~~~~~~~~~
      |                    CursorShape
x.c:2050:48: error: 'cols' undeclared (first use in this function); did you mean 'cosl'?
 2050 |                                 &xw.l, &xw.t, &cols, &rows);
      |                                                ^~~~
      |                                                cosl
x.c:2050:55: error: 'rows' undeclared (first use in this function)
 2050 |                                 &xw.l, &xw.t, &cols, &rows);
      |                                                       ^~~~
make: *** [Makefile:22: x.o] Error 1
error: builder for '/nix/store/yj96q0gnyzmd1jpwkjp6rrlcin7fnk2s-st-0.9.drv' failed with exit code 2
error: 1 dependencies of derivation '/nix/store/pjcici7k29jfi6kx1jlj7d345kyp6a3l-system-path.drv' failed to build
error: 1 dependencies of derivation '/nix/store/4smwwrkkswjwhivasdk68ic6aw9vfi94-nixos-system-nixos-23.05.2084.08700de174b.drv' failed to build

Looks to me like your config.def.h is for the wrong version of st, or a different program altogether. Various definitions are missing or of the wrong type, which presumably should have been set in that file. Make sure you get the file for st version 0.9.

In true suckless spirit, you’ll have to read the code to figure this one out otherwise - your nix code appears to be correct.