Files
cthulhu/internal/app/pending_presentation.go

58 lines
1.6 KiB
Go

// Cthulhu screen reader.
// Copyright (c) 2026 Storm Dragon
// Authors: Storm Dragon, Angus Kola
// SPDX-License-Identifier: GPL-3.0-or-later
package app
import (
"time"
"git.stormux.org/storm/cthulhu/internal/atspi"
"git.stormux.org/storm/cthulhu/internal/input"
)
// pendingPresentation owns one coalesced event and its captured input intent.
// Only the main event loop accesses it; timers never run presentation callbacks.
// Replacing or clearing an event disconnects its old timer from the select loop.
type pendingPresentation struct {
event atspi.Event
intent input.Intent
timer *time.Timer
ready <-chan time.Time
}
func (pending *pendingPresentation) schedule(event atspi.Event, intent input.Intent, delay time.Duration) {
pending.clear()
pending.event, pending.intent = event, intent
pending.timer = time.NewTimer(delay)
pending.ready = pending.timer.C
}
func (pending *pendingPresentation) clear() {
if pending.timer != nil {
pending.timer.Stop()
}
*pending = pendingPresentation{}
}
func (pending *pendingPresentation) take() (atspi.Event, input.Intent) {
event, intent := pending.event, pending.intent
pending.clear()
return event, intent
}
// pendingPresentations bounds delayed presentation to one event per family.
// Its lifetime is the event loop's lifetime, including adapter closure.
type pendingPresentations struct {
caret pendingPresentation
terminalFocus pendingPresentation
terminalDeletion pendingPresentation
}
func (pending *pendingPresentations) clear() {
pending.caret.clear()
pending.terminalFocus.clear()
pending.terminalDeletion.clear()
}