A tiny Windows utility that "nudges" a display mode (usually just the refresh rate) x seconds after you log in. This gently retriggers the Windows/driver handshake so DSC/link training on stubborn 4K panels actually settles at the mode you want.
Why this exists: On my Radeon 7900 rig driving three 4K Samsung Odyssey panels at 120 Hz, one or more displays often wake at 60 Hz (or not at all) until you manually re-apply the mode in Windows Display Settings. I tried EDID/CRU edits, custom timings, driver swaps, and premium cables, but all of that was overkill. A simple post-logon modeset nudge makes the displays stick where they’re supposed to.
-
GPU: XFX Radeon RX 7900 XTX
-
Displays: three 4K Samsung Odyssey G80SD's (similar behavior seen with mixed 4k/2k displays)
-
Links: 4x DisplayPort 1.4 (DSC capable)
With 3×4K via DP 1.4, the system relies on Display Stream Compression (DSC). Occasionally Windows finishes logon before the driver ↔ monitor DSC/link training settles on one path. The result is a valid but incorrect mode (60hz). A tiny, intentional modeset a few seconds later re‑kicks negotiation and the panel locks to 120 Hz.
TL;DR: It’s not bandwidth you’re missing; it’s timing.
-
Finds the target display (by index, .\DISPLAYx, or name substring like G80SD).
-
Waits an optional delay (e.g., 10–30 s) so the desktop and driver settle after login.
-
Reads the current DEVMODE with EnumDisplaySettingsEx.
-
Builds a target DEVMODE—commonly identical to current but with an explicit dmDisplayFrequency (the “nudge”).
-
Tests the mode via ChangeDisplaySettingsEx(..., CDS_TEST).
-
Applies it with CDS_UPDATEREGISTRY | CDS_FULLSCREEN.
-
Verifies the new mode; if unchanged, performs a gentle CDS_RESET and re‑verifies.
No device disable/enable, no EDID patching, no CRU gymnastics—just a benign, reversible nudge.
** Typical: nudge a Samsung to 120 Hz ~15s after login**
DisplayNudger -display G80SD -hz 120 -delay 15
** Target by display index**
DisplayNudger -d 2 -hz 120 -delay 20
** List supported modes for a display**
DisplayNudger -d 2 -list
Option Alias Description
--------------------------------------------------------------
-display -d Target display by 1‑based index, \.\DISPLAYx, or name substring (G80SD).
-width -w Width in pixels (optional; omit to keep current).
-height -h Height in pixels (optional).
-hz -r Refresh rate to re‑apply (e.g., 120).
-bpp -bits Bits per pixel (usually leave unset).
-wait, -delay Wait N seconds before applying (default 0).
-list, --list List the modes the driver reports for the target.
-help, --help, -? Show help.
Tip: If your resolution is already correct, only pass
-hz. The tool will clone the current mode and change just the refresh.
- Windows 10/11 x64
- .NET 8 SDK
From repository root
dotnet publish -c Release -r win-x64 /p:PublishSingleFile=true /p:PublishTrimmed=true
Output is a single exe under bin/Release/net8.0/win-x64/publish/.
Task Scheduler (most reliable)
- Open Task Scheduler → Create Task.
- Triggers: At log on → Delay task 30 seconds (tune between 10–45s; longer if wake‑from‑sleep is flaky).
- Actions: Start a program → point to DisplayNudger.exe (place in your profile directory)
- Arguments: -display G80SD -hz 120 -delay 10 (yes, delay in both scheduler and app is fine; the app delay can be your “inner” buffer).
Place in Startup folder (simpler)
Create a shortcut in shell:startup to DisplayNudger.exe with your preferred arguments.
Multimonitor changes Create a batch/powershell file to call the Nudger x number of times
Program → Options.Parse(args)
→ DisplayDevice.EnumerateAll()
→ SelectTarget(selector)
→ if (--list) { EnumerateModes(); exit 0; }
→ if (delay) await Task.Delay(delay)
→ current = EnumDisplaySettingsEx(CURRENT)
→ target = Clone(current).With(overrides: w/h/hz/bpp)
→ ChangeDisplaySettingsEx(TEST)
↳ if fail → log & exit 1
→ ChangeDisplaySettingsEx(APPLY | UPDATEREGISTRY)
→ after = EnumDisplaySettingsEx(CURRENT)
↳ if unchanged → ChangeDisplaySettingsEx(RESET) → re‑read
→ exit 0/1
Mode test failed: Increase -delay (try 20–45 s) and/or confirm the driver lists the mode via -list.
Panel still at 60 Hz: Ensure DP cables are HBR3/DP1.4 rated and the monitor OSD allows the target refresh.
Random monitor order: If -d 2 points to a different panel after reboots, prefer a name substring selector (-display G80SD).
Mixed models: If you run G80SD + G85SD, use name substrings to avoid the wrong target.
Uses the legacy GDI path intentionally for broad driver compatibility.
Writes to standard user display settings via CDS_UPDATEREGISTRY; no registry hacking beyond that.
Doesn’t disable/enable devices or alter EDIDs. If you’ve done EDID/CRU experiments, revert them; this tool assumes stock EDIDs.
Future work: surface QueryDisplayConfig details and allow targeting by path (adapter ↔ target) for power users.
MIT
https://www.xfxforce.com/shop/xfx-speedster-merc-310-7900xtx-black-edition