Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions v3/UNRELEASED_CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ After processing, the content will be moved to the main changelog and this file

## Fixed
<!-- Bug fixes -->
- Fix SetProcessDpiAwarenessContext "Access is denied" error when DPI awareness is already set via application manifest (#4803)

## Deprecated
<!-- Soon-to-be removed features -->
Expand Down
12 changes: 12 additions & 0 deletions v3/pkg/application/application_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,18 @@ func setupDPIAwareness() error {
// https://learn.microsoft.com/en-us/windows/win32/hidpi/setting-the-default-dpi-awareness-for-a-process
// https://learn.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows

// Check if DPI awareness has already been set (e.g., via application manifest).
// Windows only allows setting DPI awareness once per process - either via manifest
// or API, not both. If already set, skip the API call to avoid "Access is denied" errors.
// See: https://github.com/wailsapp/wails/issues/4803
if w32.HasGetProcessDpiAwarenessFunc() {
awareness, err := w32.GetProcessDpiAwareness()
if err == nil && awareness != w32.PROCESS_DPI_UNAWARE {
// DPI awareness already set (likely via manifest), skip API call
return nil
}
}

if w32.HasSetProcessDpiAwarenessContextFunc() {
// This is most recent version with the best results
// supported beginning with Windows 10, version 1703
Expand Down
17 changes: 17 additions & 0 deletions v3/pkg/w32/shcore.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,26 @@ var (
modshcore = syscall.NewLazyDLL("shcore.dll")

procGetDpiForMonitor = modshcore.NewProc("GetDpiForMonitor")
procGetProcessDpiAwareness = modshcore.NewProc("GetProcessDpiAwareness")
procSetProcessDpiAwareness = modshcore.NewProc("SetProcessDpiAwareness")
)

func HasGetProcessDpiAwarenessFunc() bool {
err := procGetProcessDpiAwareness.Find()
return err == nil
}

// GetProcessDpiAwareness retrieves the DPI awareness of the current process.
// Returns one of: PROCESS_DPI_UNAWARE, PROCESS_SYSTEM_DPI_AWARE, or PROCESS_PER_MONITOR_DPI_AWARE.
func GetProcessDpiAwareness() (uint, error) {
var awareness uint
status, _, err := procGetProcessDpiAwareness.Call(0, uintptr(unsafe.Pointer(&awareness)))
if status != S_OK {
return 0, fmt.Errorf("GetProcessDpiAwareness failed: %v", err)
}
return awareness, nil
}

func HasSetProcessDpiAwarenessFunc() bool {
err := procSetProcessDpiAwareness.Find()
return err == nil
Expand Down
Loading