Set external monitor as primary display before login

This may be a general linux question rather than NixOS, I’m not sure.

But I have a laptop, all working fine. When I boot up the display all goes to the laptop screen until after I am logged in in which case the second monitor becomes primary. My question is, is there a way to set this as the primary or preferred monitor earlier in the process so that at least the login prompt is on the external monitor and not the laptop’s own display?

UPDATE: My digging has led to both grobi and autorandr, I think both can do what I need. I’ll try grobi first as it seems a little simpler

UPDATE2: Using grobi from hom-manager does not seem to work but I guess this makes sense as that won’t take affect until I am logged in so I should probably do this at a system level.
I also discovered autorandr-rs which is a rust implementation. I’m still guessing a bit but I think the tools are there if I can work out how to configure them

What WM or DE do you use ?

Gnome so it’s GDM that needs to know about the monitor.

I have a solution, it may mot be the best but it does what I need. I’ll add in a different post

I tried various things. Grobi only runs once logged in. Autorandr doesn’t appear to support Wayland so I gave up on that.

The solution I came to is to copy the monitors.xml that is in my ~/.config directoy into /run/gdm. I firstly tried to do this directly but since it was outside the scope of my flake it failed so I copied it into my git and then referenced from there and it works as I would like.

{ config, pkgs, ... }:

let
  monitorsXmlContent = builtins.readFile ./framework/monitors.xml;
  monitorsConfig = pkgs.writeText "gdm_monitors.xml" monitorsXmlContent;
in
{
  systemd.tmpfiles.rules = [
    "L+ /run/gdm/.config/monitors.xml - - - - ${monitorsConfig}"
  ];
}

You may want to try setting a video mode in the kernel parameters to be used at boot using boot.kernelParams. Add the external display and mode to your config using something like boot.kernelParams = [ "video=HDMI-1:1920x1080@60" ] and if the display is connected at boot time it should be used instead of the internal display. If you do this you may want/need to enable early KMS by adding your video driver to boot.initrd.availableKernelModules in a manner such as boot.initrd.availableKernelModules = [ "i915" ]. See the ArchWiki Kernel mode setting page for more info, specifically the Forcing modes section.

Interesting. I will try this and see if it uses the external monitor earlier.

It’s the Framework laptop with AMD chipset and external monitor is via a USB-C dock

This didn’t make any noticeable difference. It will use the main display for GDM from my change above but the rest of the boot process all shows on the laptop screen.

I added amdgpu as an available kernel module and video=DP-2:3840x2160@30 in boot.kernelParams. It didn’t make any noticeable difference. I wondered if it didn’t like going to 4K so I tried 1920x1080 however I typed 192x1080 and it made the display on the laptop really narrow so it did affect the resolution but still didn’t display on the external monitor