package main import ( "context" "github.com/getlantern/systray" ) // Feature is a self-contained tray capability. It owns its menu items, // background loops, and mutable state. Adding a feature means implementing // this interface and registering it in app.go's feature list — the app's // event loop itself never changes. type Feature interface { // Name identifies the feature (ordering and logging). Name() string // Install creates this feature's tray menu items. It is called exactly // once, from the systray onReady goroutine, before Run. Install(m *Menu) // Run starts the feature's background work. It returns when the feature // shuts down: either Stop is called, or ctx is cancelled at app exit. Run(ctx context.Context) // Stop requests shutdown and releases resources (goroutines, child // processes). It must be safe to call multiple times and before Run. Stop() } // Menu is a thin wrapper over the systray package so features never import // systray directly. It centralizes menu construction behind one seam. type Menu struct{} // Item is a handle to one tray menu entry. type Item struct { mi *systray.MenuItem Clicked chan struct{} } // AddItem creates a clickable menu entry. func (Menu) AddItem(title, tooltip string) *Item { mi := systray.AddMenuItem(title, tooltip) return &Item{mi: mi, Clicked: mi.ClickedCh} } // AddSeparator inserts a menu divider. func (Menu) AddSeparator() { systray.AddSeparator() } // SetTitle updates the item's visible label. func (it *Item) SetTitle(t string) { it.mi.SetTitle(t) } // SetTooltip updates the item's hover text. func (it *Item) SetTooltip(t string) { it.mi.SetTooltip(t) } // Disable greys the item out. func (it *Item) Disable() { it.mi.Disable() } // Enable makes a disabled item clickable again. func (it *Item) Enable() { it.mi.Enable() } // setTrayTitle / setTrayTooltip / quitTray are package-level systray shims so // features can update the tray icon state without importing systray directly. func setTrayTitle(t string) { systray.SetTitle(t) } func setTrayTooltip(t string) { systray.SetTooltip(t) } func quitTray() { systray.Quit() }