[client] Hold menuMu across tray item setters

This commit is contained in:
Zoltán Papp
2026-07-28 16:25:52 +02:00
parent 29b97340d6
commit 4b915e4a5a
2 changed files with 10 additions and 13 deletions

View File

@@ -67,8 +67,8 @@ type Tray struct {
loc *Localizer
// menu and the *Item/*Submenu fields below are reassigned by buildMenu
// on every relayout (which destroys the replaced tree)touch them only
// with menuMu held; snapshot under the lock, then call the item.
// on every relayout, which destroys the replaced tree — locate items and
// call them with menuMu held, so a relayout can't destroy one mid-call.
menu *application.Menu
statusItem *application.MenuItem
// sessionExpiresItem shows the SSO deadline as a remaining-time label,
@@ -507,9 +507,8 @@ func (t *Tray) handleConnect() {
func (t *Tray) setItemEnabled(get func() *application.MenuItem, enabled bool) {
t.menuMu.Lock()
item := get()
t.menuMu.Unlock()
if item != nil {
defer t.menuMu.Unlock()
if item := get(); item != nil {
item.SetEnabled(enabled)
}
}

View File

@@ -104,21 +104,19 @@ func sessionRefreshInterval(remaining time.Duration) time.Duration {
}
// refreshSessionExpiresLabel updates only the countdown label, no relayout, to avoid disturbing an open menu.
// The item is snapshotted under menuMu since buildMenu reassigns it on every relayout.
// menuMu is held across the SetLabel so a relayout can't destroy the item mid-call.
func (t *Tray) refreshSessionExpiresLabel() {
t.menuMu.Lock()
item := t.sessionExpiresItem
t.menuMu.Unlock()
if item == nil {
return
}
t.sessionMu.Lock()
deadline := t.sessionExpiresAt
t.sessionMu.Unlock()
if deadline.IsZero() {
return
}
item.SetLabel(t.sessionRowLabel(deadline))
t.menuMu.Lock()
defer t.menuMu.Unlock()
if t.sessionExpiresItem != nil {
t.sessionExpiresItem.SetLabel(t.sessionRowLabel(deadline))
}
}
func (t *Tray) sessionRowLabel(deadline time.Time) string {