This is an old revision of the document!
Table of Contents
Windows Piling at the Monitor Seam — KDE X11, amdgpu, Odyssey G9
Fix for every window on HPZ4G4-LAB 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:
- Lock, no blank. Set Turn off screen and When locked to Never. Let it
lock, wait, unlock.
- 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=1is “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.
