[client] Dispatch status snapshots only to visible windows

This commit is contained in:
Zoltán Papp
2026-07-28 17:00:43 +02:00
parent 22e0b66412
commit 28ff2b7b3b
2 changed files with 32 additions and 4 deletions

View File

@@ -171,9 +171,10 @@ type DaemonFeed struct {
// statusSubs are Go-side snapshot consumers (the tray), fed directly so
// they don't ride the window event bus. Callbacks run synchronously on
// the stream goroutine, so pushes arrive in order.
statusSubsMu sync.Mutex
statusSubs []func(Status)
lastStatus *Status
statusSubsMu sync.Mutex
statusSubs []func(Status)
lastStatus *Status
windowDispatcher func(Status)
switchMu sync.Mutex
switchInProgress bool
@@ -204,16 +205,31 @@ func (s *DaemonFeed) OnStatus(cb func(Status)) {
s.statusSubsMu.Unlock()
}
// SetWindowDispatcher installs the frontend push path: it receives every
// snapshot and decides which webview windows get it (visible ones). While
// unset, pushStatus falls back to the event-bus broadcast.
func (s *DaemonFeed) SetWindowDispatcher(fn func(Status)) {
s.statusSubsMu.Lock()
s.windowDispatcher = fn
s.statusSubsMu.Unlock()
}
// pushStatus delivers a snapshot to the Go-side subscribers and the frontend,
// and caches it for LastStatus replays.
// and caches it for LastStatus replays. Hidden windows are skipped by the
// window dispatcher; they catch up via the show replay (WindowManager).
func (s *DaemonFeed) pushStatus(st Status) {
s.statusSubsMu.Lock()
s.lastStatus = &st
subs := slices.Clone(s.statusSubs)
dispatch := s.windowDispatcher
s.statusSubsMu.Unlock()
for _, cb := range subs {
cb(st)
}
if dispatch != nil {
dispatch(st)
return
}
s.emitter.Emit(EventStatusSnapshot, st)
}