Thanks to visit codestin.com
Credit goes to github.com

Skip to content

iFredOS/Playnite-DPIFix

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Playnite DPI Fix

Fixes blank, clipped, and offset webviews in Playnite on 4K displays at any non-100% DPI scaling (175%, 200%, 225%, 250%, 300% — Windows' recommended default for 4K — and beyond).

One-click PowerShell script that builds a patched Playnite.dll from upstream source and installs it over your existing Playnite install. Auto-detects your installed Playnite version and builds against the matching git tag, so it Just Works across Playnite updates.

The problem

On a 4K display, Windows recommends 300% scaling out of the box, and most users keep it there or pick something in the 175–250% range for a little extra screen real estate. At any of those non-100% factors, most of Playnite's add-on webview windows render incorrectly:

  • Xbox login — webview is blank, can't sign in
  • Battle.net login — clipped/offset
  • Epic Games OAuth — clipped/offset
  • GOG authentication — clipped/offset
  • Steam News, achievement plugins (SuccessStory, etc.) — content cut off
  • Effectively every plugin that uses the embedded browser

Root cause: a CefSharp.Wpf offscreen-rendering bug at non-integer DPI factors (see cefsharp/CefSharp#2856). Playnite passes the raw system DPI scale to Chromium's offscreen surface, which then either computes wrong coordinates (cropping/offset) or produces a 0×0 surface (blank).

The fix

This script:

  1. Auto-detects your installed Playnite version (reads Playnite.dll's FileVersion).
  2. Clones Playnite source at the matching git tag.
  3. Patches CefTools.cs to add force-device-scale-factor=1 to the Cef command line.
  4. Patches WebView.cs to pin per-browser DpiScaleFactor = 1.0f after browser init (and call NotifyScreenInfoChanged() to repaint at the new scale).
  5. Builds a patched Playnite.dll (Release, x86, .NET Framework 4.6.2).
  6. Backs up the original DLL and installs the patched one.

After patching, Chromium and the WPF host stay on the same 1:1 scale, eliminating the offset/clip. Webviews now render correctly and are fully clickable.

Trade-off (read this before running)

What you get What you don't
Webviews work Webviews are slightly blurry (sub-pixel softness)
Logins succeed Sharp text on webview content is gone
Plugins render Playnite's main UI is unaffected (still sharp)

The blurriness is unavoidable in this approach — Chromium renders the webview at 1× scale and the WPF host upscales it to fit your DPI. A sharp + functional combo would require patching CefSharp.Wpf itself; not possible from inside Playnite.

If functional-but-soft is acceptable, this script gets you there in one click. If you need pixel-sharp webviews at non-100% DPI, this can't deliver that today.

Tested on

  • Windows 11 Pro (build 10.0.26200)
  • 4K display at 225% scaling (the bug exists at every non-100% factor; 225% just happens to be where this was developed)
  • Playnite v10.53.0.18801
  • Visual Studio Build Tools 2022 with .NET desktop workload

Auto-detection should work for any Playnite minor release that has a matching upstream git tag.

Requirements

  • Windows 10 or 11
  • Administrator (the script auto-elevates via a UAC prompt)
  • ~5 GB free disk space (for Visual Studio Build Tools 2022, if not already installed)
  • Internet connection (clones Playnite source + downloads ~300 MB of NuGet packages on first run)

The script will install for you, if missing:

  • Git (via winget)
  • Visual Studio Build Tools 2022 with the .NET desktop workload + .NET 4.6.2 targeting pack
  • NuGet CLI

Usage

Double-click

Double-click Run-DPIFix.cmd in this folder.

It launches PowerShell with the right execution policy; the script then self-elevates with a single UAC prompt.

From a terminal

.\Build-PlayniteDPIFix.ps1

With options:

# Pin to a specific Playnite tag (skip auto-detection)
.\Build-PlayniteDPIFix.ps1 -PlayniteTag 10.54

# Build against master (latest dev — useful if your installed Playnite is newer than any published tag)
.\Build-PlayniteDPIFix.ps1 -PlayniteTag master

# Build only — don't auto-install over your Playnite install
.\Build-PlayniteDPIFix.ps1 -SkipAutoInstall

# Force a clean re-clone + re-patch
.\Build-PlayniteDPIFix.ps1 -Force

# Delete the temp build cache after a successful build (frees ~300 MB,
# but next run will be 15-20 min again instead of 3-5)
.\Build-PlayniteDPIFix.ps1 -CleanupAfter

Timing

  • First run: 15–20 min — most of that is VS Build Tools install (one-time) + NuGet restore on the CefSharp packages
  • Re-runs: 3–5 min

What it does to your system

  • Backs up your original Playnite.dll to Playnite.dll.backup next to it (only on first run; the backup is preserved across re-runs so the original is never lost).
  • Replaces Playnite.dll with the patched build.
  • Drops a copy of the patched DLL plus a README.txt summary into ~/Desktop/PlayniteDPIFix_Output/.
  • Leaves a build cache at %LOCALAPPDATA%\Temp\PlayniteDPIFix\ (~300 MB: cloned Playnite source + NuGet packages). This is kept on purpose — re-runs are 3–5 min instead of 15–20 because the cache is reused. You can:
    • Delete that folder manually any time you want the disk space back.
    • Or pass -CleanupAfter so the script deletes it for you after a successful build.

Nothing else is modified. Playnite's settings, library, plugins, themes, etc. are untouched.

Reverting

  1. Close Playnite.
  2. Open your Playnite install folder (the script prints this path; usually %LOCALAPPDATA%\Playnite).
  3. Delete Playnite.dll.
  4. Rename Playnite.dll.backupPlaynite.dll.
  5. Launch Playnite.

Auto-detection in detail

The script:

  1. Locates your Playnite install (running process → registry uninstall keys → common paths → Start Menu shortcut).
  2. Reads Playnite.dll's FileVersion (e.g. 10.53.0.18801).
  3. Takes the <major>.<minor> prefix (10.53).
  4. Verifies the tag exists upstream via git ls-remote --tags.
  5. Clones — or fetches + hard-resets — the local working tree onto that tag.

This matters because Playnite's binary contract changes between minor releases. A master-built DLL on a 10.53 install crashes with MissingMethodException on the Add-ons settings page. Building from the matching tag guarantees method signatures line up.

If the tag isn't published yet (Playnite released, upstream maintainer hasn't tagged), the script falls back to master and warns. If the build then crashes with MissingMethodException, wait a day or two for the tag, then re-run.

When Playnite updates itself

Playnite's auto-update overwrites Playnite.dll with the new official version, removing the patch. To restore:

Run Run-DPIFix.cmd again.

Auto-detection picks up the new version and rebuilds. If the new version's tag isn't published yet, see the previous section.

Troubleshooting

MissingMethodException on the Add-ons settings page after running the script. The patched DLL was built against the wrong Playnite version. Most likely cause: auto-detection fell back to master because the upstream tag for your installed version isn't published yet. Wait for the upstream tag, then re-run with -Force.

"VS Build Tools install failed." The standalone .NET 4.6.2 dev pack on Microsoft's site serves a 16-bit DOS stub on modern Windows and won't install. The script works around this by installing the targeting pack as a VS Build Tools 2022 component instead. If even that fails, install VS Build Tools 2022 manually from visualstudio.microsoft.com with the ".NET desktop build tools" workload + ".NET Framework 4.6.2 targeting pack" component, then re-run.

"Git clone failed." Either a network/firewall issue or https://github.com/JosefNemec/Playnite.git is temporarily unreachable. Test with git clone https://github.com/JosefNemec/Playnite.git in a separate terminal.

Playnite won't start after install / crashes immediately. The build produced a binary-incompatible DLL. Revert (see Reverting above) and report the issue with ~/AppData/Local/Temp/PlayniteDPIFix/build.log attached.

How the patch is built

Two source-level edits, both idempotent (anchored regex; safe to re-run):

  1. source/Playnite/Plugins/CefTools.cs — Adds force-device-scale-factor=1 and high-dpi-support=1 to CefSettings.CefCommandLineArgs immediately before Cef.Initialize(...).
  2. source/Playnite/WebView/WebView.cs — Subscribes to Browser.IsBrowserInitializedChanged, sets DpiScaleFactor = 1.0f after init fires (pre-init set produces a 0×0 offscreen surface — blank render), then calls NotifyScreenInfoChanged() to force a repaint at the new scale.

Build target: .NET Framework 4.6.2, Release|x86. Bumping to 4.7+ is not safe — it moves System.ValueTuple into mscorlib, which breaks the binary contract with the rest of Playnite's assemblies (which were built against the System.ValueTuple NuGet package).

License

MIT — see LICENSE.

This project does not redistribute Playnite binaries. It clones Playnite source at build time, patches it locally on your machine, and builds a single DLL for your personal use. Playnite itself is licensed separately by JosefNemec — see the Playnite repository for its license terms.

Acknowledgements

About

Fixes Playnite webview clipping/blanking on 4K displays at non-standard DPI scaling (e.g. 225%) by building a patched Playnite.dll from upstream source. Auto-detects the installed Playnite version.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors