//go:build kanholec_gui package gui import ( "fyne.io/fyne/v2" "fyne.io/systray" ) type TrayManager struct { app *App running bool mShow *systray.MenuItem mStatus *systray.MenuItem mStart *systray.MenuItem mStop *systray.MenuItem mQuit *systray.MenuItem } func NewTrayManager(app *App) *TrayManager { return &TrayManager{app: app} } func (t *TrayManager) Start() { go t.run() } func (t *TrayManager) run() { defer func() { recover() }() systray.Run(t.onReady, t.onExit) } func (t *TrayManager) onReady() { t.running = true systray.SetIcon(trayIconData()) systray.SetTitle("kanholec") systray.SetTooltip("kanholec - kanhole Client") t.mShow = systray.AddMenuItem("Show Dashboard", "Open kanholec GUI") systray.AddSeparator() t.mStatus = systray.AddMenuItem("Status: Disconnected", "") t.mStatus.Disable() systray.AddSeparator() t.mStart = systray.AddMenuItem("Start Client", "Start the kanholec client") t.mStop = systray.AddMenuItem("Stop Client", "Stop the kanholec client") t.mStop.Disable() systray.AddSeparator() t.mQuit = systray.AddMenuItem("Quit", "Exit kanholec") go func() { for { select { case <-t.mShow.ClickedCh: if t.app.window != nil { t.app.window.Show() t.app.window.RequestFocus() } case <-t.mStart.ClickedCh: t.app.startClient() t.mStart.Disable() t.mStop.Enable() t.mStatus.SetTitle("Status: Running") case <-t.mStop.ClickedCh: t.app.stopClient() t.mStart.Enable() t.mStop.Disable() t.mStatus.SetTitle("Status: Stopped") case <-t.mQuit.ClickedCh: t.app.Quit() systray.Quit() return } } }() } func (t *TrayManager) onExit() { t.running = false } func (t *TrayManager) SetStatus(status string) { if !t.running || t.mStatus == nil { return } t.mStatus.SetTitle("Status: " + status) } func (t *TrayManager) SetRunning(running bool) { if !t.running { return } if running { t.mStart.Disable() t.mStop.Enable() t.mStatus.SetTitle("Status: Running") } else { t.mStart.Enable() t.mStop.Disable() t.mStatus.SetTitle("Status: Stopped") } } func (t *TrayManager) Stop() { if t.running { systray.Quit() } } func (t *TrayManager) IsSupported() bool { return t.running } func trayIconResource() *fyne.StaticResource { return &fyne.StaticResource{ StaticName: "kanholec.ico", StaticContent: trayIconData(), } } func trayIconData() []byte { return []byte{ 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x10, 0x10, 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x68, 0x04, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, } }