mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 22:49:31 +08:00
152 lines
3.8 KiB
Go
152 lines
3.8 KiB
Go
//go:build darwin
|
|
|
|
package application
|
|
|
|
/*
|
|
#cgo CFLAGS: -x objective-c
|
|
#cgo LDFLAGS: -framework Foundation -framework Cocoa -framework WebKit -framework AppKit
|
|
#import <Foundation/Foundation.h>
|
|
#import <CoreGraphics/CoreGraphics.h>
|
|
#import <Cocoa/Cocoa.h>
|
|
#import <AppKit/AppKit.h>
|
|
#include <stdlib.h>
|
|
|
|
typedef struct Screen {
|
|
const char* id;
|
|
const char* name;
|
|
int p_width;
|
|
int p_height;
|
|
int width;
|
|
int height;
|
|
int x;
|
|
int y;
|
|
int w_width;
|
|
int w_height;
|
|
int w_x;
|
|
int w_y;
|
|
float scale;
|
|
double rotation;
|
|
bool isPrimary;
|
|
} Screen;
|
|
|
|
|
|
int GetNumScreens(){
|
|
return [[NSScreen screens] count];
|
|
}
|
|
|
|
Screen processScreen(NSScreen* screen){
|
|
Screen returnScreen;
|
|
returnScreen.scale = screen.backingScaleFactor;
|
|
|
|
// screen bounds
|
|
returnScreen.height = screen.frame.size.height;
|
|
returnScreen.width = screen.frame.size.width;
|
|
returnScreen.x = screen.frame.origin.x;
|
|
returnScreen.y = screen.frame.origin.y;
|
|
|
|
// work area
|
|
NSRect workArea = [screen visibleFrame];
|
|
returnScreen.w_height = workArea.size.height;
|
|
returnScreen.w_width = workArea.size.width;
|
|
returnScreen.w_x = workArea.origin.x;
|
|
returnScreen.w_y = workArea.origin.y;
|
|
|
|
|
|
// adapted from https://stackoverflow.com/a/1237490/4188138
|
|
NSDictionary* screenDictionary = [screen deviceDescription];
|
|
NSNumber* screenID = [screenDictionary objectForKey:@"NSScreenNumber"];
|
|
CGDirectDisplayID displayID = [screenID unsignedIntValue];
|
|
returnScreen.id = [[NSString stringWithFormat:@"%d", displayID] UTF8String];
|
|
|
|
// Get physical monitor size
|
|
NSValue *sizeValue = [screenDictionary objectForKey:@"NSDeviceSize"];
|
|
NSSize physicalSize = sizeValue.sizeValue;
|
|
returnScreen.p_height = physicalSize.height;
|
|
returnScreen.p_width = physicalSize.width;
|
|
|
|
// Get the rotation
|
|
double rotation = CGDisplayRotation(displayID);
|
|
returnScreen.rotation = rotation;
|
|
|
|
if( @available(macOS 10.15, *) ){
|
|
returnScreen.name = [screen.localizedName UTF8String];
|
|
}
|
|
|
|
return returnScreen;
|
|
}
|
|
|
|
// Get primary screen
|
|
Screen GetPrimaryScreen(){
|
|
// Get primary screen
|
|
NSScreen *mainScreen = [NSScreen mainScreen];
|
|
return processScreen(mainScreen);
|
|
}
|
|
|
|
Screen* getAllScreens() {
|
|
NSArray<NSScreen *> *screens = [NSScreen screens];
|
|
Screen* returnScreens = malloc(sizeof(Screen) * screens.count);
|
|
for (int i = 0; i < screens.count; i++) {
|
|
NSScreen* screen = [screens objectAtIndex:i];
|
|
returnScreens[i] = processScreen(screen);
|
|
}
|
|
return returnScreens;
|
|
}
|
|
|
|
Screen getScreenForWindow(void* window){
|
|
NSScreen* screen = ((NSWindow*)window).screen;
|
|
return processScreen(screen);
|
|
}
|
|
|
|
*/
|
|
import "C"
|
|
import "unsafe"
|
|
|
|
func cScreenToScreen(screen C.Screen) *Screen {
|
|
|
|
return &Screen{
|
|
Size: Size{
|
|
Width: int(screen.p_width),
|
|
Height: int(screen.p_height),
|
|
},
|
|
Bounds: Rect{
|
|
X: int(screen.x),
|
|
Y: int(screen.y),
|
|
Height: int(screen.height),
|
|
Width: int(screen.width),
|
|
},
|
|
WorkArea: Rect{
|
|
X: int(screen.w_x),
|
|
Y: int(screen.w_y),
|
|
Height: int(screen.w_height),
|
|
Width: int(screen.w_width),
|
|
},
|
|
Scale: float32(screen.scale),
|
|
ID: C.GoString(screen.id),
|
|
Name: C.GoString(screen.name),
|
|
IsPrimary: bool(screen.isPrimary),
|
|
Rotation: float32(screen.rotation),
|
|
}
|
|
}
|
|
|
|
func getPrimaryScreen() (*Screen, error) {
|
|
cScreen := C.GetPrimaryScreen()
|
|
return cScreenToScreen(cScreen), nil
|
|
}
|
|
|
|
func getScreens() ([]*Screen, error) {
|
|
cScreens := C.getAllScreens()
|
|
defer C.free(unsafe.Pointer(cScreens))
|
|
numScreens := int(C.GetNumScreens())
|
|
displays := make([]*Screen, numScreens)
|
|
cScreenHeaders := (*[1 << 30]C.Screen)(unsafe.Pointer(cScreens))[:numScreens:numScreens]
|
|
for i := 0; i < numScreens; i++ {
|
|
displays[i] = cScreenToScreen(cScreenHeaders[i])
|
|
}
|
|
return displays, nil
|
|
}
|
|
|
|
func getScreenForWindow(window *macosWebviewWindow) (*Screen, error) {
|
|
cScreen := C.getScreenForWindow(window.nsWindow)
|
|
return cScreenToScreen(cScreen), nil
|
|
}
|