ui/app: create windows directly

Replace CreateWindow with NewWindow that immediately creates a Window
ready to use.

Drop the Windows channel of windows created by the system. For iOS
and Android where the system creates the windows, let them rendezvous
with the window created in the first NewWindow call.

Android is further changed so that destroying and re-creating the
Java Activity simply reconnects with the original Window.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2019-07-12 19:21:02 +02:00
parent 46cee54dd6
commit a3b9c7818f
8 changed files with 116 additions and 79 deletions
+37 -6
View File
@@ -13,8 +13,8 @@ import (
"gioui.org/ui/app/internal/gpu"
iinput "gioui.org/ui/app/internal/input"
"gioui.org/ui/input"
"gioui.org/ui/system"
"gioui.org/ui/key"
"gioui.org/ui/system"
)
type WindowOptions struct {
@@ -47,6 +47,12 @@ type Window struct {
router iinput.Router
}
// driverEvent is sent when a new native driver
// is available for the Window.
type driverEvent struct {
driver *window
}
// driver is the interface for the platform implementation
// of a Window.
var _ interface {
@@ -59,13 +65,31 @@ var _ interface {
var ackEvent Event
func newWindow(nw *window) *Window {
// NewWindow creates a new window for a set of window
// options. The options are hints; the platform is free to
// ignore or adjust them.
// If the current program is running on iOS and Android,
// NewWindow returns the window previously by the platform.
func NewWindow(opts *WindowOptions) (*Window, error) {
if opts == nil {
opts = &WindowOptions{
Width: ui.Dp(800),
Height: ui.Dp(600),
Title: "Gio program",
}
}
if opts.Width.V <= 0 || opts.Height.V <= 0 {
panic("window width and height must be larger than 0")
}
w := &Window{
driver: nw,
events: make(chan Event),
stage: StagePaused,
}
return w
if err := createWindow(w, opts); err != nil {
return nil, err
}
return w, nil
}
func (w *Window) Events() <-chan Event {
@@ -103,8 +127,9 @@ func (w *Window) Draw(root *ui.Ops) {
w.syncGPU = false
alive := w.isAlive()
size := w.size
driver := w.driver
w.mu.Unlock()
if !alive || stage < StageRunning {
if !alive || stage < StageRunning || driver == nil {
return
}
if w.gpu != nil {
@@ -117,7 +142,7 @@ func (w *Window) Draw(root *ui.Ops) {
}
}
if w.gpu == nil {
ctx, err := newContext(w.driver)
ctx, err := newContext(driver)
if err != nil {
w.err = err
return
@@ -205,6 +230,12 @@ func (w *Window) contextDriver() interface{} {
return w.driver
}
func (w *Window) setDriver(d *window) {
w.mu.Lock()
defer w.mu.Unlock()
w.driver = d
}
func (w *Window) event(e Event) {
w.eventLock.Lock()
defer w.eventLock.Unlock()