mirror of
https://github.com/wailsapp/wails.git
synced 2026-03-14 22:55:48 +01:00
[v3 windows] Add HiDPI awareness
This commit is contained in:
parent
fc3725d3f4
commit
6f246eed4a
4 changed files with 55 additions and 10 deletions
|
|
@ -1,7 +1,6 @@
|
|||
package application
|
||||
|
||||
import (
|
||||
"github.com/samber/lo"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
|
|
@ -9,6 +8,8 @@ import (
|
|||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/samber/lo"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/assetserver"
|
||||
"github.com/wailsapp/wails/v2/pkg/assetserver/webview"
|
||||
assetserveroptions "github.com/wailsapp/wails/v2/pkg/options/assetserver"
|
||||
|
|
@ -16,6 +17,7 @@ import (
|
|||
wailsruntime "github.com/wailsapp/wails/v3/internal/runtime"
|
||||
"github.com/wailsapp/wails/v3/pkg/events"
|
||||
"github.com/wailsapp/wails/v3/pkg/logger"
|
||||
"github.com/wailsapp/wails/v3/pkg/w32"
|
||||
)
|
||||
|
||||
var globalApplication *App
|
||||
|
|
@ -33,6 +35,12 @@ func New(appOptions Options) *App {
|
|||
return globalApplication
|
||||
}
|
||||
|
||||
err := w32.SetProcessDPIAware()
|
||||
if err != nil {
|
||||
println("Fatal error in application initialisation: ", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
mergeApplicationDefaults(&appOptions)
|
||||
|
||||
result := &App{
|
||||
|
|
|
|||
|
|
@ -36,9 +36,9 @@ func (w *windowsWebviewWindow) setTitle(title string) {
|
|||
}
|
||||
|
||||
func (w *windowsWebviewWindow) setSize(width, height int) {
|
||||
x, y := w.position()
|
||||
// TODO: Take scaling/DPI into consideration
|
||||
w32.MoveWindow(w.hwnd, x, y, width, height, true)
|
||||
rect := w32.GetWindowRect(w.hwnd)
|
||||
width, height = w.scaleWithWindowDPI(width, height)
|
||||
w32.MoveWindow(w.hwnd, int(rect.Left), int(rect.Top), width, height, true)
|
||||
}
|
||||
|
||||
func (w *windowsWebviewWindow) setAlwaysOnTop(alwaysOnTop bool) {
|
||||
|
|
@ -206,7 +206,10 @@ func (w *windowsWebviewWindow) enableSizeConstraints() {
|
|||
|
||||
func (w *windowsWebviewWindow) size() (int, int) {
|
||||
rect := w32.GetWindowRect(w.hwnd)
|
||||
return int(rect.Right - rect.Left), int(rect.Bottom - rect.Top)
|
||||
width := int(rect.Right - rect.Left)
|
||||
height := int(rect.Bottom - rect.Top)
|
||||
width, height = w.scaleToDefaultDPI(width, height)
|
||||
return width, height
|
||||
}
|
||||
|
||||
func (w *windowsWebviewWindow) setForeground() {
|
||||
|
|
@ -218,18 +221,19 @@ func (w *windowsWebviewWindow) update() {
|
|||
}
|
||||
|
||||
func (w *windowsWebviewWindow) width() int {
|
||||
rect := w32.GetWindowRect(w.hwnd)
|
||||
return int(rect.Right - rect.Left)
|
||||
width, _ := w.size()
|
||||
return width
|
||||
}
|
||||
|
||||
func (w *windowsWebviewWindow) height() int {
|
||||
rect := w32.GetWindowRect(w.hwnd)
|
||||
return int(rect.Bottom - rect.Top)
|
||||
_, height := w.size()
|
||||
return height
|
||||
}
|
||||
|
||||
func (w *windowsWebviewWindow) position() (int, int) {
|
||||
rect := w32.GetWindowRect(w.hwnd)
|
||||
return int(rect.Left), int(rect.Right)
|
||||
left, right := w.scaleToDefaultDPI(int(rect.Left), int(rect.Right))
|
||||
return left, right
|
||||
}
|
||||
|
||||
func (w *windowsWebviewWindow) destroy() {
|
||||
|
|
@ -293,6 +297,7 @@ func (w *windowsWebviewWindow) setHTML(html string) {
|
|||
}
|
||||
|
||||
func (w *windowsWebviewWindow) setPosition(x int, y int) {
|
||||
x, y = w.scaleWithWindowDPI(x, y)
|
||||
info := w32.GetMonitorInfoForWindow(w.hwnd)
|
||||
workRect := info.RcWork
|
||||
w32.SetWindowPos(w.hwnd, w32.HWND_TOP, int(workRect.Left)+x, int(workRect.Top)+y, 0, 0, w32.SWP_NOSIZE)
|
||||
|
|
@ -635,6 +640,16 @@ func (w *windowsWebviewWindow) WndProc(msg uint32, wparam, lparam uintptr) uintp
|
|||
if hasConstraints {
|
||||
return 0
|
||||
}
|
||||
case w32.WM_DPICHANGED:
|
||||
newWindowSize := (*w32.RECT)(unsafe.Pointer(lparam))
|
||||
w32.SetWindowPos(w.hwnd,
|
||||
uintptr(0),
|
||||
int(newWindowSize.Left),
|
||||
int(newWindowSize.Top),
|
||||
int(newWindowSize.Right-newWindowSize.Left),
|
||||
int(newWindowSize.Bottom-newWindowSize.Top),
|
||||
w32.SWP_NOZORDER|w32.SWP_NOACTIVATE)
|
||||
|
||||
}
|
||||
|
||||
if options := w.parent.options; options.Frameless {
|
||||
|
|
@ -743,10 +758,22 @@ func (w *windowsWebviewWindow) scaleWithWindowDPI(width, height int) (int, int)
|
|||
return scaledWidth, scaledHeight
|
||||
}
|
||||
|
||||
func (w *windowsWebviewWindow) scaleToDefaultDPI(width, height int) (int, int) {
|
||||
dpix, dpiy := w.DPI()
|
||||
scaledWidth := ScaleToDefaultDPI(width, dpix)
|
||||
scaledHeight := ScaleToDefaultDPI(height, dpiy)
|
||||
|
||||
return scaledWidth, scaledHeight
|
||||
}
|
||||
|
||||
func ScaleWithDPI(pixels int, dpi uint) int {
|
||||
return (pixels * int(dpi)) / 96
|
||||
}
|
||||
|
||||
func ScaleToDefaultDPI(pixels int, dpi uint) int {
|
||||
return (pixels * 96) / int(dpi)
|
||||
}
|
||||
|
||||
func NewIconFromResource(instance w32.HINSTANCE, resId uint16) (w32.HICON, error) {
|
||||
var err error
|
||||
var result w32.HICON
|
||||
|
|
|
|||
|
|
@ -552,6 +552,7 @@ const (
|
|||
WM_MOUSEHOVER = 0x2A1
|
||||
WM_MOUSELEAVE = 0x2A3
|
||||
WM_CLIPBOARDUPDATE = 0x031D
|
||||
WM_DPICHANGED = 0x02E0
|
||||
)
|
||||
|
||||
// WM_ACTIVATE
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ var (
|
|||
procGetMonitorInfo = moduser32.NewProc("GetMonitorInfoW")
|
||||
procGetDpiForSystem = moduser32.NewProc("GetDpiForSystem")
|
||||
procGetDpiForWindow = moduser32.NewProc("GetDpiForWindow")
|
||||
procSetProcessDPIAware = moduser32.NewProc("SetProcessDPIAware")
|
||||
procEnumDisplayMonitors = moduser32.NewProc("EnumDisplayMonitors")
|
||||
procEnumDisplaySettingsEx = moduser32.NewProc("EnumDisplaySettingsExW")
|
||||
procChangeDisplaySettingsEx = moduser32.NewProc("ChangeDisplaySettingsExW")
|
||||
|
|
@ -303,6 +304,14 @@ func GetDpiForWindow(hwnd HWND) UINT {
|
|||
return uint(dpi)
|
||||
}
|
||||
|
||||
func SetProcessDPIAware() error {
|
||||
status, r, err := procSetProcessDPIAware.Call()
|
||||
if status == 0 {
|
||||
return fmt.Errorf("SetProcessDPIAware failed %d: %v %v", status, r, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetForegroundWindow() HWND {
|
||||
ret, _, _ := procGetForegroundWindow.Call()
|
||||
return HWND(ret)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue