Skip to content

Instantly share code, notes, and snippets.

@mlongval
Created March 9, 2026 19:38
Show Gist options
  • Select an option

  • Save mlongval/5f43f97a3de5574b9d8430c6f3e8f4ee to your computer and use it in GitHub Desktop.

Select an option

Save mlongval/5f43f97a3de5574b9d8430c6f3e8f4ee to your computer and use it in GitHub Desktop.
GDM greeter on external display — mutter 49+ correct monitors.xml path (seat0/config)

GDM Greeter on External Display (mutter 49+ / GNOME 47+)

The Problem

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.

Why the Common Fix Doesn't Work

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.

The Fix

1. Find your user monitors.xml

cat ~/.config/monitors.xml

2. Copy it to the correct GDM path

sudo mkdir -p /var/lib/gdm/seat0/config
sudo cp ~/.config/monitors.xml /var/lib/gdm/seat0/config/monitors.xml

3. Set correct ownership

The 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.xml

Or 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.xml

4. Reboot and verify

The GDM greeter should now appear on the external display.

Caveats

  • 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=1 in 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.

Debugging (if it still doesn't work)

Enable mutter debug logging to see which config path GDM is actually reading:

1. Enable GDM debug mode

Edit /etc/gdm/custom.conf and add:

[debug]
Enable=true

2. Set mutter log environment variable

Create /etc/systemd/system/gdm.service.d/debug.conf:

[Service]
Environment=G_MESSAGES_DEBUG=mutter

3. Reboot, then check logs

journalctl -b -u gdm | grep -i "monitor\|config"
journalctl -b | grep -i "mutter\|monitor" | head -80

Look 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.

Environment

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/config is not ephemeral

Note for rpm-ostree / Bluefin users

/etc and /var are mutable on rpm-ostree systems, so this fix applies as-is. No layering or workarounds needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment