Multi Monitor GDM Help

Hi All, I thought I would share something to help you if you are struggling in getting the GDM login screen to not show on the correct monitor if you have multi monitor setup. you have to first create a monitor.xml file in your /home/username/.config/ folder or this is automatically done and setup when you login with gnome and you set your monitor layout how you want there. Once done. Add the below to your configuration.nix file. Note the areas where you have to change the directory names to your user name first.

{ config, pkgs, ... }:
{
services.xserver.displayManager.gdm.enable = true;

systemd.services.copyGdmMonitorsXml = {
description = "Copy monitors.xml to GDM config";
after = [ "network.target" "systemd-user-sessions.service" "display-manager.service" ];

serviceConfig = {
  ExecStart = "${pkgs.bash}/bin/bash -c 'echo \"Running copyGdmMonitorsXml service\" && mkdir -p /run/gdm/.config && echo \"Created /run/gdm/.config directory\" && [ \"/home/your-username/.config/monitors.xml\" -ef \"/run/gdm/.config/monitors.xml\" ] || cp /home/your-username/.config/monitors.xml /run/gdm/.config/monitors.xml && echo \"Copied monitors.xml to /run/gdm/.config/monitors.xml\" && chown gdm:gdm /run/gdm/.config/monitors.xml && echo \"Changed ownership of monitors.xml to gdm\"'";
  Type = "oneshot";
};

wantedBy = [ "multi-user.target" ];
  };
}

once this is done run:

sudo nixos-rebuild switch
sudo systemctl restart display-manager

for most this should be it, however I had to do a reboot for it to show.

if still having issues follow the below…

Ensure Permissions: Make sure the GDM user has the necessary permissions to read the monitors.xml file. You can do this by running the following commands:

sudo chown gdm:gdm /home/user-name/.config/monitors.xml
sudo chmod 644 /home/user-name/.config/monitors.xml

Manually Copy the monitors.xml File: As a temporary measure, manually copy the monitors.xml file to the GDM configuration directory to see if it resolves the issue. Run the following commands:

sudo mkdir -p /run/gdm/.config
sudo cp /home/user-name/.config/monitors.xml /run/gdm/.config/monitors.xml
sudo chown gdm:gdm /run/gdm/.config/monitors.xml

Restart GDM: Restart the GDM service:

sudo systemctl restart display-manager

then do a final reboot too.

4 Likes

I’m new to NixOs, but this feels like it should be part of the wiki! thanks so much!

@hid4ri ! Thank you so much. I’ve spent hours trying to do this. You provided really useful easy to implement instructions. Way to go!

thank you so much! this frustrated me for a long time, glad to have found a fix for it

I think this no longer works with Gnome 49. At least for me

Edit: Nope, it still works. My issue was with my specific setup.

The path had changed with 49 from /run/gdm/.config/monitors.xml to /var/lib/gdm/seat0/config/monitors.xml, which is easy to adapt.

My issue was that I had used L instead of L+ in my setup using systemd tmpfiles:

  systemd.tmpfiles.rules =
    let
      monitors.xml = pkgs.writeText "monitors.xml" ''
      (...) # (my copy-pasted monitors.xml from $HOME/.config/monitors.xml)
      '';
    in
     "L /var/lib/gdm/seat0/config/monitors.xml - gdm gdm - ${monitors.xml}"
];

L creates a symlink, L+ overwrites if necessary. A simple change to L+ fixed my issue. Kinda obvious in hindsight. Not sure why the old symlink got borked, but it did. This should prevent similar issues in the future.

Thank you @hid4ri @nadir !

I can confirm the adapted version works for me after switching to /var/lib/gdm/seat0/config . I’m using GDM 49.2.

Here is a my adapted configuration, in case anyone want to reuse it:

  # Apply user monitor settings to login screen
  # by copying the user's monitors.xml to GDM's config directory
  systemd.services.applyUserMonitorSettings = let
    username = "USERNAME";
    gdmConfigDir = "/var/lib/gdm/seat0/config";
  in {
    description = "Apply user monitor settings to GDM login screen";
    after = [ "network.target" "systemd-user-sessions.service" "display-manager.service" ];
    wantedBy = [ "multi-user.target" ];

    serviceConfig = {
      Type = "oneshot";
      ExecStart = "${pkgs.bash}/bin/bash -c 'echo \"Applying user monitor settings to GDM login screen\" && mkdir -p ${gdmConfigDir} && echo \"Created ${gdmConfigDir} directory\" && [ \"/home/${username}/.config/monitors.xml\" -ef \"${gdmConfigDir}/monitors.xml\" ] || cp /home/${username}/.config/monitors.xml ${gdmConfigDir}/monitors.xml && echo \"Copied monitors.xml to ${gdmConfigDir}/monitors.xml\" && chown gdm:gdm ${gdmConfigDir}/monitors.xml && echo \"Changed ownership of monitors.xml to gdm\"'";
    };
  };