5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-04 07:29:56 +08:00
wails/v3/examples/screen/screens.go
Mohamed Gharib efe0c8d534
[v3-Windows] New DIP system for Enhanced High DPI Monitor Support (#3665)
* [v3-Windows] New DIP system for Enhanced High DPI Monitor Support

* Update changelog

* Remove asset middleware

* Remove SetThreadDpiAwarenessContext()

* Fix macOS build.

* Fill missing screens fields (linux, darwin)

* Skip DPI transformation on unsupported platforms

* Simplify distanceFromRectSquared()

* Update v3/pkg/application/screenmanager.go

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2024-09-22 08:38:30 +10:00

130 lines
3.5 KiB
Go

package main
import (
"runtime"
"github.com/wailsapp/wails/v3/pkg/application"
)
type ScreenService struct {
screenManager application.ScreenManager
isExampleLayout bool
}
func (s *ScreenService) GetSystemScreens() []*application.Screen {
s.isExampleLayout = false
screens, _ := application.Get().GetScreens()
return screens
}
func (s *ScreenService) ProcessExampleScreens(rawScreens []interface{}) []*application.Screen {
s.isExampleLayout = true
parseRect := func(m map[string]interface{}) application.Rect {
return application.Rect{
X: int(m["X"].(float64)),
Y: int(m["Y"].(float64)),
Width: int(m["Width"].(float64)),
Height: int(m["Height"].(float64)),
}
}
screens := []*application.Screen{}
for _, s := range rawScreens {
s := s.(map[string]interface{})
bounds := parseRect(s["Bounds"].(map[string]interface{}))
screens = append(screens, &application.Screen{
ID: s["ID"].(string),
Name: s["Name"].(string),
X: bounds.X,
Y: bounds.Y,
Size: application.Size{Width: bounds.Width, Height: bounds.Height},
Bounds: bounds,
PhysicalBounds: parseRect(s["PhysicalBounds"].(map[string]interface{})),
WorkArea: parseRect(s["WorkArea"].(map[string]interface{})),
PhysicalWorkArea: parseRect(s["PhysicalWorkArea"].(map[string]interface{})),
IsPrimary: s["IsPrimary"].(bool),
ScaleFactor: float32(s["ScaleFactor"].(float64)),
Rotation: 0,
})
}
s.screenManager.LayoutScreens(screens)
return s.screenManager.Screens()
}
func (s *ScreenService) transformPoint(point application.Point, toDIP bool) application.Point {
if s.isExampleLayout {
if toDIP {
return s.screenManager.PhysicalToDipPoint(point)
} else {
return s.screenManager.DipToPhysicalPoint(point)
}
} else {
// =======================
// TODO: remove this block when DPI is implemented in Linux & Mac
if runtime.GOOS != "windows" {
println("DPI not implemented yet!")
return point
}
// =======================
if toDIP {
return application.PhysicalToDipPoint(point)
} else {
return application.DipToPhysicalPoint(point)
}
}
}
func (s *ScreenService) TransformPoint(point map[string]interface{}, toDIP bool) (points [2]application.Point) {
pt := application.Point{
X: int(point["X"].(float64)),
Y: int(point["Y"].(float64)),
}
ptTransformed := s.transformPoint(pt, toDIP)
ptDblTransformed := s.transformPoint(ptTransformed, !toDIP)
// double-transform multiple times to catch any double-rounding issues
for i := 0; i < 10; i++ {
ptTransformed = s.transformPoint(ptDblTransformed, toDIP)
ptDblTransformed = s.transformPoint(ptTransformed, !toDIP)
}
points[0] = ptTransformed
points[1] = ptDblTransformed
return points
}
func (s *ScreenService) TransformRect(rect map[string]interface{}, toDIP bool) application.Rect {
r := application.Rect{
X: int(rect["X"].(float64)),
Y: int(rect["Y"].(float64)),
Width: int(rect["Width"].(float64)),
Height: int(rect["Height"].(float64)),
}
if s.isExampleLayout {
if toDIP {
return s.screenManager.PhysicalToDipRect(r)
} else {
return s.screenManager.DipToPhysicalRect(r)
}
} else {
// =======================
// TODO: remove this block when DPI is implemented in Linux & Mac
if runtime.GOOS != "windows" {
println("DPI not implemented yet!")
return r
}
// =======================
if toDIP {
return application.PhysicalToDipRect(r)
} else {
return application.DipToPhysicalRect(r)
}
}
}