mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 13:02:04 +08:00
[v2] Introduce size and physical size of screens (#2856)
This commit is contained in:
parent
427fe7e8d3
commit
761efed84d
@ -18,6 +18,8 @@ typedef struct Screen {
|
|||||||
int isPrimary;
|
int isPrimary;
|
||||||
int height;
|
int height;
|
||||||
int width;
|
int width;
|
||||||
|
int pHeight;
|
||||||
|
int pWidth;
|
||||||
} Screen;
|
} Screen;
|
||||||
|
|
||||||
|
|
||||||
@ -48,14 +50,42 @@ Screen GetNthScreen(int nth, void *inctx){
|
|||||||
returnScreen.isPrimary = nth==0;
|
returnScreen.isPrimary = nth==0;
|
||||||
returnScreen.height = (int) nthScreen.frame.size.height;
|
returnScreen.height = (int) nthScreen.frame.size.height;
|
||||||
returnScreen.width = (int) nthScreen.frame.size.width;
|
returnScreen.width = (int) nthScreen.frame.size.width;
|
||||||
|
|
||||||
|
returnScreen.pWidth = 0;
|
||||||
|
returnScreen.pHeight = 0;
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/13859109/how-to-programmatically-determine-native-pixel-resolution-of-retina-macbook-pro
|
||||||
|
CGDirectDisplayID sid = ((NSNumber *)[nthScreen.deviceDescription
|
||||||
|
objectForKey:@"NSScreenNumber"]).unsignedIntegerValue;
|
||||||
|
|
||||||
|
CFArrayRef ms = CGDisplayCopyAllDisplayModes(sid, NULL);
|
||||||
|
CFIndex n = CFArrayGetCount(ms);
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
CGDisplayModeRef m = (CGDisplayModeRef) CFArrayGetValueAtIndex(ms, i);
|
||||||
|
if (CGDisplayModeGetIOFlags(m) & kDisplayModeNativeFlag) {
|
||||||
|
// This corresponds with "System Settings" -> General -> About -> Displays
|
||||||
|
returnScreen.pWidth = CGDisplayModeGetPixelWidth(m);
|
||||||
|
returnScreen.pHeight = CGDisplayModeGetPixelHeight(m);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CFRelease(ms);
|
||||||
|
|
||||||
|
if (returnScreen.pWidth == 0 || returnScreen.pHeight == 0) {
|
||||||
|
// If there was no native resolution take a best fit approach and use the backing pixel size.
|
||||||
|
NSRect pSize = [nthScreen convertRectToBacking:nthScreen.frame];
|
||||||
|
returnScreen.pHeight = (int) pSize.size.height;
|
||||||
|
returnScreen.pWidth = (int) pSize.size.width;
|
||||||
|
}
|
||||||
return returnScreen;
|
return returnScreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
"github.com/wailsapp/wails/v2/internal/frontend"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/wailsapp/wails/v2/internal/frontend"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetAllScreens(wailsContext unsafe.Pointer) ([]frontend.Screen, error) {
|
func GetAllScreens(wailsContext unsafe.Pointer) ([]frontend.Screen, error) {
|
||||||
@ -65,11 +95,21 @@ func GetAllScreens(wailsContext unsafe.Pointer) ([]frontend.Screen, error) {
|
|||||||
for screeNum := 0; screeNum < numScreens; screeNum++ {
|
for screeNum := 0; screeNum < numScreens; screeNum++ {
|
||||||
screenNumC := C.int(screeNum)
|
screenNumC := C.int(screeNum)
|
||||||
cScreen := C.GetNthScreen(screenNumC, wailsContext)
|
cScreen := C.GetNthScreen(screenNumC, wailsContext)
|
||||||
|
|
||||||
screen := frontend.Screen{
|
screen := frontend.Screen{
|
||||||
Height: int(cScreen.height),
|
Height: int(cScreen.height),
|
||||||
Width: int(cScreen.width),
|
Width: int(cScreen.width),
|
||||||
IsCurrent: cScreen.isCurrent == C.int(1),
|
IsCurrent: cScreen.isCurrent == C.int(1),
|
||||||
IsPrimary: cScreen.isPrimary == C.int(1),
|
IsPrimary: cScreen.isPrimary == C.int(1),
|
||||||
|
|
||||||
|
Size: frontend.ScreenSize{
|
||||||
|
Height: int(cScreen.height),
|
||||||
|
Width: int(cScreen.width),
|
||||||
|
},
|
||||||
|
PhysicalSize: frontend.ScreenSize{
|
||||||
|
Height: int(cScreen.pHeight),
|
||||||
|
Width: int(cScreen.pWidth),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
screens = append(screens, screen)
|
screens = append(screens, screen)
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ typedef struct Screen {
|
|||||||
int isPrimary;
|
int isPrimary;
|
||||||
int height;
|
int height;
|
||||||
int width;
|
int width;
|
||||||
|
int scale;
|
||||||
} Screen;
|
} Screen;
|
||||||
|
|
||||||
int GetNMonitors(GtkWindow *window){
|
int GetNMonitors(GtkWindow *window){
|
||||||
@ -36,14 +37,16 @@ Screen GetNThMonitor(int monitor_num, GtkWindow *window){
|
|||||||
screen.isPrimary = gdk_monitor_is_primary(monitor);
|
screen.isPrimary = gdk_monitor_is_primary(monitor);
|
||||||
screen.height = geometry.height;
|
screen.height = geometry.height;
|
||||||
screen.width = geometry.width;
|
screen.width = geometry.width;
|
||||||
|
screen.scale = gdk_monitor_get_scale_factor(monitor);
|
||||||
return screen;
|
return screen;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/wailsapp/wails/v2/internal/frontend"
|
"github.com/wailsapp/wails/v2/internal/frontend"
|
||||||
"sync"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Screen = frontend.Screen
|
type Screen = frontend.Screen
|
||||||
@ -59,11 +62,21 @@ func GetAllScreens(window *C.GtkWindow) ([]Screen, error) {
|
|||||||
numMonitors := C.GetNMonitors(window)
|
numMonitors := C.GetNMonitors(window)
|
||||||
for i := 0; i < int(numMonitors); i++ {
|
for i := 0; i < int(numMonitors); i++ {
|
||||||
cMonitor := C.GetNThMonitor(C.int(i), window)
|
cMonitor := C.GetNThMonitor(C.int(i), window)
|
||||||
|
|
||||||
screen := Screen{
|
screen := Screen{
|
||||||
IsCurrent: cMonitor.isCurrent == 1,
|
IsCurrent: cMonitor.isCurrent == 1,
|
||||||
IsPrimary: cMonitor.isPrimary == 1,
|
IsPrimary: cMonitor.isPrimary == 1,
|
||||||
Width: int(cMonitor.width),
|
Width: int(cMonitor.width),
|
||||||
Height: int(cMonitor.height),
|
Height: int(cMonitor.height),
|
||||||
|
|
||||||
|
Size: frontend.ScreenSize{
|
||||||
|
Width: int(cMonitor.width),
|
||||||
|
Height: int(cMonitor.height),
|
||||||
|
},
|
||||||
|
PhysicalSize: frontend.ScreenSize{
|
||||||
|
Width: int(cMonitor.width * cMonitor.scale),
|
||||||
|
Height: int(cMonitor.height * cMonitor.scale),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
screens = append(screens, screen)
|
screens = append(screens, screen)
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,12 @@ package windows
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc/w32"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc"
|
||||||
|
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc/w32"
|
||||||
)
|
)
|
||||||
|
|
||||||
func MonitorsEqual(first w32.MONITORINFO, second w32.MONITORINFO) bool {
|
func MonitorsEqual(first w32.MONITORINFO, second w32.MONITORINFO) bool {
|
||||||
@ -66,13 +68,26 @@ func EnumProc(hMonitor w32.HMONITOR, hdcMonitor w32.HDC, lprcMonitor *w32.RECT,
|
|||||||
return w32.TRUE
|
return w32.TRUE
|
||||||
}
|
}
|
||||||
|
|
||||||
height := lprcMonitor.Right - lprcMonitor.Left
|
width := lprcMonitor.Right - lprcMonitor.Left
|
||||||
width := lprcMonitor.Bottom - lprcMonitor.Top
|
height := lprcMonitor.Bottom - lprcMonitor.Top
|
||||||
ourMonitorData.IsPrimary = monInfo.DwFlags&w32.MONITORINFOF_PRIMARY == 1
|
ourMonitorData.IsPrimary = monInfo.DwFlags&w32.MONITORINFOF_PRIMARY == 1
|
||||||
ourMonitorData.Height = int(width)
|
ourMonitorData.Height = int(height)
|
||||||
ourMonitorData.Width = int(height)
|
ourMonitorData.Width = int(width)
|
||||||
ourMonitorData.IsCurrent = MonitorsEqual(*currentMonInfo, *monInfo)
|
ourMonitorData.IsCurrent = MonitorsEqual(*currentMonInfo, *monInfo)
|
||||||
|
|
||||||
|
ourMonitorData.PhysicalSize.Width = int(width)
|
||||||
|
ourMonitorData.PhysicalSize.Height = int(height)
|
||||||
|
|
||||||
|
var dpiX, dpiY uint
|
||||||
|
w32.GetDPIForMonitor(hMonitor, w32.MDT_EFFECTIVE_DPI, &dpiX, &dpiY)
|
||||||
|
if dpiX == 0 || dpiY == 0 {
|
||||||
|
screenContainer.errors = append(screenContainer.errors, fmt.Errorf("unable to get DPI for screen"))
|
||||||
|
screenContainer.monitors = append(screenContainer.monitors, Screen{})
|
||||||
|
return w32.TRUE
|
||||||
|
}
|
||||||
|
ourMonitorData.Size.Width = winc.ScaleToDefaultDPI(ourMonitorData.PhysicalSize.Width, dpiX)
|
||||||
|
ourMonitorData.Size.Height = winc.ScaleToDefaultDPI(ourMonitorData.PhysicalSize.Height, dpiY)
|
||||||
|
|
||||||
// the reason we need a container is that we have don't know how many times this function will be called
|
// the reason we need a container is that we have don't know how many times this function will be called
|
||||||
// this "append" call could potentially do an allocation and rewrite the pointer to monitors. So we save the pointer in screenContainer.monitors
|
// this "append" call could potentially do an allocation and rewrite the pointer to monitors. So we save the pointer in screenContainer.monitors
|
||||||
// and retrieve the values after all EnumProc calls
|
// and retrieve the values after all EnumProc calls
|
||||||
|
@ -48,8 +48,21 @@ const (
|
|||||||
type Screen struct {
|
type Screen struct {
|
||||||
IsCurrent bool `json:"isCurrent"`
|
IsCurrent bool `json:"isCurrent"`
|
||||||
IsPrimary bool `json:"isPrimary"`
|
IsPrimary bool `json:"isPrimary"`
|
||||||
Width int `json:"width"`
|
|
||||||
Height int `json:"height"`
|
// Deprecated: Please use Size and PhysicalSize
|
||||||
|
Width int `json:"width"`
|
||||||
|
// Deprecated: Please use Size and PhysicalSize
|
||||||
|
Height int `json:"height"`
|
||||||
|
|
||||||
|
// Size is the size of the screen in logical pixel space, used when setting sizes in Wails
|
||||||
|
Size ScreenSize `json:"size"`
|
||||||
|
// PhysicalSize is the physical size of the screen in pixels
|
||||||
|
PhysicalSize ScreenSize `json:"physicalSize"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ScreenSize struct {
|
||||||
|
Width int `json:"width"`
|
||||||
|
Height int `json:"height"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MessageDialogOptions contains the options for the Message dialogs, EG Info, Warning, etc runtime methods
|
// MessageDialogOptions contains the options for the Message dialogs, EG Info, Warning, etc runtime methods
|
||||||
|
@ -36,6 +36,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Added sveltekit.mdx guide. Added by @figuerom16 in [PR](https://github.com/wailsapp/wails/pull/2771)
|
- Added sveltekit.mdx guide. Added by @figuerom16 in [PR](https://github.com/wailsapp/wails/pull/2771)
|
||||||
- Added ProgramName option to [linux.Options](/docs/reference/options#linux). Added by @lyimmi in [PR](https://github.com/wailsapp/wails/pull/2817)
|
- Added ProgramName option to [linux.Options](/docs/reference/options#linux). Added by @lyimmi in [PR](https://github.com/wailsapp/wails/pull/2817)
|
||||||
- Added new community tempalte wails-sveltekit-ts. Added by [@haukened](https://github.com/haukened) in [PR](https://github.com/wailsapp/wails/pull/2851)
|
- Added new community tempalte wails-sveltekit-ts. Added by [@haukened](https://github.com/haukened) in [PR](https://github.com/wailsapp/wails/pull/2851)
|
||||||
|
- Added support for retrieving the logical and physical screen size in the screen api. Added by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2856)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user