Skip to content

WKWebView reports devicePixelRatio=1 on macOS Retina displays (custom URL scheme) #5111

@wblech

Description

@wblech

Description

In Wails v2.12.0 on macOS, window.devicePixelRatio returns 1 inside the WKWebView on Retina displays, where it should return 2. This causes all canvas-based rendering (, xterm.js WebGL/Canvas, chart libraries) to render at half resolution — macOS upscales the 1x content to 2x, producing visibly blurry output.

The root cause is that WKWebView does not automatically propagate the display's backing scale factor to JavaScript's devicePixelRatio when content is loaded via a custom URL scheme (wails://). This affects both wails dev and wails build.

This results in visibly blurry text and graphics in any app that uses <canvas> — terminal emulators (xterm.js), chart libraries, drawing tools, games, and code editors all render at half the expected resolution. Text on canvas is particularly affected, appearing soft and hard to read compared to native DOM text.

window.matchMedia('(-webkit-min-device-pixel-ratio: 2)') also returns false.

To Reproduce

  1. Create a new Wails project on a Mac with a Retina display:
  wails init -n dpr-test -t vanilla
  cd dpr-test    
  1. Edit frontend/index.html — add this inline script before the module script:
  <div id="dpr-info" style="position:fixed;top:10px;left:10px;background:#000;color:#0f0;padding:10px;font-family:mono
  space;font-size:16px;z-index:9999;border-radius:4px;"></div>                                                        
  <script>
      var info = 'devicePixelRatio: ' + window.devicePixelRatio + '\n'                                                
          + 'matchMedia 2x: ' + window.matchMedia('(-webkit-min-device-pixel-ratio: 2)').matches + '\n'               
          + 'screen: ' + screen.width + 'x' + screen.height;                                                          
      document.getElementById('dpr-info').innerText = info;                                                           
  </script>              
  1. Build and open:
  wails build
  open build/bin/dpr-test.app          
  1. The overlay shows devicePixelRatio: 1 (also reproducible with wails dev)

Expected behaviour

window.devicePixelRatio should return 2 on Retina displays (matching NSScreen.mainScreen.backingScaleFactor).
Canvas-based content should render at native resolution.

Screenshots

Before Fix bug:

Image

After fix:

Image

Another example with blur:

Image

Without blur after fix:

Image

Attempted Fixes

  • NSHighResolutionCapable in Info.plist: Already set to true — does not affect WKWebView's DPR reporting.
  • JavaScript Object.defineProperty override of devicePixelRatio: Forces canvas to render at 2x, but the WKWebView compositor still operates at 1x internally. Creates glyph rendering artifacts at small font sizes due to sub-pixel alignment mismatch.
  • wantsLayer = YES + layer.contentsScale = backingScaleFactor on the WKWebView: Does not affect window.devicePixelRatiocontentsScale controls the CALayer rendering, not WebKit's internal device scale factor.
  • _setOverrideDeviceScaleFactor: SPI on WKWebView (working fix): Sets WebPageProxy::customDeviceScaleFactor, which is the authoritative source for window.devicePixelRatio in JavaScript. This SPI is stable since macOS 10.11 and used by Electron, Playwright, and WebKit's own test infrastructure. I have a working patch and can submit a PR.

System Details

Wails Doctor          
                                

                                                                                                                      
# Wails
Version | v2.11.0


# System
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
| OS           | MacOS                                                                                                                   |
| Version      | 15.7.4                                                                                                                  |
| ID           | 24G517                                                                                                                  |
| Branding     |                                                                                                                         |
| Go Version   | go1.25.6                                                                                                                |
| Platform     | darwin                                                                                                                  |
| Architecture | arm64                                                                                                                   |
| CPU 1        | Apple M3                                                                                                                |
| CPU 2        | Apple M3                                                                                                                |
| GPU          | Chipset Model: Apple M3 Type: GPU Bus: Built-In Total Number of Cores: 10 Vendor: Apple (0x106b) Metal Support: Metal 3 |
| Memory       | 24GB                                                                                                                    |
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

# Dependencies
┌────────────────────────────────────────────────────────────────┐
| Dependency                | Package Name | Status    | Version |
| Xcode command line tools  | N/A          | Installed | 2410    |
| Nodejs                    | N/A          | Installed | 22.18.0 |
| npm                       | N/A          | Installed | 10.9.3  |
| *Xcode                    | N/A          | Available |         |
| *upx                      | N/A          | Available |         |
| *nsis                     | N/A          | Available |         |
|                                                                |
└─────────────────── * - Optional Dependency ────────────────────┘

# Diagnosis
Optional package(s) installation details: 
  - Xcode: Available at https://apps.apple.com/us/app/xcode/id497799835
  - upx : Available at https://upx.github.io/
  - nsis : More info at https://wails.io/docs/guides/windows-installer/

Additional context

Affects any Wails v2 app using <canvas> on macOS Retina: terminals (xterm.js), charts, games, editors, drawing apps.

  • The issue is specific to the custom wails:// URL scheme. WKWebView correctly reports DPR when loading content via http:// or https://.
  • The fix is in v2/internal/frontend/desktop/darwin/WailsContext.m, after the WKWebView is created.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions