~eliasnaur/gio-patches

app{,/internal/window}: [JS, Wayland, Windows, X11] make app.Main blocking v1 PROPOSED

Sebastien Binet: 1
 app{,/internal/window}: [JS, Wayland, Windows, X11] make app.Main blocking

 6 files changed, 8 insertions(+), 40 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~eliasnaur/gio-patches/patches/11343/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH] app{,/internal/window}: [JS, Wayland, Windows, X11] make app.Main blocking Export this patch

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_unix.go    | 10 +---------
 app/internal/window/os_wayland.go |  6 ------
 app/internal/window/os_windows.go | 16 ++--------------
 app/internal/window/os_x11.go     |  5 -----
 6 files changed, 8 insertions(+), 40 deletions(-)

diff --git a/app/app.go b/app/app.go
index 6946809..d21224e 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 30255f2..32235df 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_unix.go b/app/internal/window/os_unix.go
index 76d6ce1..baaebb5 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 50e8aa7..4a456ce 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 aed71ff..bcf2f3e 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 42749b0..f986243 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()
-- 
2.27.0
Thanks. Merged along with the macOS implementation and
updates to examples.

-- elias