User Tools

Site Tools


kde_windows_issue

Windows Piling at the Monitor Seam — KDE X11, amdgpu, Odyssey G9

Fix for every window gathering at the boundary between the two monitors after the screens blank. Verified on linux-cachyos 7.1.4-1, KDE Plasma on X11, amdgpu driving a PowerColor RX 6600 XT, systemd-boot.

The layout: Samsung Odyssey G93SC (5120×1440) is primary at +0+0 on DisplayPort-1. The 1080p sits to its right at +5120+206 on DisplayPort-0. To the kernel, the G9 is card1-DP-2 — the names do not match, see the gotchas.

Quick Reference

Task Command
Check session type echo $XDG_SESSION_TYPE
Current layout xrandr –listmonitors
Log RandR events xev -root -event randr
Map DRM connector to panel head -3 /sys/class/drm/card1-DP-*/modes
Dump G9 EDID cp /sys/class/drm/card1-DP-2/edid /usr/lib/firmware/edid/g9.bin
Kernel parameters video=DP-2:e drm.edid_firmware=DP-2:edid/g9.bin
Rebuild initramfs sudo mkinitcpio -P
Confirm EDID in initramfs sudo lsinitcpio /boot/initramfs-linux-cachyos.img
Confirm params are live cat /proc/cmdline

What Is Actually Happening

The G9 has DisplayPort Deep Sleep and Samsung gives no OSD toggle for it. After the screen has been dark for a while — minutes, not seconds — the panel drops the DP link completely. amdgpu sees a hot-unplug, X tears down the G9's CRTC, and the only desktop left is the 1080p at x=5120. KWin evacuates every window onto it. When the G9 comes back the windows stay where they were shoved — bunched at the seam.

The failure in the xev log, in order — EDID deleted, output disconnected, CRTC torn down to nothing:

RRNotify event, serial 18, synthetic NO, window 0x3dc,
    subtype XRROutputPropertyChangeNotifyEvent
    output DisplayPort-1, property EDID, timestamp 1311448446, state Delete

RRNotify event, serial 18, synthetic NO, window 0x3dc,
    subtype XRROutputChangeNotifyEvent
    output DisplayPort-1, crtc 79, mode 5120x1440 (5120x1440)
    rotation RR_Rotate_0
    connection RR_Disconnected, subpixel_order SubPixelUnknown

RRNotify event, serial 30, synthetic NO, window 0x3dc,
    subtype XRRCrtcChangeNotifyEvent
    crtc 79, mode None, rotation RR_Rotate_0
    x 0, y 0, width 0, height 0

Windows 11 hides this by remembering window placement across display changes. KWin on X11 does not.

Diagnose It

# Make a log directory:

mkdir -p ~/seamlog

# Log every RandR event, then walk away:

nohup xev -root -event randr > ~/seamlog/randr.log 2>&1 &

xev is in xorg-xev. Exit 127 on the job means it is not installed.

# Count events after waking the screens:

wc -l ~/seamlog/randr.log

One line is xev's own header — nothing happened. The failing run produced 141 lines.

# Look for the disconnect:

grep -c RR_Disconnected ~/seamlog/randr.log

Bisect lock versus blank

By default both happen at once — Power Management → Display and Brightness → Turn off screen is set to When locked: Immediately. Separate them:

  1. Lock, no blank. Set Turn off screen and When locked to Never. Let it

lock, wait, unlock.

  1. Blank, no lock. Turn off auto-lock in Screen Locking, restore the

screen timer, let it go dark on its own.

Result here: locked with screens lit — zero RandR events, windows untouched. Blank without the greeter — 141 events, windows at the seam. The blank is the trigger, not the lock screen.

The Fix

Force the connector enabled so DRM ignores the G9 dropping its link, and pin its EDID so the identity never gets deleted.

# Find which DRM connector is the G9:

for f in /sys/class/drm/card1-DP-*/modes; do echo "== $f"; head -3 "$f"; done

The one leading with 5120×1440 is the G9:

== /sys/class/drm/card1-DP-1/modes
1920x1080
1920x1080
1920x1080
== /sys/class/drm/card1-DP-2/modes
5120x1440
3840x1080
3840x2160

# Make the firmware directory:

sudo mkdir -p /usr/lib/firmware/edid

# Dump the G9's EDID while the panel is awake:

sudo cp /sys/class/drm/card1-DP-2/edid /usr/lib/firmware/edid/g9.bin

# Check the dump is real:

edid-decode /usr/lib/firmware/edid/g9.bin | head -20

Expect 384 bytes, header 00 ff ff ff ff ff ff 00, and the name block decoding to Odyssey G93SC. Zero bytes means the read failed — the panel was asleep.

# Add the EDID to the initramfs — in /etc/mkinitcpio.conf:

mkinitcpio.conf
FILES=(/usr/lib/firmware/edid/g9.bin)

If FILES already has entries, add this one inside the existing parentheses.

# Rebuild the initramfs:

sudo mkinitcpio -P

# Confirm the EDID made it in:

sudo lsinitcpio /boot/initramfs-linux-cachyos.img | grep -i edid
usr/lib/firmware/edid/
usr/lib/firmware/edid/g9.bin

# Back up the boot entry:

sudo cp /boot/loader/entries/linux-cachyos.conf /boot/loader/entries/linux-cachyos.conf.bak

# Append the parameters to the options line:

sudo sh -c "sed -i '/^options /s|\$| video=DP-2:e drm.edid_firmware=DP-2:edid/g9.bin|' /boot/loader/entries/linux-cachyos.conf"

# Verify — exactly one options line, params at the end:

sudo grep ^options /boot/loader/entries/linux-cachyos.conf
options root=UUID=82b232c2-b345-41a9-9e9b-51b676c85bbc rw zswap.enabled=0 nowatchdog quiet splash video=DP-2:e drm.edid_firmware=DP-2:edid/g9.bin

The LTS entry is deliberately left unpatched — it is never booted except as a rescue.

# After reboot, confirm the params are live:

cat /proc/cmdline

# Confirm the layout came back intact:

xrandr --listmonitors
Monitors: 2
 0: +*DisplayPort-1 5120/1190x1440/340+0+0  DisplayPort-1
 1: +DisplayPort-0 1920/509x1080/286+5120+206  DisplayPort-0

# Test — start the logger, leave it dark 15+ minutes, wake it:

wc -l ~/seamlog/randr.log

One line is a pass. Give it a few days before calling it fixed — the failure was never on demand.

The gotchas that will waste your afternoon

# 1. xrandr and the kernel name the connectors differently.

xrandr's DisplayPort-1 is the kernel's card1-DP-2. Off by one and in a different format. Never assume the mapping — read the modes files. Pinning the G9's EDID onto the 1080p connector is a mess to unwind.

# 2. sudo does not expand your globs.

[josephk@HPZ4G4-LAB ~]$ sudo grep ^options /boot/loader/entries/*.conf
grep: /boot/loader/entries/*.conf: No such file or directory

/boot/loader/entries is not readable as your user, so the shell cannot expand *.conf before sudo runs and grep gets the literal string. A sudo sed -i … *.conf fails the same way — silently leaving the entry unedited. Name the file, or wrap the whole command in sudo sh -c “…”.

# 3. mkinitcpio does not pick up the EDID on its own.

The build output never mentions it and reports success. Without the FILES= line, drm.edid_firmware silently does nothing. Always check with lsinitcpio.

# 4. Quick tests lie.

xset dpms force off and a mouse wiggle never reproduced it, and neither did a fast Meta+L. The G9 needs minutes of darkness before deep sleep kicks in. Anything shorter is a false pass.

# 5. grep for RR_Disconnected, not disconnected.

grep -c disconnected on a failing log returned 0. xev writes the constant name. That one nearly sent the whole diagnosis sideways.

Red Herrings

RememberWindowPositions (KWin script in ~/.local/share/kwin/scripts/rememberwindowpositions) logged loudly during every unlock — including capturing kscreenlocker_greet — but disabling it changed nothing. Loud logs are not the culprit. Prove it with a clean disable-and-test before tuning it.

If it is re-enabled:

  • multiMonitorType=1 is “Last position — even if windows end up

off-screen”, a single-monitor setting. Use 0, last monitor the window

  was on.
* Add ''kscreenlocker_greet'' to its blacklist.

The 5-second xrandr poll showed 369 identical samples during a failure. Transient disconnects slip between samples. Use xev — it catches every event.

Recovery

# G9 wrong or black after reboot — boot once without the params:

e

Press it on the entry at the systemd-boot menu, delete the two parameters, Enter. One-shot, nothing saved.

# Roll back the boot entry:

sudo cp /boot/loader/entries/linux-cachyos.conf.bak /boot/loader/entries/linux-cachyos.conf

# G9 at the wrong resolution — drop the EDID half only:

sudo sh -c "sed -i 's| drm.edid_firmware=DP-2:edid/g9.bin||' /boot/loader/entries/linux-cachyos.conf"

The G9's EDID is three blocks. drm.edid_firmware occasionally mishandles multi-block EDIDs. video=DP-2:e alone may still hold the connector.

Troubleshooting

Symptom Cause Fix
Windows at x=5120 after the screens blank G9 deep sleep drops the DP link video=DP-2:e plus EDID firmware
Fine after a quick lock, bad after long idle deep sleep needs minutes of dark test with 15+ minutes blank
grep disconnected finds nothing xev writes RR_Disconnected grep RR_Disconnected
sudo grep … *.conf: No such file glob expanded as your user name the file or sudo sh -c
lsinitcpio shows no edid file not in FILES= edit /etc/mkinitcpio.conf, mkinitcpio -P
G9 wrong resolution after reboot multi-block EDID via firmware drop drm.edid_firmware, keep video=DP-2:e
Problem back after a kernel update entry rewritten or EDID dropped check /proc/cmdline and lsinitcpio
Rescue boot scatters windows LTS entry unpatched expected
xev job shows Exit 127 xorg-xev not installed sudo pacman -S xorg-xev

Which Fix Should I Use?

video= + EDID When locked: Never Window Rules
Panel still sleeps yes no yes
Stops the disconnect yes yes no
Safe for the OLED yes no — burn-in yes
Covers every window yes yes only forced apps
Setup effort one-time trivial per app

Rule of thumb: pin the connector in the kernel — never leave the OLED lit to dodge it.

kde_windows_issue.txt · Last modified: by admin