[client][ui] added accessible tray icons (#3335)
Added accessible tray icons with: - dark mode support on Windows and Linux, kudos to @burgosz for the PoC - template icon support on MacOS Also added appropriate connecting status icons
@ -53,7 +53,7 @@ nfpms:
|
||||
contents:
|
||||
- src: client/ui/netbird.desktop
|
||||
dst: /usr/share/applications/netbird.desktop
|
||||
- src: client/ui/netbird-systemtray-connected.png
|
||||
- src: client/ui/netbird.png
|
||||
dst: /usr/share/pixmaps/netbird.png
|
||||
dependencies:
|
||||
- netbird
|
||||
@ -70,7 +70,7 @@ nfpms:
|
||||
contents:
|
||||
- src: client/ui/netbird.desktop
|
||||
dst: /usr/share/applications/netbird.desktop
|
||||
- src: client/ui/netbird-systemtray-connected.png
|
||||
- src: client/ui/netbird.png
|
||||
dst: /usr/share/pixmaps/netbird.png
|
||||
dependencies:
|
||||
- netbird
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/app"
|
||||
"fyne.io/fyne/v2/dialog"
|
||||
"fyne.io/fyne/v2/theme"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
"fyne.io/systray"
|
||||
"github.com/cenkalti/backoff/v4"
|
||||
@ -90,6 +91,14 @@ func main() {
|
||||
}
|
||||
|
||||
client := newServiceClient(daemonAddr, a, showSettings, showRoutes)
|
||||
settingsChangeChan := make(chan fyne.Settings)
|
||||
a.Settings().AddChangeListener(settingsChangeChan)
|
||||
go func() {
|
||||
for range settingsChangeChan {
|
||||
client.updateIcon()
|
||||
}
|
||||
}()
|
||||
|
||||
if showSettings || showRoutes {
|
||||
a.Run()
|
||||
} else {
|
||||
@ -106,46 +115,108 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
//go:embed netbird.ico
|
||||
var iconAboutICO []byte
|
||||
|
||||
//go:embed netbird.png
|
||||
var iconAboutPNG []byte
|
||||
|
||||
//go:embed netbird-systemtray-connected.ico
|
||||
var iconConnectedICO []byte
|
||||
|
||||
//go:embed netbird-systemtray-connected.png
|
||||
var iconConnectedPNG []byte
|
||||
|
||||
//go:embed netbird-systemtray-connected-macos.png
|
||||
var iconConnectedMacOS []byte
|
||||
|
||||
//go:embed netbird-systemtray-connected-dark.ico
|
||||
var iconConnectedDarkICO []byte
|
||||
|
||||
//go:embed netbird-systemtray-connected-dark.png
|
||||
var iconConnectedDarkPNG []byte
|
||||
|
||||
//go:embed netbird-systemtray-disconnected.ico
|
||||
var iconDisconnectedICO []byte
|
||||
|
||||
//go:embed netbird-systemtray-disconnected.png
|
||||
var iconDisconnectedPNG []byte
|
||||
|
||||
//go:embed netbird-systemtray-disconnected-macos.png
|
||||
var iconDisconnectedMacOS []byte
|
||||
|
||||
//go:embed netbird-systemtray-update-disconnected.ico
|
||||
var iconUpdateDisconnectedICO []byte
|
||||
|
||||
//go:embed netbird-systemtray-update-disconnected.png
|
||||
var iconUpdateDisconnectedPNG []byte
|
||||
|
||||
//go:embed netbird-systemtray-update-disconnected-macos.png
|
||||
var iconUpdateDisconnectedMacOS []byte
|
||||
|
||||
//go:embed netbird-systemtray-update-disconnected-dark.ico
|
||||
var iconUpdateDisconnectedDarkICO []byte
|
||||
|
||||
//go:embed netbird-systemtray-update-disconnected-dark.png
|
||||
var iconUpdateDisconnectedDarkPNG []byte
|
||||
|
||||
//go:embed netbird-systemtray-update-connected.ico
|
||||
var iconUpdateConnectedICO []byte
|
||||
|
||||
//go:embed netbird-systemtray-update-connected.png
|
||||
var iconUpdateConnectedPNG []byte
|
||||
|
||||
//go:embed netbird-systemtray-update-cloud.ico
|
||||
var iconUpdateCloudICO []byte
|
||||
//go:embed netbird-systemtray-update-connected-macos.png
|
||||
var iconUpdateConnectedMacOS []byte
|
||||
|
||||
//go:embed netbird-systemtray-update-cloud.png
|
||||
var iconUpdateCloudPNG []byte
|
||||
//go:embed netbird-systemtray-update-connected-dark.ico
|
||||
var iconUpdateConnectedDarkICO []byte
|
||||
|
||||
//go:embed netbird-systemtray-update-connected-dark.png
|
||||
var iconUpdateConnectedDarkPNG []byte
|
||||
|
||||
//go:embed netbird-systemtray-connecting.ico
|
||||
var iconConnectingICO []byte
|
||||
|
||||
//go:embed netbird-systemtray-connecting.png
|
||||
var iconConnectingPNG []byte
|
||||
|
||||
//go:embed netbird-systemtray-connecting-macos.png
|
||||
var iconConnectingMacOS []byte
|
||||
|
||||
//go:embed netbird-systemtray-connecting-dark.ico
|
||||
var iconConnectingDarkICO []byte
|
||||
|
||||
//go:embed netbird-systemtray-connecting-dark.png
|
||||
var iconConnectingDarkPNG []byte
|
||||
|
||||
//go:embed netbird-systemtray-error.ico
|
||||
var iconErrorICO []byte
|
||||
|
||||
//go:embed netbird-systemtray-error.png
|
||||
var iconErrorPNG []byte
|
||||
|
||||
//go:embed netbird-systemtray-error-macos.png
|
||||
var iconErrorMacOS []byte
|
||||
|
||||
//go:embed netbird-systemtray-error-dark.ico
|
||||
var iconErrorDarkICO []byte
|
||||
|
||||
//go:embed netbird-systemtray-error-dark.png
|
||||
var iconErrorDarkPNG []byte
|
||||
|
||||
type serviceClient struct {
|
||||
ctx context.Context
|
||||
addr string
|
||||
conn proto.DaemonServiceClient
|
||||
|
||||
icAbout []byte
|
||||
icConnected []byte
|
||||
icDisconnected []byte
|
||||
icUpdateConnected []byte
|
||||
icUpdateDisconnected []byte
|
||||
icUpdateCloud []byte
|
||||
icConnecting []byte
|
||||
icError []byte
|
||||
|
||||
// systray menu items
|
||||
mStatus *systray.MenuItem
|
||||
@ -214,20 +285,7 @@ func newServiceClient(addr string, a fyne.App, showSettings bool, showRoutes boo
|
||||
update: version.NewUpdate(),
|
||||
}
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
s.icConnected = iconConnectedICO
|
||||
s.icDisconnected = iconDisconnectedICO
|
||||
s.icUpdateConnected = iconUpdateConnectedICO
|
||||
s.icUpdateDisconnected = iconUpdateDisconnectedICO
|
||||
s.icUpdateCloud = iconUpdateCloudICO
|
||||
|
||||
} else {
|
||||
s.icConnected = iconConnectedPNG
|
||||
s.icDisconnected = iconDisconnectedPNG
|
||||
s.icUpdateConnected = iconUpdateConnectedPNG
|
||||
s.icUpdateDisconnected = iconUpdateDisconnectedPNG
|
||||
s.icUpdateCloud = iconUpdateCloudPNG
|
||||
}
|
||||
s.setNewIcons()
|
||||
|
||||
if showSettings {
|
||||
s.showSettingsUI()
|
||||
@ -239,6 +297,63 @@ func newServiceClient(addr string, a fyne.App, showSettings bool, showRoutes boo
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *serviceClient) setNewIcons() {
|
||||
if runtime.GOOS == "windows" {
|
||||
s.icAbout = iconAboutICO
|
||||
if s.app.Settings().ThemeVariant() == theme.VariantDark {
|
||||
s.icConnected = iconConnectedDarkICO
|
||||
s.icDisconnected = iconDisconnectedICO
|
||||
s.icUpdateConnected = iconUpdateConnectedDarkICO
|
||||
s.icUpdateDisconnected = iconUpdateDisconnectedDarkICO
|
||||
s.icConnecting = iconConnectingDarkICO
|
||||
s.icError = iconErrorDarkICO
|
||||
} else {
|
||||
s.icConnected = iconConnectedICO
|
||||
s.icDisconnected = iconDisconnectedICO
|
||||
s.icUpdateConnected = iconUpdateConnectedICO
|
||||
s.icUpdateDisconnected = iconUpdateDisconnectedICO
|
||||
s.icConnecting = iconConnectingICO
|
||||
s.icError = iconErrorICO
|
||||
}
|
||||
} else {
|
||||
s.icAbout = iconAboutPNG
|
||||
if s.app.Settings().ThemeVariant() == theme.VariantDark {
|
||||
s.icConnected = iconConnectedDarkPNG
|
||||
s.icDisconnected = iconDisconnectedPNG
|
||||
s.icUpdateConnected = iconUpdateConnectedDarkPNG
|
||||
s.icUpdateDisconnected = iconUpdateDisconnectedDarkPNG
|
||||
s.icConnecting = iconConnectingDarkPNG
|
||||
s.icError = iconErrorDarkPNG
|
||||
} else {
|
||||
s.icConnected = iconConnectedPNG
|
||||
s.icDisconnected = iconDisconnectedPNG
|
||||
s.icUpdateConnected = iconUpdateConnectedPNG
|
||||
s.icUpdateDisconnected = iconUpdateDisconnectedPNG
|
||||
s.icConnecting = iconConnectingPNG
|
||||
s.icError = iconErrorPNG
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *serviceClient) updateIcon() {
|
||||
s.setNewIcons()
|
||||
s.updateIndicationLock.Lock()
|
||||
if s.connected {
|
||||
if s.isUpdateIconActive {
|
||||
systray.SetTemplateIcon(iconUpdateConnectedMacOS, s.icUpdateConnected)
|
||||
} else {
|
||||
systray.SetTemplateIcon(iconConnectedMacOS, s.icConnected)
|
||||
}
|
||||
} else {
|
||||
if s.isUpdateIconActive {
|
||||
systray.SetTemplateIcon(iconUpdateDisconnectedMacOS, s.icUpdateDisconnected)
|
||||
} else {
|
||||
systray.SetTemplateIcon(iconDisconnectedMacOS, s.icDisconnected)
|
||||
}
|
||||
}
|
||||
s.updateIndicationLock.Unlock()
|
||||
}
|
||||
|
||||
func (s *serviceClient) showSettingsUI() {
|
||||
// add settings window UI elements.
|
||||
s.wSettings = s.app.NewWindow("NetBird Settings")
|
||||
@ -376,8 +491,10 @@ func (s *serviceClient) login() error {
|
||||
}
|
||||
|
||||
func (s *serviceClient) menuUpClick() error {
|
||||
systray.SetTemplateIcon(iconConnectingMacOS, s.icConnecting)
|
||||
conn, err := s.getSrvClient(defaultFailTimeout)
|
||||
if err != nil {
|
||||
systray.SetTemplateIcon(iconErrorMacOS, s.icError)
|
||||
log.Errorf("get client: %v", err)
|
||||
return err
|
||||
}
|
||||
@ -407,6 +524,7 @@ func (s *serviceClient) menuUpClick() error {
|
||||
}
|
||||
|
||||
func (s *serviceClient) menuDownClick() error {
|
||||
systray.SetTemplateIcon(iconConnectingMacOS, s.icConnecting)
|
||||
conn, err := s.getSrvClient(defaultFailTimeout)
|
||||
if err != nil {
|
||||
log.Errorf("get client: %v", err)
|
||||
@ -458,9 +576,9 @@ func (s *serviceClient) updateStatus() error {
|
||||
s.connected = true
|
||||
s.sendNotification = true
|
||||
if s.isUpdateIconActive {
|
||||
systray.SetIcon(s.icUpdateConnected)
|
||||
systray.SetTemplateIcon(iconUpdateConnectedMacOS, s.icUpdateConnected)
|
||||
} else {
|
||||
systray.SetIcon(s.icConnected)
|
||||
systray.SetTemplateIcon(iconConnectedMacOS, s.icConnected)
|
||||
}
|
||||
systray.SetTooltip("NetBird (Connected)")
|
||||
s.mStatus.SetTitle("Connected")
|
||||
@ -482,11 +600,9 @@ func (s *serviceClient) updateStatus() error {
|
||||
s.isUpdateIconActive = s.update.SetDaemonVersion(status.DaemonVersion)
|
||||
if !s.isUpdateIconActive {
|
||||
if systrayIconState {
|
||||
systray.SetIcon(s.icConnected)
|
||||
s.mAbout.SetIcon(s.icConnected)
|
||||
systray.SetTemplateIcon(iconConnectedMacOS, s.icConnected)
|
||||
} else {
|
||||
systray.SetIcon(s.icDisconnected)
|
||||
s.mAbout.SetIcon(s.icDisconnected)
|
||||
systray.SetTemplateIcon(iconDisconnectedMacOS, s.icDisconnected)
|
||||
}
|
||||
}
|
||||
|
||||
@ -517,9 +633,9 @@ func (s *serviceClient) updateStatus() error {
|
||||
func (s *serviceClient) setDisconnectedStatus() {
|
||||
s.connected = false
|
||||
if s.isUpdateIconActive {
|
||||
systray.SetIcon(s.icUpdateDisconnected)
|
||||
systray.SetTemplateIcon(iconUpdateDisconnectedMacOS, s.icUpdateDisconnected)
|
||||
} else {
|
||||
systray.SetIcon(s.icDisconnected)
|
||||
systray.SetTemplateIcon(iconDisconnectedMacOS, s.icDisconnected)
|
||||
}
|
||||
systray.SetTooltip("NetBird (Disconnected)")
|
||||
s.mStatus.SetTitle("Disconnected")
|
||||
@ -529,7 +645,7 @@ func (s *serviceClient) setDisconnectedStatus() {
|
||||
}
|
||||
|
||||
func (s *serviceClient) onTrayReady() {
|
||||
systray.SetIcon(s.icDisconnected)
|
||||
systray.SetTemplateIcon(iconDisconnectedMacOS, s.icDisconnected)
|
||||
systray.SetTooltip("NetBird")
|
||||
|
||||
// setup systray menu items
|
||||
@ -554,7 +670,7 @@ func (s *serviceClient) onTrayReady() {
|
||||
systray.AddSeparator()
|
||||
|
||||
s.mAbout = systray.AddMenuItem("About", "About")
|
||||
s.mAbout.SetIcon(s.icDisconnected)
|
||||
s.mAbout.SetIcon(s.icAbout)
|
||||
versionString := normalizedVersion(version.NetbirdVersion())
|
||||
s.mVersionUI = s.mAbout.AddSubMenuItem(fmt.Sprintf("GUI: %s", versionString), fmt.Sprintf("GUI Version: %s", versionString))
|
||||
s.mVersionUI.Disable()
|
||||
@ -771,9 +887,9 @@ func (s *serviceClient) onUpdateAvailable() {
|
||||
s.isUpdateIconActive = true
|
||||
|
||||
if s.connected {
|
||||
systray.SetIcon(s.icUpdateConnected)
|
||||
systray.SetTemplateIcon(iconUpdateConnectedMacOS, s.icUpdateConnected)
|
||||
} else {
|
||||
systray.SetIcon(s.icUpdateDisconnected)
|
||||
systray.SetTemplateIcon(iconUpdateDisconnectedMacOS, s.icUpdateDisconnected)
|
||||
}
|
||||
}
|
||||
|
||||
|
BIN
client/ui/netbird-systemtray-connected-dark.ico
Normal file
After Width: | Height: | Size: 103 KiB |
BIN
client/ui/netbird-systemtray-connected-dark.png
Normal file
After Width: | Height: | Size: 5.1 KiB |
BIN
client/ui/netbird-systemtray-connected-macos.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 103 KiB |
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 5.2 KiB |
BIN
client/ui/netbird-systemtray-connecting-dark.ico
Normal file
After Width: | Height: | Size: 103 KiB |
BIN
client/ui/netbird-systemtray-connecting-dark.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
client/ui/netbird-systemtray-connecting-macos.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
client/ui/netbird-systemtray-connecting.ico
Normal file
After Width: | Height: | Size: 103 KiB |
BIN
client/ui/netbird-systemtray-connecting.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
client/ui/netbird-systemtray-disconnected-macos.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 102 KiB |
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 4.7 KiB |
BIN
client/ui/netbird-systemtray-error-dark.ico
Normal file
After Width: | Height: | Size: 103 KiB |
BIN
client/ui/netbird-systemtray-error-dark.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
client/ui/netbird-systemtray-error-macos.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
client/ui/netbird-systemtray-error.ico
Normal file
After Width: | Height: | Size: 103 KiB |
BIN
client/ui/netbird-systemtray-error.png
Normal file
After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 5.5 KiB |
BIN
client/ui/netbird-systemtray-update-connected-dark.ico
Normal file
After Width: | Height: | Size: 102 KiB |
BIN
client/ui/netbird-systemtray-update-connected-dark.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
client/ui/netbird-systemtray-update-connected-macos.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 102 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 4.7 KiB |
BIN
client/ui/netbird-systemtray-update-disconnected-dark.ico
Normal file
After Width: | Height: | Size: 103 KiB |
BIN
client/ui/netbird-systemtray-update-disconnected-dark.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
client/ui/netbird-systemtray-update-disconnected-macos.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 103 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 5.2 KiB |
BIN
client/ui/netbird.png
Normal file
After Width: | Height: | Size: 4.7 KiB |