From 6a9a87046221602d1a323887cd619e75c81cc24e Mon Sep 17 00:00:00 2001 From: Sebastien Binet Date: Fri, 26 Jun 2020 11:01:25 +0000 Subject: [PATCH] app{,/internal/window}: make app.Main blocking on desktop platforms This CL implements the app.Main function as a blocking-forever function for JS, Wayland, Windows and X11. This works better for applications that can now programmatically close windows. --- app/app.go | 6 ++++-- app/internal/window/os_js.go | 5 +---- app/internal/window/os_macos.go | 4 ---- app/internal/window/os_macos.m | 6 ------ app/internal/window/os_unix.go | 10 +--------- app/internal/window/os_wayland.go | 6 ------ app/internal/window/os_windows.go | 16 ++-------------- app/internal/window/os_x11.go | 5 ----- 8 files changed, 8 insertions(+), 50 deletions(-) diff --git a/app/app.go b/app/app.go index 6946809d..d21224e5 100644 --- a/app/app.go +++ b/app/app.go @@ -35,8 +35,10 @@ func DataDir() (string, error) { return dataDir() } -// Main must be called from the program main function. It -// blocks until there are no more windows active. +// Main must be called last from the program main function. +// On most platforms Main blocks forever, for Android and +// iOS it returns immediately to give control of the main +// thread back to the system. // // Calling Main is necessary because some operating systems // require control of the main thread of the program for diff --git a/app/internal/window/os_js.go b/app/internal/window/os_js.go index 30255f22..32235dfd 100644 --- a/app/internal/window/os_js.go +++ b/app/internal/window/os_js.go @@ -36,8 +36,6 @@ type window struct { animating bool } -var mainDone = make(chan struct{}) - func NewWindow(win Callbacks, opts *Options) error { doc := js.Global().Get("document") cont := getContainer(doc) @@ -70,7 +68,6 @@ func NewWindow(win Callbacks, opts *Options) error { w.draw(true) select {} w.cleanup() - close(mainDone) }() return nil } @@ -449,7 +446,7 @@ func (w *window) config() (int, int, float32, unit.Metric) { } func Main() { - <-mainDone + select {} } func translateKey(k string) (string, bool) { diff --git a/app/internal/window/os_macos.go b/app/internal/window/os_macos.go index 43e32405..ef95b704 100644 --- a/app/internal/window/os_macos.go +++ b/app/internal/window/os_macos.go @@ -40,7 +40,6 @@ __attribute__ ((visibility ("hidden"))) CGFloat gio_getScreenBackingScale(void); __attribute__ ((visibility ("hidden"))) CFTypeRef gio_readClipboard(void); __attribute__ ((visibility ("hidden"))) void gio_writeClipboard(unichar *chars, NSUInteger length); __attribute__ ((visibility ("hidden"))) void gio_setNeedsDisplay(CFTypeRef viewRef); -__attribute__ ((visibility ("hidden"))) void gio_appTerminate(void); __attribute__ ((visibility ("hidden"))) CFTypeRef gio_createWindow(CFTypeRef viewRef, const char *title, CGFloat width, CGFloat height, CGFloat minWidth, CGFloat minHeight, CGFloat maxWidth, CGFloat maxHeight); __attribute__ ((visibility ("hidden"))) void gio_makeKeyAndOrderFront(CFTypeRef windowRef); __attribute__ ((visibility ("hidden"))) NSPoint gio_cascadeTopLeftFromPoint(CFTypeRef windowRef, NSPoint topLeft); @@ -271,9 +270,6 @@ func gio_onClose(view C.CFTypeRef) { w.view = 0 C.CFRelease(w.window) w.window = 0 - if len(viewMap) == 0 { - C.gio_appTerminate() - } } //export gio_onHide diff --git a/app/internal/window/os_macos.m b/app/internal/window/os_macos.m index 44610813..b8c0deec 100644 --- a/app/internal/window/os_macos.m +++ b/app/internal/window/os_macos.m @@ -153,12 +153,6 @@ CFTypeRef gio_createWindow(CFTypeRef viewRef, const char *title, CGFloat width, } } -void gio_appTerminate(void) { - @autoreleasepool { - [NSApp terminate:nil]; - } -} - void gio_close(CFTypeRef windowRef) { NSWindow* window = (__bridge NSWindow *)windowRef; [window performClose:nil]; diff --git a/app/internal/window/os_unix.go b/app/internal/window/os_unix.go index 76d6ce17..baaebb56 100644 --- a/app/internal/window/os_unix.go +++ b/app/internal/window/os_unix.go @@ -8,16 +8,8 @@ import ( "errors" ) -// windowCounter keeps track of the number of windows. -// A send of +1 or -1 represents a change in window count. -var windowCounter = make(chan int) - func Main() { - // Wait for first window - count := <-windowCounter - for count > 0 { - count += <-windowCounter - } + select {} } // instead of creating files with build tags for each combination of wayland +/- x11 diff --git a/app/internal/window/os_wayland.go b/app/internal/window/os_wayland.go index 50e8aa79..4a456ce2 100644 --- a/app/internal/window/os_wayland.go +++ b/app/internal/window/os_wayland.go @@ -232,14 +232,8 @@ func newWLWindow(window Callbacks, opts *Options) error { d.destroy() return err } - // Increment window counter. - windowCounter <- +1 w.w = window go func() { - defer func() { - // Decrement window counter. - windowCounter <- -1 - }() defer d.destroy() defer w.destroy() w.w.SetDriver(w) diff --git a/app/internal/window/os_windows.go b/app/internal/window/os_windows.go index fb5b2882..247f10ad 100644 --- a/app/internal/window/os_windows.go +++ b/app/internal/window/os_windows.go @@ -57,10 +57,6 @@ type window struct { const _WM_REDRAW = windows.WM_USER + 0 -// windowCounter keeps track of the number of windows. -// A send of +1 or -1 represents a change in window count. -var windowCounter = make(chan int) - type gpuAPI struct { priority int initializer func(w *window) (Context, error) @@ -84,11 +80,7 @@ var resources struct { } func Main() { - // Wait for first window - count := <-windowCounter - for count > 0 { - count += <-windowCounter - } + select {} } func NewWindow(window Callbacks, opts *Options) error { @@ -104,11 +96,7 @@ func NewWindow(window Callbacks, opts *Options) error { defer w.destroy() cerr <- nil winMap.Store(w.hwnd, w) - windowCounter <- +1 - defer func() { - winMap.Delete(w.hwnd) - windowCounter <- -1 - }() + defer winMap.Delete(w.hwnd) w.w = window w.w.SetDriver(w) defer w.w.Event(system.DestroyEvent{}) diff --git a/app/internal/window/os_x11.go b/app/internal/window/os_x11.go index 42749b03..f9862439 100644 --- a/app/internal/window/os_x11.go +++ b/app/internal/window/os_x11.go @@ -576,12 +576,7 @@ func newX11Window(gioWin Callbacks, opts *Options) error { // make the window visible on the screen C.XMapWindow(dpy, win) - // Increment window counter. - windowCounter <- +1 go func() { - defer func() { - windowCounter <- -1 - }() w.w.SetDriver(w) w.setStage(system.StageRunning) w.loop()