On modern GNOME systems (mutter 49+), the GDM login greeter ignores external displays and always appears on the internal laptop panel, even when an external monitor is connected and configured correctly in the user session.
Every guide online tells you to copy your monitors.xml to:
/var/lib/gdm/.config/monitors.xml
This no longer works. In mutter 49+, GDM's XDG_CONFIG_HOME is not
/var/lib/gdm/.config — it is:
/var/lib/gdm/seat0/config
Mutter looks for monitors.xml at /var/lib/gdm/seat0/config/monitors.xml.
The file at /var/lib/gdm/.config/monitors.xml is never read.
cat ~/.config/monitors.xmlsudo mkdir -p /var/lib/gdm/seat0/config
sudo cp ~/.config/monitors.xml /var/lib/gdm/seat0/config/monitors.xmlThe seat0/config directory is owned by GDM's dynamic UID (not the named gdm user).
Match the directory's owner automatically:
sudo chown --reference=/var/lib/gdm/seat0/config /var/lib/gdm/seat0/config/monitors.xmlOr find the UID manually and set it explicitly:
ls -ld /var/lib/gdm/seat0/config
# e.g. shows UID 60578
sudo chown 60578:60578 /var/lib/gdm/seat0/config/monitors.xmlThe GDM greeter should now appear on the external display.
- Fractional scaling in GDM: GDM may not support fractional scaling reliably.
If your user session uses a fractional scale (e.g. 1.333), use
scale=1in the GDM monitors.xml to avoid rendering issues. The user session applies its own scale after login independently. - No external display connected: GDM falls back to the internal display automatically when no external display is present.
Enable mutter debug logging to see which config path GDM is actually reading:
Edit /etc/gdm/custom.conf and add:
[debug]
Enable=trueCreate /etc/systemd/system/gdm.service.d/debug.conf:
[Service]
Environment=G_MESSAGES_DEBUG=mutterjournalctl -b -u gdm | grep -i "monitor\|config"
journalctl -b | grep -i "mutter\|monitor" | head -80Look for the path mutter reports when loading monitor configuration — this will
confirm whether it is reading from seat0/config or falling back.
Remember to remove the debug config once you're done.
Tested on:
- Distro: Bluefin (Universal Blue / immutable Fedora, rpm-ostree based)
- Hardware: ThinkPad T480, Intel integrated GPU
- Display: ARZOPA USB-C display on DP-1, 2560×1600
- GNOME / mutter: 49.4
- Kernel: 6.18.x
- Persistence: Confirmed across 3 reboots —
seat0/configis not ephemeral
/etc and /var are mutable on rpm-ostree systems, so this fix applies as-is.
No layering or workarounds needed.