75 lines
1.8 KiB
Go
75 lines
1.8 KiB
Go
// Package tray owns the native tray menu wiring for the desktop shell.
|
|
package tray
|
|
|
|
import "sync"
|
|
|
|
// MenuItem exposes click events from a native tray menu item.
|
|
type MenuItem interface {
|
|
Clicked() <-chan struct{}
|
|
}
|
|
|
|
// Backend is the platform tray implementation.
|
|
type Backend interface {
|
|
Register(onReady func(), onExit func())
|
|
SetIcon(icon []byte)
|
|
SetTooltip(tooltip string)
|
|
AddMenuItem(title, tooltip string) MenuItem
|
|
Quit()
|
|
}
|
|
|
|
// Actions are executed from the native tray menu.
|
|
type Actions struct {
|
|
Show func()
|
|
Quit func()
|
|
}
|
|
|
|
// Controller initializes one native tray and routes its menu actions.
|
|
type Controller struct {
|
|
backend Backend
|
|
icon []byte
|
|
start sync.Once
|
|
}
|
|
|
|
// New creates a tray controller for one application process.
|
|
func New(backend Backend, icon []byte) *Controller {
|
|
return &Controller{
|
|
backend: backend,
|
|
icon: append([]byte(nil), icon...),
|
|
}
|
|
}
|
|
|
|
// Start registers the native tray without taking over the Wails event loop.
|
|
func (c *Controller) Start(actions Actions) {
|
|
if c == nil || c.backend == nil {
|
|
return
|
|
}
|
|
c.start.Do(func() {
|
|
c.backend.Register(func() {
|
|
c.backend.SetIcon(c.icon)
|
|
c.backend.SetTooltip("Verstak")
|
|
show := c.backend.AddMenuItem("Show Verstak", "Show the Verstak window")
|
|
quit := c.backend.AddMenuItem("Quit", "Quit Verstak")
|
|
if actions.Show != nil && show != nil {
|
|
go routeClicks(show.Clicked(), actions.Show)
|
|
}
|
|
if actions.Quit != nil && quit != nil {
|
|
go routeClicks(quit.Clicked(), actions.Quit)
|
|
}
|
|
}, nil)
|
|
})
|
|
}
|
|
|
|
// Stop releases the native tray after Wails has begun application shutdown.
|
|
func (c *Controller) Stop() {
|
|
if c == nil || c.backend == nil {
|
|
return
|
|
}
|
|
c.backend.Quit()
|
|
}
|
|
|
|
func routeClicks(clicked <-chan struct{}, action func()) {
|
|
for range clicked {
|
|
action()
|
|
}
|
|
}
|