Add main thread dispatching

Make `window.Run` operate on main thread
This commit is contained in:
Lea Anthony 2022-12-09 07:47:47 +11:00
commit 85abb1122f
No known key found for this signature in database
GPG key ID: 33DAF7BB90A58405
6 changed files with 131 additions and 71 deletions

View file

@ -45,17 +45,22 @@ func main() {
},
})
myWindow2 := app.NewWindow(&options.Window{
Title: "#2",
Width: 1024,
Height: 768,
AlwaysOnTop: false,
URL: "https://google.com",
DisableResize: true,
Mac: &options.MacWindow{
Backdrop: options.MacBackdropTranslucent,
},
})
var myWindow2 *application.Window
go func() {
time.Sleep(2 * time.Second)
myWindow2 = app.NewWindow(&options.Window{
Title: "#2",
Width: 1024,
Height: 768,
AlwaysOnTop: false,
URL: "https://google.com",
DisableResize: true,
Mac: &options.MacWindow{
Backdrop: options.MacBackdropTranslucent,
},
})
}()
go func() {
time.Sleep(5 * time.Second)

View file

@ -40,10 +40,7 @@ func (a *App) NewWindow(options *options.Window) *Window {
}
a.windows[id] = newWindow
if a.running {
err := newWindow.Run()
if err != nil {
panic(err)
}
newWindow.Run()
}
return newWindow
@ -67,10 +64,7 @@ func (a *App) Run() error {
// run windows
for _, window := range a.windows {
err := window.Run()
if err != nil {
return err
}
go window.Run()
}
return a.run()

View file

@ -0,0 +1,41 @@
//go:build darwin
package application
/*
extern void dispatch(unsigned int id);
*/
import "C"
import "strconv"
var mainThreadFuntionStore = make(map[uint]func())
func generateFunctionStoreID() uint {
startID := 0
for {
if _, ok := mainThreadFuntionStore[uint(startID)]; !ok {
return uint(startID)
}
startID++
if startID == 0 {
panic("Too many functions stored")
}
}
}
func Dispatch(fn func()) {
id := generateFunctionStoreID()
mainThreadFuntionStore[id] = fn
C.dispatch(C.uint(id))
}
//export dispatchCallback
func dispatchCallback(id C.uint) {
fn := mainThreadFuntionStore[uint(id)]
if fn == nil {
panic("dispatchCallback called with invalid id " + strconv.Itoa(int(id)))
}
fn()
delete(mainThreadFuntionStore, uint(id))
}

View file

@ -0,0 +1,20 @@
//go:build darwin
package application
/*
#cgo CFLAGS: -mmacosx-version-min=10.13 -x objective-c
#cgo LDFLAGS: -framework Cocoa
#include "Cocoa/Cocoa.h"
extern void dispatchCallback(unsigned int);
void dispatch(unsigned int id) {
dispatch_async(dispatch_get_main_queue(), ^{
dispatchCallback(id);
});
}
*/
import "C"

View file

@ -11,7 +11,6 @@ type windowImpl interface {
setTitle(title string)
setSize(width, height int)
setAlwaysOnTop(alwaysOnTop bool)
run() error
navigateToURL(url string)
setResizable(resizable bool)
setMinSize(width, height int)
@ -26,6 +25,7 @@ type windowImpl interface {
isFullscreen() bool
restore()
setBackgroundColor(color *options.RGBA)
run()
}
type Window struct {
@ -68,9 +68,9 @@ func (w *Window) SetSize(width, height int) {
w.impl.setSize(width, height)
}
func (w *Window) Run() error {
func (w *Window) Run() {
w.impl = newWindowImpl(w.id, w.options)
return w.impl.run()
w.impl.run()
}
func (w *Window) SetAlwaysOnTop(b bool) {

View file

@ -489,59 +489,59 @@ func (w *macosWindow) enableDevTools() {
C.windowEnableDevTools(w.nsWindow)
}
func (w *macosWindow) run() error {
w.nsWindow = C.windowNew(C.uint(w.id), C.int(w.options.Width), C.int(w.options.Height))
w.setTitle(w.options.Title)
w.setAlwaysOnTop(w.options.AlwaysOnTop)
w.setResizable(!w.options.DisableResize)
w.setMinSize(w.options.MinWidth, w.options.MinHeight)
w.setMaxSize(w.options.MaxWidth, w.options.MaxHeight)
if w.options.URL != "" {
w.navigateToURL(w.options.URL)
}
if w.options.EnableDevTools {
w.enableDevTools()
}
w.setBackgroundColor(w.options.BackgroundColour)
if w.options.Mac != nil {
macOptions := w.options.Mac
switch macOptions.Backdrop {
case options.MacBackdropTransparent:
C.windowSetTransparent(w.nsWindow)
C.webviewSetTransparent(w.nsWindow)
case options.MacBackdropTranslucent:
C.windowSetTranslucent(w.nsWindow)
C.webviewSetTransparent(w.nsWindow)
func (w *macosWindow) run() {
Dispatch(func() {
w.nsWindow = C.windowNew(C.uint(w.id), C.int(w.options.Width), C.int(w.options.Height))
w.setTitle(w.options.Title)
w.setAlwaysOnTop(w.options.AlwaysOnTop)
w.setResizable(!w.options.DisableResize)
w.setMinSize(w.options.MinWidth, w.options.MinHeight)
w.setMaxSize(w.options.MaxWidth, w.options.MaxHeight)
if w.options.URL != "" {
w.navigateToURL(w.options.URL)
}
if macOptions.TitleBar != nil {
titleBarOptions := macOptions.TitleBar
C.windowSetTitleBarAppearsTransparent(w.nsWindow, C.bool(titleBarOptions.AppearsTransparent))
C.windowSetHideTitleBar(w.nsWindow, C.bool(titleBarOptions.Hide))
C.windowSetHideTitle(w.nsWindow, C.bool(titleBarOptions.HideTitle))
C.windowSetFullSizeContent(w.nsWindow, C.bool(titleBarOptions.FullSizeContent))
C.windowSetUseToolbar(w.nsWindow, C.bool(titleBarOptions.UseToolbar))
C.windowSetHideToolbarSeparator(w.nsWindow, C.bool(titleBarOptions.HideToolbarSeparator))
if w.options.EnableDevTools {
w.enableDevTools()
}
w.setBackgroundColor(w.options.BackgroundColour)
if w.options.Mac != nil {
macOptions := w.options.Mac
switch macOptions.Backdrop {
case options.MacBackdropTransparent:
C.windowSetTransparent(w.nsWindow)
C.webviewSetTransparent(w.nsWindow)
case options.MacBackdropTranslucent:
C.windowSetTranslucent(w.nsWindow)
C.webviewSetTransparent(w.nsWindow)
}
if macOptions.Appearance != "" {
C.windowSetAppearanceTypeByName(w.nsWindow, C.CString(string(macOptions.Appearance)))
}
if macOptions.TitleBar != nil {
titleBarOptions := macOptions.TitleBar
C.windowSetTitleBarAppearsTransparent(w.nsWindow, C.bool(titleBarOptions.AppearsTransparent))
C.windowSetHideTitleBar(w.nsWindow, C.bool(titleBarOptions.Hide))
C.windowSetHideTitle(w.nsWindow, C.bool(titleBarOptions.HideTitle))
C.windowSetFullSizeContent(w.nsWindow, C.bool(titleBarOptions.FullSizeContent))
C.windowSetUseToolbar(w.nsWindow, C.bool(titleBarOptions.UseToolbar))
C.windowSetHideToolbarSeparator(w.nsWindow, C.bool(titleBarOptions.HideToolbarSeparator))
}
switch w.options.StartState {
case options.WindowStateMaximised:
w.setMaximised()
case options.WindowStateMinimised:
w.setMinimised()
case options.WindowStateFullscreen:
w.setFullscreen()
if macOptions.Appearance != "" {
C.windowSetAppearanceTypeByName(w.nsWindow, C.CString(string(macOptions.Appearance)))
}
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
C.windowShow(w.nsWindow)
})
}
func (w *macosWindow) setBackgroundColor(colour *options.RGBA) {