System Tray Menu
Adding a System Tray menu
Since the v2.2.0 release Fyne has built in support for a system tray menu. This feature displays an icon on macOS, Windows and Linux computers and when tapped will pop out a menu as specified by the app.
As this is a desktop specific feature we must first do a runtime check that the app is running in desktop mode. To do this, and get a reference to the desktop features, we do a Go type assertion:
if desk, ok := a.(desktop.App); ok {
...
}
If the ok
variable is true then we can set up a menu using the standard
Fyne menu API that you might have used in Window.SetMainMenu
before.
m := fyne.NewMenu("MyApp",
fyne.NewMenuItem("Show", func() {
log.Println("Tapped show")
}))
desk.SetSystemTrayMenu(m)
With this code added to the setup of your application you can run the app and see that it shows a Fyne icon in the system tray. When you tap it a menu will appear containing “Show” and “Quit”.
The default icon is the Fyne logo, you can either fix this using app metadata
or by setting the app icon in App.SetIcon
or for system tray directly
using desk.SetSystemTrayIcon
.
Manage window lifecycle
By default a Fyne app will exit when you close all windows and this may not be
what you want with a system tray app. To override the behaviour you can use
the Window.SetCloseIntercept
feature to override what happens when a window is
closed. In the example below we hide the window instead of closing it by calling
Window.Hide()
. Add this before you show the window for the first time.
w.SetCloseIntercept(func() {
w.Hide()
})
The benefit of hiding a window is that you can simply show it again using
Window.Show()
which is much more efficient than creating a new window if the
same content is needed a second time.
We update the menu created earlier to show the window that was hidden above.
fyne.NewMenuItem("Show", func() {
w.Show()
})
Complete app
That’s all there is to setting up a system tray menu with Fyne! The complete code for this tutorial is as follows.
package main
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/driver/desktop"
"fyne.io/fyne/v2/widget"
)
func main() {
a := app.New()
w := a.NewWindow("SysTray")
if desk, ok := a.(desktop.App); ok {
m := fyne.NewMenu("MyApp",
fyne.NewMenuItem("Show", func() {
w.Show()
}))
desk.SetSystemTrayMenu(m)
}
w.SetContent(widget.NewLabel("Fyne System Tray"))
w.SetCloseIntercept(func() {
w.Hide()
})
w.ShowAndRun()
}