57 lines
2.1 KiB
Go
57 lines
2.1 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 (
|
|
"git.stormux.org/storm/cthulhu/internal/atspi"
|
|
"git.stormux.org/storm/cthulhu/internal/presentation"
|
|
)
|
|
|
|
type promptPresentation struct {
|
|
state *eventLoopState
|
|
event atspi.Event
|
|
activation bool
|
|
focus bool
|
|
}
|
|
|
|
func newPromptPresentation(state *eventLoopState, event atspi.Event) promptPresentation {
|
|
control := event.Source.Role == "button" || event.Source.Role == "tree table" || event.Source.Role == "table cell"
|
|
return promptPresentation{
|
|
state: state,
|
|
event: event,
|
|
activation: event.Type == atspi.WindowActivatedEvent && control && event.WindowMessage != "",
|
|
focus: isFocusGainEvent(event) && control && state.pendingPromptWindow.Valid() && event.Window == state.pendingPromptWindow,
|
|
}
|
|
}
|
|
|
|
func (prompt promptPresentation) focusSpeech(spoken, fallback presentation.Speech) (presentation.Speech, presentation.Speech) {
|
|
if prompt.focus && !prompt.state.pendingPromptTextAnnounced && prompt.event.WindowMessage != "" {
|
|
spoken = spoken.Prepend(prompt.event.WindowMessage, ", ")
|
|
fallback = spoken
|
|
}
|
|
return spoken, fallback
|
|
}
|
|
|
|
func (prompt promptPresentation) appendFocus() bool {
|
|
return prompt.focus && (prompt.state.pendingPromptTextAnnounced || prompt.event.WindowMessage != "")
|
|
}
|
|
|
|
func (prompt promptPresentation) finishFocus() {
|
|
if isFocusGainEvent(prompt.event) && (prompt.event.Source.Role == "button" || prompt.event.Source.Role == "tree table" || prompt.event.Source.Role == "table cell") {
|
|
prompt.state.pendingPromptWindow = atspi.ObjectID{}
|
|
prompt.state.pendingPromptTextAnnounced = false
|
|
}
|
|
}
|
|
|
|
func (prompt promptPresentation) rememberWindow() {
|
|
if (prompt.event.Type == atspi.WindowCreateEvent || prompt.event.Type == atspi.WindowActivatedEvent) &&
|
|
(prompt.event.Source.Role == "alert" || prompt.event.Source.Role == "frame" || prompt.activation) &&
|
|
prompt.event.Window.Valid() {
|
|
prompt.state.pendingPromptWindow = prompt.event.Window
|
|
prompt.state.pendingPromptTextAnnounced = prompt.event.Source.Text != "" || prompt.activation
|
|
}
|
|
}
|