package main import ( _ "embed" "fmt" "log" "os" "os/exec" "runtime" "strings" "time" "fyne.io/systray" ) //go:embed icon.png var iconBytes []byte const uiURL = "http://localhost:7070" func runTray(appName string, shutdownCh chan struct{}) { systray.Run(func() { onTrayReady(appName, shutdownCh) }, func() { onTrayExit(shutdownCh) }) } func onTrayReady(appName string, shutdownCh chan struct{}) { systray.SetIcon(iconBytes) systray.SetTitle(appName) systray.SetTooltip(fmt.Sprintf("%s Agent - Cliquez pour ouvrir l'interface", appName)) mOpen := systray.AddMenuItem("Ouvrir l'interface", "Ouvrir l'interface web locale") mInstances := systray.AddMenuItem("Mes instances", "Afficher les instances") mSettings := systray.AddMenuItem("Paramètres", "Ouvrir les paramètres") systray.AddSeparator() mQuit := systray.AddMenuItem("Quitter", "Arrêter l'agent") go func() { for { select { case <-mOpen.ClickedCh: openBrowser(uiURL) case <-mInstances.ClickedCh: openBrowser(uiURL + "#instances") case <-mSettings.ClickedCh: openBrowser(uiURL + "#settings") case <-mQuit.ClickedCh: close(shutdownCh) systray.Quit() return } } }() } func onTrayExit(shutdownCh chan struct{}) { log.Printf("Tray exit requested") // If the user did not already trigger shutdown via the menu, signal it now. select { case <-shutdownCh: default: close(shutdownCh) } // Give other goroutines a moment to clean up, then exit. time.Sleep(200 * time.Millisecond) os.Exit(0) } func openBrowser(url string) { var cmd string var args []string switch runtime.GOOS { case "windows": cmd = "rundll32" args = []string{"url.dll,FileProtocolHandler", url} case "darwin": cmd = "open" args = []string{url} default: cmd = "xdg-open" args = []string{url} } openCmd := exec.Command(cmd, args...) hideWindow(openCmd) if err := openCmd.Start(); err != nil { log.Printf("Failed to open browser: %v", err) } } func normalizeName(name string) string { return strings.ReplaceAll(name, " ", "") }