libreoffice support started, still broken. Some updates to how wine-access gets called.

This commit is contained in:
Storm Dragon committed 2026-10-14 16:24:49 -04:00
1 parent 8e76d2341c
commit 7f78177786
26 files changed
+1173 -21

No files matched your search

+51
View File
@@ -0,0 +1,51 @@
// Copyright (c) 2026 Storm Dragon
// Authors: Storm Dragon, Angus Kola
// SPDX-License-Identifier: GPL-3.0-or-later
package presentation
import (
"strings"
"git.stormux.org/storm/cthulhu/internal/atspi"
)
// Normalize only the presentation copy. Native names remain coordinates for
// ownership and diagnostics. Orca's soffice generator speaks contents first,
// then the coordinate; an empty Text value is a blank cell, not a missing name.
func libreOfficeFocusSnapshot(snapshot atspi.Snapshot, options Options) atspi.Snapshot {
context := snapshot.LibreOffice
if !atspi.IsLibreOfficeProcess(snapshot.ApplicationProcess) ||
context == nil || !context.InSpreadsheet {
return snapshot
}
if snapshot.Role == "table" {
// Orca omits table size for spreadsheets. These dimensions describe
// the sheet capacity, not the populated data.
snapshot.TableRowCount, snapshot.TableColumnCount = 0, 0
snapshot.Multiselectable, snapshot.SensitiveKnown = false, false
return snapshot
}
if context.CellEditor && snapshot.Role == "paragraph" {
snapshot.Role = ""
snapshot.SensitiveKnown = false
return snapshot
}
if snapshot.Role != "table cell" || !context.Cell {
return snapshot
}
snapshot.Name = strings.TrimSpace(context.CellText)
snapshot.Text = context.Coordinates
// Calc cell formatting in Orca omits container selection capabilities
// and insensitive-state chatter; these bits are not cell availability.
snapshot.Multiselectable = false
snapshot.SensitiveKnown = false
if reading_options(options).OnlySpeakDisplayedText {
snapshot.Text = ""
return snapshot
}
if snapshot.Name == "" {
snapshot.Name = "blank"
}
return snapshot
}
+46
View File
@@ -0,0 +1,46 @@
// Copyright (c) 2026 Storm Dragon
// Authors: Storm Dragon, Angus Kola
// SPDX-License-Identifier: GPL-3.0-or-later
package presentation
import (
"testing"
"git.stormux.org/storm/cthulhu/internal/atspi"
"git.stormux.org/storm/cthulhu/internal/config"
)
func TestLibreOfficeCellValueCoordinatesAndDisplayedText(t *testing.T) {
for _, value := range []string{"42", "", "é 猫"} {
snapshot := atspi.Snapshot{Role: "table cell", Name: "B3", Text: value, ApplicationProcess: "soffice.bin",
LibreOffice: &atspi.LibreOfficeContext{InSpreadsheet: true, Cell: true, CellText: value, Coordinates: "B3"}}
want := value + ", B3"
if value == "" {
want = "blank, B3"
}
if got := FocusText(snapshot); got != want {
t.Fatalf("cell %q = %q, want %q", value, got, want)
}
reading := config.DefaultSettings().Reading
reading.OnlySpeakDisplayedText = true
options := DefaultOptions()
options.Reading = &reading
if got := FocusTextWithOptions(snapshot, options); got != value {
t.Fatalf("displayed cell %q = %q", value, got)
}
if snapshot.Name != "B3" || snapshot.Text != value {
t.Fatal("presentation mutated native semantics")
}
}
}
func TestLibreOfficePresentationRequiresVerifiedCellContext(t *testing.T) {
for _, process := range []string{"", "chromium", "steamwebhelper"} {
snapshot := atspi.Snapshot{Role: "table cell", Name: "B3", Text: "42", ApplicationProcess: process,
LibreOffice: &atspi.LibreOfficeContext{InSpreadsheet: true, Cell: true, CellText: "wrong", Coordinates: "wrong"}}
if got := FocusText(snapshot); got != "B3, 42" {
t.Fatalf("other process %q got LibreOffice policy: %q", process, got)
}
}
}
+3 -1
View File
@@ -77,6 +77,7 @@ func FocusTextWithOptions(snapshot atspi.Snapshot, options Options) string {
}
func FocusSpeechWithOptions(snapshot atspi.Snapshot, options Options) Speech {
snapshot = libreOfficeFocusSnapshot(snapshot, options)
// GTK sliders can expose the previous displayed number through Text
// while Value already contains the current number. Present Value once.
if snapshot.Role == "slider" && controlValue(snapshot) != "" {
@@ -214,7 +215,8 @@ func EventSpeechWithOptions(event atspi.Event, options Options) Speech {
focus := speech.Text
if event.Source.Role == "table cell" && event.Source.TableName != "" {
table := atspi.Snapshot{Role: "table", TableRowCount: event.Source.TableRowCount,
TableColumnCount: event.Source.TableColumnCount}
TableColumnCount: event.Source.TableColumnCount, ApplicationProcess: event.Source.ApplicationProcess,
LibreOffice: event.Source.LibreOffice}
speech = speech.Prepend(FocusTextWithOptions(table, options), ", ")
speech = speech.Prepend(event.Source.TableName, ", ")
focus = speech.Text