Reputation: 65
I am using GoLang fyne and systray to develop a UI application on Windows 11. I want the core of the application to be a system tray app that will pop open a GoLang fyne window when the user clicks on it.
It is mostly working, except when the app opens the fyne window and I click on the red 'x' to close the window, the entire application crashes with the following error. I have tried recreating the app in a loop at the bottom of main, however that results in a 'GLFW not initialized' error.
How can I keep the systray overarching application running, while allowing the user to open and close the fyne windows at will? Thanks.
Error:
panic: close of closed channel
goroutine 1 [running, locked to thread]:
fyne.io/fyne/v2/internal/driver/glfw.(*gLDriver).runGL(0x7ff756905917?)
C:/Users/asdf/go/pkg/mod/fyne.io/fyne/[email protected]/internal/driver/glfw/loop.go:111 +0x4e
fyne.io/fyne/v2/internal/driver/glfw.(*gLDriver).Run(0xc00030c0d0)
C:/Users/asdf/go/pkg/mod/fyne.io/fyne/[email protected]/internal/driver/glfw/driver.go:164 +0x73
fyne.io/fyne/v2/app.(*fyneApp).Run(0xc000328000)
C:/Users/asdf/go/pkg/mod/fyne.io/fyne/[email protected]/app/app.go:68 +0x65
main.main()
Code:
package main
import (
icon "company/winres"
"fmt"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/widget"
"github.com/getlantern/systray"
"github.com/k0kubun/pp/v3"
)
// Create a channel to communicate between goroutines for launching windows
var ch = make(chan string)
// Define the top level app
var mainApp fyne.App
func main() {
// Create a struct describing your scheme
scheme := pp.ColorScheme{
Integer: pp.Yellow | pp.Bold,
String: pp.Green | pp.BackgroundBlack | pp.Bold,
StringQuotation: pp.Green | pp.BackgroundBlack | pp.Bold,
}
// Register it for usage
pp.Default.SetColorScheme(scheme)
// Print startup message
pp.Println("Starting Application now ...")
// Run the system tray application
systray.Register(onReady, onExit)
// Define the main application and initial window
pp.Println("Creating app and window")
mainApp = app.New()
window := mainApp.NewWindow("Backup Information")
window.Resize(fyne.NewSize(256, 256))
yes := widget.NewButton("Yes", closeCallback)
yes.Importance = widget.HighImportance
window.SetContent(container.NewVBox(
widget.NewLabel("Are you sure you want to interact with this test dialog?"),
container.NewHBox(layout.NewSpacer(),
widget.NewButton("No", closeCallback), yes,
layout.NewSpacer())))
// Process commuication from tray inputs
go func() {
for {
// Main goroutine waits for a message from the background goroutine
msg := <-ch
fmt.Println(msg)
// Show the window
window.Show()
}
}()
// Wait for taskbar inputs
for {
// Run the fyne app
pp.Println("Running now ...")
mainApp.Run()
pp.Println("Done running ...")
}
}
func closeCallback() {
mainApp.Quit()
}
func onReady() {
// Setup the tray icons
systray.SetIcon(icon.Data)
systray.SetTemplateIcon(icon.Data, icon.Data)
systray.SetTitle("asdf")
// Define actions
mInformation := systray.AddMenuItem("Info", "Information")
mBackupNow := systray.AddMenuItem("Now", "Immediately start")
mQuit := systray.AddMenuItem("Quit", "Quit")
// Handle actions
go func() {
for {
select {
case <-mInformation.ClickedCh:
pp.Println("User chose to view information")
ch <- "Hello from background goroutine"
case <-mBackupNow.ClickedCh:
pp.Println("User chose to start backup")
case <-mQuit.ClickedCh:
systray.Quit()
}
}
}()
}
func onExit() {
pp.Println("Exiting now ...")
}
Upvotes: 1
Views: 230
Reputation: 56
You can use "SetCloseIntercept" event to hide the window when the user tries to close it.
window.SetCloseIntercept(func() {
window.Hide()
})
Upvotes: 0
Reputation: 11
Don’t Run and Quit the app multiple times, just call “Run()” at the end of your main…
That way the app will run through window show and hide and only exit when you quit it.
P.s. life will be easier if you use the Fyne abstraction for systray instead of interacting with that library directly (you are multiplexing multiple run loops).
Good example at https://docs.fyne.io/explore/systray
Upvotes: 0