How can I set my display resolution with nix?

I just put NixOS on my Surface Go and the screen is too small. I can change it to a setting I like by running xrandr --output <display> --scale .7, but that is ephemeral. I’m hoping there’s a way I can just set my resolution in my configuration.nix, but I can’t figure out how. I’ve tried setting the value I want in both services.xserver.resolutions and services.xserver.virtualScreen, as well as setting services.xserver.exportConfiguration to true, but nothing works. It does seem like when I set virtualScreen to something, it causes my resolution to change, but only to some predetermined value - it doesn’t seem to actually use the numbers I give it.

1 Like

Firstly, have you considered increasing services.xserver.dpi?

Typically this is what you want to do to increase the size of content on the screen. It’ll make the applications scale their content, rather than your display drawing pixels bigger, which results in big and finely detailed drawings instead of big pixels.

Normally this should be auto-detected, but I’ve found this to be flaky. It’s worth reading on the arch wiki on the topic.

If you try this you might also want to set environment.variables:


And similar settings if you find some applications don’t respect that setting, and maybe use a bigger mouse cursor icon. Some legacy-ish things haven’t gotten used to the high dpi world we live in :slight_smile:

If you’re set on resolutions, I believe the reason your .resolutions doesn’t work is because drivers can refuse to set resolutions that they do not support. It’s worth checking with xrandr -q if your monitor actually supports that resolution.

If that doesn’t fix it, I’d check that the right xorg config is actually generated and manually start from a tty with startx/xinit to make sure my display manager isn’t mucking with my config. I believe lightdm by default plays with xrandr.

1 Like

Thank you for your answer, but sadly it doesn’t work for me. certain important things are still too small.
You were correct about the resolutions, I must have been trying ones that weren’t supported. Funny thing is, not a single smaller resolution (other than maybe the ones that are so small I didn’t check) has the same aspect ratio of my screen! so I can’t use that either.
I set up that xrandr command for scaling my display to always run when i3 starts, and that worked, until I set up vsync - then it broke.
So sadly, it seems I’m just gonna be stuck manually scaling the display every time I reboot :pensive:

If you can list the exact things various people here can probably help working through how to fix them; As I said, certain older applications haven’t learned about dpi yet, but they usually do have scaling features anyway :slight_smile:

Well I just realized that setting the scaling manually breaks my vsync, so maybe I’ll have to go the DPI + make thing bigger route after all. I think I can figure out how to size everything that I’ve noticed is too small so far other than the cursor. I changed my gtk-cursor-theme-size but that only takes effect on some windows. Would you happen to know how to do this?

Maybe it is a good idea to check out the hidpi section on the wiki: Xorg - NixOS Wiki

I happen to know this one; x applications and gtk applications take their cursor config from different locations.

Maybe changing this is enough, if you’re using a window manager that doesn’t set any X related things on startup:

If that doesn’t help, check the arch wiki on the topic and set those options manually.

Or, if you use home-manager, you want:

I believe qt listens to X, so you shouldn’t need to worry about that.

Make sure your x cursor theme is the same as your gtk cursor theme, and that it supports the cursor size you want.

And yes, it’d be awesome if you could update the hidpi section in the wiki when you know it all works (or share your config here so someone else can) :slight_smile:

Maybe we can improve the settings, too, this is clearly a little unwieldy.

Okay, so I’ve been able to set my cursor size on the display manager using

I’ve been able to set the cursor on the “desktop” of i3 by throwing "exec_always ${p.xorg.xsetroot}/bin/xsetroot -xcf ${p.icons.breeze.cursors.breeze}/cursors/left_ptr ${toString cursor-size}" in my i3 config. (although I’m gonna have to do that for all cursor, not just left_ptr)

I’ve been able to set the cursor size on applications that respect gtk-cursor-theme-size.

Which leaves two obvious things still sicking out. My cursor is still small when over:

  • the i3 works space/status bar
  • alacritty (also checked xterm since I have it on my system and it’s also small)

I’m very very surprised there isn’t just a global “cursor size” setting on linux.

You might have more success using anything wayland based anyways. Scaling isn’t really what XOrg is good at.
Sway and Gnome on wayland are pretty good.

Pointing xrdb -merge at your ~/.Xresources is probably nicer than that startup script :slight_smile:

My guess is that alacritty and i3 happen to use a cursor variant whose size you didn’t explicitly set (i.e. top-left-arrow or such). Both of them use X directly rather than going through a toolkit, so they may be the only applications you use that actually test the X config properly.

Set Xcursor.size in your~/.Xresources to cover all of them (and load with xrdb -merge if your xinit chain doesn’t - that of lightdm should).

Generally, it would make more sense to use the icon theme as intended and set it with xrdb for consistency - just need to orchestrate installing the package.

I believe NixOS will set up theme paths correctly by default if you actually install the package instead of pointing an executable to its path, so if you add it to environment.systemPackages you can just set Xcursor.theme to its name.

The display manager setting is special because it runs as root - it should not be configured with user settings. Why gnome themes need to be set separately is a bit beyond me, too, but most likely an artefact from when X didn’t allow for flexible theming and a gnomie wanted bigger icons.

I was under the impression that X settings from lightdm will carry over to the user session, though. Perhaps the NixOS xinit scripts, or your i3 config do some sanitization that removes the cursor settings.

Wayland would indeed solve this, but their solution is more of a band-aid because xwayland will simply be scaled up linearly if not configured correctly. That defeats the point of hidpi displays, and results in hazy pictures. It’s probably the way to bring things forward, and makes for an easier out-of-the box experience, but it’s still best to configure the underlying X a bit.

I have my .Xresources file as Xcursor.size: 200. Running xrdb -merge has no noticeable effect on my cursor size anywhere. Nor does it apply on restart (I use lightdm).

Yeah, I have services.xserver.displayManager.lightdm.greeters.gtk.cursorTheme.size = 50;, and I do see that size of cursor on the login screen, but it goes back to being small when I log in.

You need xrdb -merge ~/.Xresources. xrdb doesn’t load from a default location.

If the lightdm cursor setting only sets the gtk cursor size, it makes sense that it wouldn’t carry over into your X configuration.

I assume it still won’t work. The next things to check are:

  • X cursor theme is loaded correctly and contains the set size
  • Output of xrdb -query
  • Maybe i3 only reads the settings when it starts
    • Try i3 restart after you’ve merged the config in
    • Put the commands in .xsession or .xinitrc if that helps (not sure which lightdm reads, if either)

Now if that still doesn’t work I’m out of ideas :wink: