mirror of
https://github.com/wailsapp/wails.git
synced 2026-03-14 14:45:49 +01:00
Add screen support
Co-authored-by: Oleg Gulevskyy <43781031+oleggulevskyy@users.noreply.github.com>
This commit is contained in:
parent
92af7455ad
commit
ad1d104d85
6 changed files with 229 additions and 1 deletions
|
|
@ -2,6 +2,7 @@ package main
|
|||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
|
|
@ -169,7 +170,37 @@ func main() {
|
|||
w.SetURL("https://wails.io")
|
||||
})
|
||||
})
|
||||
|
||||
stateMenu.Add("Get Primary Screen").OnClick(func(ctx *application.Context) {
|
||||
screen, err := app.GetPrimaryScreen()
|
||||
if err != nil {
|
||||
app.NewErrorDialog().SetTitle("Error").SetMessage(err.Error()).Show()
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("Screen: %+v", screen)
|
||||
app.NewInfoDialog().SetTitle("Primary Screen").SetMessage(msg).Show()
|
||||
})
|
||||
stateMenu.Add("Get Screens").OnClick(func(ctx *application.Context) {
|
||||
screens, err := app.GetScreens()
|
||||
if err != nil {
|
||||
app.NewErrorDialog().SetTitle("Error").SetMessage(err.Error()).Show()
|
||||
return
|
||||
}
|
||||
for _, screen := range screens {
|
||||
msg := fmt.Sprintf("Screen: %+v", screen)
|
||||
app.NewInfoDialog().SetTitle(fmt.Sprintf("Screen %s", screen.ID)).SetMessage(msg).Show()
|
||||
}
|
||||
})
|
||||
stateMenu.Add("Get Screen for Window").OnClick(func(ctx *application.Context) {
|
||||
currentWindow(func(w *application.Window) {
|
||||
screen, err := w.GetScreen()
|
||||
if err != nil {
|
||||
app.NewErrorDialog().SetTitle("Error").SetMessage(err.Error()).Show()
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("Screen: %+v", screen)
|
||||
app.NewInfoDialog().SetTitle(fmt.Sprintf("Screen %s", screen.ID)).SetMessage(msg).Show()
|
||||
})
|
||||
})
|
||||
app.NewWindow()
|
||||
|
||||
app.SetMenu(menu)
|
||||
|
|
|
|||
|
|
@ -362,6 +362,14 @@ func (a *App) NewSaveFileDialog() *SaveFileDialog {
|
|||
return newSaveFileDialog()
|
||||
}
|
||||
|
||||
func (a *App) GetPrimaryScreen() (*Screen, error) {
|
||||
return getPrimaryScreen()
|
||||
}
|
||||
|
||||
func (a *App) GetScreens() ([]*Screen, error) {
|
||||
return getScreens()
|
||||
}
|
||||
|
||||
func (a *App) Clipboard() *Clipboard {
|
||||
if a.clipboard == nil {
|
||||
a.clipboard = newClipboard()
|
||||
|
|
|
|||
26
exp/pkg/application/screen.go
Normal file
26
exp/pkg/application/screen.go
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
package application
|
||||
|
||||
type Screen struct {
|
||||
ID string // A unique identifier for the display
|
||||
Name string // The name of the display
|
||||
Scale float32 // The scale factor of the display
|
||||
X int // The x-coordinate of the top-left corner of the rectangle
|
||||
Y int // The y-coordinate of the top-left corner of the rectangle
|
||||
Size Size // The size of the display
|
||||
Bounds Rect // The bounds of the display
|
||||
WorkArea Rect // The work area of the display
|
||||
IsPrimary bool // Whether this is the primary display
|
||||
Rotation float32 // The rotation of the display
|
||||
}
|
||||
|
||||
type Rect struct {
|
||||
X int
|
||||
Y int
|
||||
Width int
|
||||
Height int
|
||||
}
|
||||
|
||||
type Size struct {
|
||||
Width int
|
||||
Height int
|
||||
}
|
||||
151
exp/pkg/application/screen_darwin.go
Normal file
151
exp/pkg/application/screen_darwin.go
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
//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 *macosWindow) (*Screen, error) {
|
||||
cScreen := C.getScreenForWindow(window.nsWindow)
|
||||
return cScreenToScreen(cScreen), nil
|
||||
}
|
||||
|
|
@ -52,6 +52,7 @@ type (
|
|||
setFullscreenButtonEnabled(enabled bool)
|
||||
show()
|
||||
hide()
|
||||
getScreen() (*Screen, error)
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -545,3 +546,10 @@ func (w *Window) enableSizeConstraints() {
|
|||
w.SetMinSize(w.options.MinWidth, w.options.MinHeight)
|
||||
w.SetMaxSize(w.options.MaxWidth, w.options.MaxHeight)
|
||||
}
|
||||
|
||||
func (w *Window) GetScreen() (*Screen, error) {
|
||||
if w.impl == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return w.impl.getScreen()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -691,6 +691,10 @@ type macosWindow struct {
|
|||
parent *Window
|
||||
}
|
||||
|
||||
func (w *macosWindow) getScreen() (*Screen, error) {
|
||||
return getScreenForWindow(w)
|
||||
}
|
||||
|
||||
func (w *macosWindow) show() {
|
||||
C.windowShow(w.nsWindow)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue