From 51e3532c8c150ed4173a3f1c89aa4e2ce0fcd7b2 Mon Sep 17 00:00:00 2001 From: tbodt Date: Tue, 21 Jul 2026 19:27:25 -0500 Subject: [PATCH] feat: put status text in disabled menu item on macos Tooltips on menu bar icons are unexpected on macos, the idiomatic solution is disabled menu items. --- cmd/backrest/tray.go | 8 ++++++++ cmd/backrest/tray_status.go | 22 +++++++++++++--------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/cmd/backrest/tray.go b/cmd/backrest/tray.go index cca1b36c3..c6fbbca5b 100644 --- a/cmd/backrest/tray.go +++ b/cmd/backrest/tray.go @@ -23,10 +23,18 @@ func startTray() { systray.Run(func() { onReady(status) }, func() {}) } +var mStatusText *systray.MenuItem + func onReady(status *trayStatus) { systray.SetTooltip("Backrest") systray.SetIcon(icon) + if runtime.GOOS == "darwin" { + mStatusText = systray.AddMenuItem("", "") + mStatusText.Disable() + mStatusText.Hide() + } + mOpenUI := systray.AddMenuItem("Open WebUI", "Open the Backrest WebUI in your default browser") mOpenLog := systray.AddMenuItem("Open Log Dir", "Open the Backrest log directory") mQuit := systray.AddMenuItem("Quit", "Kills the backrest process and exits the tray app") diff --git a/cmd/backrest/tray_status.go b/cmd/backrest/tray_status.go index 6ab6d22a4..bd97544b5 100644 --- a/cmd/backrest/tray_status.go +++ b/cmd/backrest/tray_status.go @@ -72,11 +72,15 @@ func (t *trayStatus) refresh() { if log == nil { return } - state, tooltip := computeStatus(log) + state, message := computeStatus(log) if ic := statusIcon(state); ic != nil { systray.SetIcon(ic) } - systray.SetTooltip(tooltip) + systray.SetTooltip("Backrest — " + message) + if mStatusText != nil { + mStatusText.SetTitle(message) + mStatusText.Show() + } } // computeStatus returns the tray state and tooltip for the most recent backup. @@ -100,22 +104,22 @@ func computeStatus(log *oplog.OpLog) (trayState, string) { }) if last == nil { - return stateIdle, "Backrest — no backups yet" + return stateIdle, "No backups yet" } when := relativeTime(last.GetUnixTimeEndMs()) switch last.GetStatus() { case v1.OperationStatus_STATUS_INPROGRESS: - return stateRunning, "Backrest — backup in progress…" + return stateRunning, "Backup in progress…" case v1.OperationStatus_STATUS_SUCCESS: - return stateOK, "Backrest — last backup succeeded " + when + return stateOK, "Last backup succeeded " + when case v1.OperationStatus_STATUS_WARNING: - return stateWarning, "Backrest — last backup finished with warnings " + when + return stateWarning, "Last backup finished with warnings " + when case v1.OperationStatus_STATUS_ERROR, v1.OperationStatus_STATUS_SYSTEM_CANCELLED: - return stateError, "Backrest — last backup failed " + when + return stateError, "Last backup failed " + when case v1.OperationStatus_STATUS_USER_CANCELLED: - return stateIdle, "Backrest — last backup was cancelled " + when + return stateIdle, "Last backup was cancelled " + when default: - return stateIdle, "Backrest — no backups yet" + return stateIdle, "No backups yet" } }