// Cthulhu screen reader. // Copyright (c) 2026 Storm Dragon // Authors: Storm Dragon, Angus Kola // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation, either version 3 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // // You should have received a copy of the GNU General Public License along with // this program. If not, see . package app import ( "context" "log/slog" "git.stormux.org/storm/cthulhu/internal/lifecycle" "git.stormux.org/storm/cthulhu/internal/notification" "git.stormux.org/storm/cthulhu/internal/sessionbus" ) // newNotificationRuntime constructs notification services in their original // registration order. The caller appends them before speech history and remote // services, preserving reverse-order shutdown. func newNotificationRuntime(logger *slog.Logger, speech speechEnqueuer, braille *brailleWorker, live *liveSettings, onList func()) (*notification.Presenter, func(), []lifecycle.Service) { presenter := notification.NewPresenter() announcer := ¬ificationAnnouncer{presenter: presenter, speech: speech, braille: braille, live: live} var services []lifecycle.Service if makoConnection, err := sessionbus.Connect(logger, "notifications"); err == nil { makoMonitor := notification.NewMakoMonitor(makoConnection, presenter, announcer) presenter.SetMakoController(makoMonitor) services = append(services, lifecycle.Service{ Name: "mako-notifications", Start: func(ctx context.Context) error { return makoMonitor.Start(ctx) }, Stop: func(ctx context.Context) error { return makoMonitor.Stop(ctx) }, }) } if onList == nil { list := newNotificationListWorker(logger, presenter, speech) onList = list.Open services = append(services, lifecycle.Service{ Name: "notification list", Start: list.Start, Stop: list.Stop, }) } return presenter, onList, services }