mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 23:55:39 +00:00
8611894b4b
app.Window implements a method for safely running functions against the underlying native window through the driverFuncs channel. However, the functions still run in a different goroutine than the one driving the native event loop, which forces the implementations in package wm to do complicated synchronization. A previous change added a mechanism to run functions in the native event loop thread. The macOS port needed this functionality, but with some care it can be generalized. That's what this change does through the new Run method. The advantage is that the thread switch dance is now confined to app.Window, with the help of a generic wm.Driver.Wakeup method. All other Driver methods can then assume they run on their event loop threads. Run is exported because it is also needed for programs that use Windows configured with CustomRenderer to control their own rendering. Signed-off-by: Elias Naur <mail@eliasnaur.com>
146 lines
2.8 KiB
Go
146 lines
2.8 KiB
Go
// SPDX-License-Identifier: Unlicense OR MIT
|
|
|
|
// package wm implements platform specific windows
|
|
// and GPU contexts.
|
|
package wm
|
|
|
|
import (
|
|
"errors"
|
|
"image/color"
|
|
|
|
"gioui.org/gpu"
|
|
"gioui.org/io/event"
|
|
"gioui.org/io/pointer"
|
|
"gioui.org/io/system"
|
|
"gioui.org/unit"
|
|
)
|
|
|
|
type Size struct {
|
|
Width unit.Value
|
|
Height unit.Value
|
|
}
|
|
|
|
type Options struct {
|
|
Size *Size
|
|
MinSize *Size
|
|
MaxSize *Size
|
|
Title *string
|
|
WindowMode *WindowMode
|
|
StatusColor *color.NRGBA
|
|
NavigationColor *color.NRGBA
|
|
Orientation *Orientation
|
|
CustomRenderer bool
|
|
}
|
|
|
|
type WakeupEvent struct{}
|
|
|
|
type WindowMode uint8
|
|
|
|
const (
|
|
Windowed WindowMode = iota
|
|
Fullscreen
|
|
)
|
|
|
|
type Orientation uint8
|
|
|
|
const (
|
|
AnyOrientation Orientation = iota
|
|
LandscapeOrientation
|
|
PortraitOrientation
|
|
)
|
|
|
|
type FrameEvent struct {
|
|
system.FrameEvent
|
|
|
|
Sync bool
|
|
}
|
|
|
|
type Callbacks interface {
|
|
SetDriver(d Driver)
|
|
Event(e event.Event)
|
|
// Func runs a function during an Event. This is required for platforms
|
|
// that require coordination between the rendering goroutine and the system
|
|
// main thread.
|
|
Run(f func())
|
|
}
|
|
|
|
type Context interface {
|
|
API() gpu.API
|
|
Present() error
|
|
MakeCurrent() error
|
|
Release()
|
|
Lock()
|
|
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)
|
|
NewContext() (Context, error)
|
|
|
|
// ReadClipboard requests the clipboard content.
|
|
ReadClipboard()
|
|
// WriteClipboard requests a clipboard write.
|
|
WriteClipboard(s string)
|
|
|
|
// Option processes option changes.
|
|
Option(opts *Options)
|
|
|
|
// SetCursor updates the current cursor to name.
|
|
SetCursor(name pointer.CursorName)
|
|
|
|
// Close the window.
|
|
Close()
|
|
// Wakeup wakes up the event loop and sends a WakeupEvent.
|
|
Wakeup()
|
|
}
|
|
|
|
type windowRendezvous struct {
|
|
in chan windowAndOptions
|
|
out chan windowAndOptions
|
|
errs chan error
|
|
}
|
|
|
|
type windowAndOptions struct {
|
|
window Callbacks
|
|
opts *Options
|
|
}
|
|
|
|
func newWindowRendezvous() *windowRendezvous {
|
|
wr := &windowRendezvous{
|
|
in: make(chan windowAndOptions),
|
|
out: make(chan windowAndOptions),
|
|
errs: make(chan error),
|
|
}
|
|
go func() {
|
|
var main windowAndOptions
|
|
var out chan windowAndOptions
|
|
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() {}
|