Support Min/Max/Fullscreen, BackgroundColour

This commit is contained in:
Lea Anthony 2022-12-08 17:25:39 +11:00
commit 508bbb4fb4
No known key found for this signature in database
GPG key ID: 33DAF7BB90A58405
9 changed files with 307 additions and 43 deletions

View file

@ -22,18 +22,25 @@ func main() {
println("TERMINATION!!")
})
myWindow := app.NewWindow(&options.Window{
Title: "Basic",
Width: 600,
Height: 400,
AlwaysOnTop: false,
DisableResize: false,
MinWidth: 100,
MinHeight: 100,
MaxWidth: 1000,
MaxHeight: 1000,
Title: "Basic",
Width: 600,
Height: 400,
AlwaysOnTop: false,
DisableResize: false,
//MinWidth: 100,
//MinHeight: 100,
//MaxWidth: 1000,
//MaxHeight: 1000,
EnableDevTools: true,
BackgroundColour: &options.RGBA{
Red: 255,
Green: 255,
Blue: 255,
Alpha: 30,
},
StartState: options.WindowStateMaximised,
Mac: &options.MacWindow{
Backdrop: options.MacBackdropNormal,
Backdrop: options.MacBackdropTranslucent,
},
})

View file

@ -2,4 +2,7 @@ module github.com/wailsapp/wails/exp
go 1.19
require github.com/leaanthony/clir v1.3.0
require (
github.com/gofrs/uuid v4.3.1+incompatible
github.com/leaanthony/clir v1.3.0
)

View file

@ -1,2 +1,4 @@
github.com/gofrs/uuid v4.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI=
github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/leaanthony/clir v1.3.0 h1:L9nPDWrmc/qU9UWZZvRaFajWYuO0np9V5p+5gxyYno0=
github.com/leaanthony/clir v1.3.0/go.mod h1:k/RBkdkFl18xkkACMCLt09bhiZnrGORoxmomeMvDpE0=

View file

@ -1,5 +1,6 @@
package application
import "C"
import "github.com/wailsapp/wails/exp/pkg/options"
type Application interface {
@ -11,6 +12,9 @@ type App struct {
systemEventListeners map[string][]func()
windows []*Window
// Running
running bool
}
func (a *App) On(s string, callback func()) {
@ -20,5 +24,34 @@ func (a *App) On(s string, callback func()) {
func (a *App) NewWindow(options *options.Window) *Window {
newWindow := NewWindow(options)
a.windows = append(a.windows, newWindow)
if a.running {
err := newWindow.Run()
if err != nil {
panic(err)
}
}
return newWindow
}
func (a *App) Run() error {
a.running = true
go func() {
for {
event := <-systemEvents
a.handleSystemEvent(event)
}
}()
// run windows
for _, window := range a.windows {
err := window.Run()
if err != nil {
return err
}
}
return a.run()
}

View file

@ -1,5 +1,10 @@
//go:build darwin
#ifndef application_h
#define application_h
void Init(void);
void Run(void);
void SetActivationPolicy(int policy);
void SetActivationPolicy(int policy);
#endif

View file

@ -22,23 +22,7 @@ func New(options *options.Application) *App {
}
}
func (a *App) Run() error {
go func() {
for {
event := <-systemEvents
a.handleSystemEvent(event)
}
}()
// run windows
for _, window := range a.windows {
err := window.Run()
if err != nil {
return err
}
}
func (a *App) run() error {
C.Run()
return nil
}

View file

@ -1,6 +1,10 @@
package application
import "github.com/wailsapp/wails/exp/pkg/options"
import (
"sync/atomic"
"github.com/wailsapp/wails/exp/pkg/options"
)
type windowImpl interface {
setTitle(title string)
@ -13,15 +17,29 @@ type windowImpl interface {
setMaxSize(width, height int)
enableDevTools()
execJS(js string)
setMaximised()
setMinimised()
setFullscreen()
isMinimised() bool
isMaximised() bool
isFullscreen() bool
restore()
setBackgroundColor(color *options.RGBA)
}
type Window struct {
options *options.Window
impl windowImpl
id uint64
}
var windowID atomic.Uint64
func NewWindow(options *options.Window) *Window {
id := windowID.Load()
windowID.Add(1)
return &Window{
id: id,
options: options,
}
}
@ -117,3 +135,62 @@ func (w *Window) ExecJS(js string) {
}
w.impl.execJS(js)
}
// Set Maximized
func (w *Window) SetMaximized() {
if w.impl == nil {
w.options.StartState = options.WindowStateMaximised
return
}
w.impl.setMaximised()
}
// Set Minimized
func (w *Window) SetMinimized() {
if w.impl == nil {
w.options.StartState = options.WindowStateMinimised
return
}
w.impl.setMinimised()
}
// Set Fullscreen
func (w *Window) SetFullscreen() {
if w.impl == nil {
w.options.StartState = options.WindowStateFullscreen
return
}
w.impl.setFullscreen()
}
// IsMinimised returns true if the window is minimised
func (w *Window) IsMinimised() bool {
if w.impl == nil {
return false
}
return w.impl.isMinimised()
}
// IsMaximised returns true if the window is maximised
func (w *Window) IsMaximised() bool {
if w.impl == nil {
return false
}
return w.impl.isMaximised()
}
// IsFullscreen returns true if the window is fullscreen
func (w *Window) IsFullscreen() bool {
if w.impl == nil {
return false
}
return w.impl.isFullscreen()
}
func (w *Window) SetBackgroundColor(color *options.RGBA) {
if w.impl == nil {
w.options.BackgroundColour = color
return
}
w.impl.setBackgroundColor(color)
}

View file

@ -200,10 +200,94 @@ void webviewSetTransparent(void* nsWindow) {
// Get window delegate
WindowDelegate* delegate = (WindowDelegate*)[(NSWindow*)nsWindow delegate];
// Set webview background transparent
[delegate.webView setValue:@YES forKey:@"drawsTransparentBackground"];
[delegate.webView setValue:@NO forKey:@"drawsBackground"];
});
}
// Set webview background color
void webviewSetBackgroundColor(void* nsWindow, int r, int g, int b, int alpha) {
// Set webview background color on main thread
dispatch_async(dispatch_get_main_queue(), ^{
// Get window delegate
WindowDelegate* delegate = (WindowDelegate*)[(NSWindow*)nsWindow delegate];
// Set webview background color
[delegate.webView setValue:[NSColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:alpha/255.0] forKey:@"backgroundColor"];
});
}
// Set Window maximised
void windowSetMaximised(void* nsWindow) {
// Set window maximized on main thread
dispatch_async(dispatch_get_main_queue(), ^{
[(NSWindow*)nsWindow zoom:nil];
});
}
// Set Window fullscreen
void windowSetFullscreen(void* nsWindow) {
// Set window fullscreen on main thread
dispatch_async(dispatch_get_main_queue(), ^{
[(NSWindow*)nsWindow toggleFullScreen:nil];
});
}
// Set Window Minimised
void windowSetMinimised(void* nsWindow) {
// Set window minimised on main thread
dispatch_async(dispatch_get_main_queue(), ^{
// Get screen that the window is on
NSScreen* screen = [(NSWindow*)nsWindow screen];
NSRect screenRect = [screen frame];
// Set window to top left corner
[(NSWindow*)nsWindow setFrame:NSMakeRect(0, screenRect.size.height, 0, 0) display:YES];
});
}
// restore window to normal size
void windowRestore(void* nsWindow) {
// Set window normal on main thread
dispatch_async(dispatch_get_main_queue(), ^{
// If window is fullscreen
if([(NSWindow*)nsWindow styleMask] & NSFullScreenWindowMask) {
[(NSWindow*)nsWindow toggleFullScreen:nil];
}
// If window is maximised
if([(NSWindow*)nsWindow isZoomed]) {
[(NSWindow*)nsWindow zoom:nil];
}
// If window in minimised
if([(NSWindow*)nsWindow isMiniaturized]) {
[(NSWindow*)nsWindow deminiaturize:nil];
}
});
}
bool windowIsMaximised(void* nsWindow) {
// Get window maximized on main thread
__block bool maximized = false;
dispatch_sync(dispatch_get_main_queue(), ^{
maximized = [(NSWindow*)nsWindow isZoomed];
});
return maximized;
}
bool windowIsFullscreen(void* nsWindow) {
// Get window fullscreen on main thread
__block bool fullscreen = false;
dispatch_sync(dispatch_get_main_queue(), ^{
fullscreen = [(NSWindow*)nsWindow styleMask] & NSFullScreenWindowMask;
});
return fullscreen;
}
bool windowIsMinimised(void* nsWindow) {
// Get window minimised on main thread
__block bool minimised = false;
dispatch_sync(dispatch_get_main_queue(), ^{
minimised = [(NSWindow*)nsWindow isMiniaturized];
});
return minimised;
}
*/
@ -215,10 +299,44 @@ import (
)
type macosWindow struct {
id uint64
nsWindow unsafe.Pointer
options *options.Window
}
func (w *macosWindow) isMinimised() bool {
return C.windowIsMinimised(w.nsWindow) == C.bool(true)
}
func (w *macosWindow) isMaximised() bool {
return C.windowIsMaximised(w.nsWindow) == C.bool(true)
}
func (w *macosWindow) isFullscreen() bool {
return C.windowIsFullscreen(w.nsWindow) == C.bool(true)
}
func (w *macosWindow) restore() {
//TODO implement me
panic("implement me")
}
func (w *macosWindow) setMaximised() {
C.windowSetMaximised(w.nsWindow)
}
func (w *macosWindow) setMinimised() {
C.windowSetMinimised(w.nsWindow)
}
func (w *macosWindow) setFullscreen() {
C.windowSetFullscreen(w.nsWindow)
}
func (w *macosWindow) restoreWindow() {
C.windowRestore(w.nsWindow)
}
func (w *macosWindow) execJS(js string) {
C.windowExecJS(w.nsWindow, C.CString(js))
}
@ -274,6 +392,7 @@ func (w *macosWindow) run() error {
if w.options.EnableDevTools {
w.enableDevTools()
}
w.setBackgroundColor(w.options.BackgroundColour)
if w.options.Mac != nil {
switch w.options.Mac.Backdrop {
case options.MacBackdropTransparent:
@ -283,7 +402,26 @@ func (w *macosWindow) run() error {
C.windowSetTranslucent(w.nsWindow)
C.webviewSetTransparent(w.nsWindow)
}
switch w.options.StartState {
case options.WindowStateMaximised:
w.setMaximised()
case options.WindowStateMinimised:
w.setMinimised()
case options.WindowStateFullscreen:
w.setFullscreen()
}
}
C.windowShow(w.nsWindow)
return nil
}
func (w *macosWindow) setBackgroundColor(colour *options.RGBA) {
if colour == nil {
return
}
C.webviewSetBackgroundColor(w.nsWindow, C.int(colour.Red), C.int(colour.Green), C.int(colour.Blue), C.int(colour.Alpha))
}

View file

@ -21,18 +21,24 @@ type Mac struct {
}
type Window struct {
Title string
Width, Height int
AlwaysOnTop bool
URL string
DisableResize bool
Resizable bool
MinWidth int
MinHeight int
MaxWidth int
MaxHeight int
EnableDevTools bool
Mac *MacWindow
Title string
Width, Height int
AlwaysOnTop bool
URL string
DisableResize bool
Resizable bool
MinWidth int
MinHeight int
MaxWidth int
MaxHeight int
EnableDevTools bool
StartState WindowState
Mac *MacWindow
BackgroundColour *RGBA
}
type RGBA struct {
Red, Green, Blue, Alpha uint8
}
type MacBackdrop int
@ -43,6 +49,15 @@ const (
MacBackdropTranslucent
)
type WindowState int
const (
WindowStateNormal WindowState = iota
WindowStateMinimised
WindowStateMaximised
WindowStateFullscreen
)
// MacWindow contains macOS specific options
type MacWindow struct {
Backdrop MacBackdrop