//go:build windows package platform import ( _ "embed" "runtime" "fyne.io/systray" ) // trayIconICO is the brand mascot as a Windows .ico, embedded in the binary and // shown in the notification area. // //go:embed tray-icon.ico var trayIconICO []byte // InstallStatusBar installs the Windows system-tray icon, mirroring the macOS // menu bar: left-click (primary tap) opens the main window, right-click shows // the Show / Settings / Quit menu. systray owns a Win32 message loop, so it runs // on its own OS-locked goroutine; the menu-item click channels are drained in a // second goroutine. The handler closures already hand work to a goroutine before // touching the Wails runtime, so invoking them from here is safe. func InstallStatusBar(m StatusBarMenu, h StatusBarHandler) { statusBarHandler = h go func() { // systray creates a window + GetMessage loop on this thread; the window // is thread-affine, so the goroutine must not migrate. runtime.LockOSThread() systray.Run(func() { trayOnReady(m) }, nil) }() } func trayOnReady(m StatusBarMenu) { systray.SetIcon(trayIconICO) systray.SetTitle(m.Title) systray.SetTooltip(m.Title) // Left-click → open the main window (matches the macOS convention). Right- // click falls through to the menu below (Windows default). systray.SetOnTapped(func() { if statusBarHandler.OnShowWindow != nil { statusBarHandler.OnShowWindow() } }) show := systray.AddMenuItem(m.Show, "") settings := systray.AddMenuItem(m.Settings, "") quit := systray.AddMenuItem(m.Quit, "") go func() { for { select { case <-show.ClickedCh: if statusBarHandler.OnShowWindow != nil { statusBarHandler.OnShowWindow() } case <-settings.ClickedCh: if statusBarHandler.OnOpenSettings != nil { statusBarHandler.OnOpenSettings() } case <-quit.ClickedCh: if statusBarHandler.OnQuit != nil { statusBarHandler.OnQuit() } } } }() } // SetDockVisible is a no-op on Windows: the app lifecycle already hides/shows the // window (Wails WindowHide/WindowShow), which removes/adds the taskbar button, so // there is no separate Dock-style activation policy to toggle. func SetDockVisible(_ bool) {}