forked from joejulian/gio
18c2ba8e20
Unlike Raise, Close and other fire-and-forget methods on Window, Config calls driverRun because it needs to wait for the result. However, driverRun isn't guaranteed to block in all contexts. This change avoids the synchronization dance altogether by removing the Config method and introducing a ConfigEvent event. The event also makes it clear when the configuration changes. Signed-off-by: Elias Naur <mail@eliasnaur.com>
194 lines
4.2 KiB
Go
194 lines
4.2 KiB
Go
// SPDX-License-Identifier: Unlicense OR MIT
|
|
|
|
// package app implements platform specific windows
|
|
// and GPU contexts.
|
|
package app
|
|
|
|
import (
|
|
"errors"
|
|
"image"
|
|
"image/color"
|
|
|
|
"gioui.org/io/key"
|
|
|
|
"gioui.org/gpu"
|
|
"gioui.org/io/pointer"
|
|
"gioui.org/io/system"
|
|
"gioui.org/unit"
|
|
)
|
|
|
|
type size struct {
|
|
Width unit.Value
|
|
Height unit.Value
|
|
}
|
|
|
|
// Config describes a Window configuration.
|
|
type Config struct {
|
|
// Size is the window dimensions (Width, Height).
|
|
Size image.Point
|
|
// MaxSize is the window maximum allowed dimensions.
|
|
MaxSize image.Point
|
|
// MinSize is the window minimum allowed dimensions.
|
|
MinSize image.Point
|
|
// Title is the window title displayed in its decoration bar.
|
|
Title string
|
|
// WindowMode is the window mode.
|
|
Mode WindowMode
|
|
// StatusColor is the color of the Android status bar.
|
|
StatusColor color.NRGBA
|
|
// NavigationColor is the color of the navigation bar
|
|
// on Android, or the address bar in browsers.
|
|
NavigationColor color.NRGBA
|
|
// Orientation is the current window orientation.
|
|
Orientation Orientation
|
|
// CustomRenderer is true when the window content is rendered by the
|
|
// client.
|
|
CustomRenderer bool
|
|
}
|
|
|
|
// ConfigEvent is sent whenever the configuration of a Window changes.
|
|
type ConfigEvent struct {
|
|
Config Config
|
|
}
|
|
|
|
func (c *Config) apply(m unit.Metric, options []Option) {
|
|
for _, o := range options {
|
|
o(m, c)
|
|
}
|
|
}
|
|
|
|
type wakeupEvent struct{}
|
|
|
|
// WindowMode is the window mode (WindowMode.Option sets it).
|
|
//
|
|
// Supported platforms are macOS, X11, Windows, Android and JS.
|
|
type WindowMode uint8
|
|
|
|
const (
|
|
// Windowed is the normal window mode with OS specific window decorations.
|
|
Windowed WindowMode = iota
|
|
// Fullscreen is the full screen window mode.
|
|
Fullscreen
|
|
)
|
|
|
|
func (m WindowMode) Option() Option {
|
|
return func(_ unit.Metric, cnf *Config) {
|
|
cnf.Mode = m
|
|
}
|
|
}
|
|
|
|
// Orientation is the orientation of the app (Orientation.Option sets it).
|
|
//
|
|
// Supported platforms are Android and JS.
|
|
type Orientation uint8
|
|
|
|
const (
|
|
// AnyOrientation allows the window to be freely orientated.
|
|
AnyOrientation Orientation = iota
|
|
// LandscapeOrientation constrains the window to landscape orientations.
|
|
LandscapeOrientation
|
|
// PortraitOrientation constrains the window to portrait orientations.
|
|
PortraitOrientation
|
|
)
|
|
|
|
func (o Orientation) Option() Option {
|
|
return func(_ unit.Metric, cnf *Config) {
|
|
cnf.Orientation = o
|
|
}
|
|
}
|
|
|
|
type frameEvent struct {
|
|
system.FrameEvent
|
|
|
|
Sync bool
|
|
}
|
|
|
|
type context interface {
|
|
API() gpu.API
|
|
RenderTarget() gpu.RenderTarget
|
|
Present() error
|
|
Refresh() error
|
|
Release()
|
|
Lock() error
|
|
Unlock()
|
|
}
|
|
|
|
// errDeviceLost is returned from Context.Present when
|
|
// the underlying GPU device is gone and should be
|
|
// recreated.
|
|
var errDeviceLost = errors.New("GPU device lost")
|
|
|
|
// Driver is the interface for the platform implementation
|
|
// of a window.
|
|
type driver interface {
|
|
// SetAnimating sets the animation flag. When the window is animating,
|
|
// FrameEvents are delivered as fast as the display can handle them.
|
|
SetAnimating(anim bool)
|
|
|
|
// ShowTextInput updates the virtual keyboard state.
|
|
ShowTextInput(show bool)
|
|
|
|
SetInputHint(mode key.InputHint)
|
|
|
|
NewContext() (context, error)
|
|
|
|
// ReadClipboard requests the clipboard content.
|
|
ReadClipboard()
|
|
// WriteClipboard requests a clipboard write.
|
|
WriteClipboard(s string)
|
|
|
|
// Configure the window.
|
|
Configure([]Option)
|
|
|
|
// SetCursor updates the current cursor to name.
|
|
SetCursor(name pointer.CursorName)
|
|
|
|
// Raise the window at the top.
|
|
Raise()
|
|
|
|
// Close the window.
|
|
Close()
|
|
// Wakeup wakes up the event loop and sends a WakeupEvent.
|
|
Wakeup()
|
|
}
|
|
|
|
type windowRendezvous struct {
|
|
in chan windowAndConfig
|
|
out chan windowAndConfig
|
|
errs chan error
|
|
}
|
|
|
|
type windowAndConfig struct {
|
|
window *callbacks
|
|
options []Option
|
|
}
|
|
|
|
func newWindowRendezvous() *windowRendezvous {
|
|
wr := &windowRendezvous{
|
|
in: make(chan windowAndConfig),
|
|
out: make(chan windowAndConfig),
|
|
errs: make(chan error),
|
|
}
|
|
go func() {
|
|
var main windowAndConfig
|
|
var out chan windowAndConfig
|
|
for {
|
|
select {
|
|
case w := <-wr.in:
|
|
var err error
|
|
if main.window != nil {
|
|
err = errors.New("multiple windows are not supported")
|
|
}
|
|
wr.errs <- err
|
|
main = w
|
|
out = wr.out
|
|
case out <- main:
|
|
}
|
|
}
|
|
}()
|
|
return wr
|
|
}
|
|
|
|
func (wakeupEvent) ImplementsEvent() {}
|
|
func (ConfigEvent) ImplementsEvent() {}
|