libreoffice support started, still broken. Some updates to how wine-access gets called.
This commit is contained in:
1 parent
8e76d2341c
commit
7f78177786
26 files changed
+1173
-21
No files matched your search
@@ -0,0 +1,148 @@
|
||||
// Copyright (c) 2026 Storm Dragon
|
||||
// Authors: Storm Dragon, Angus Kola
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package atspi
|
||||
|
||||
/*
|
||||
#include "adapter_native.h"
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// libreOfficeFocusTarget resolves only a Calc editor's direct text children.
|
||||
// F2 focuses its temporary panel; the paragraph can appear later, on typing.
|
||||
// The callback owns and releases the returned reference. No sheet is walked.
|
||||
func (adapter *Adapter) libreOfficeFocusTarget(event *C.AtspiEvent, eventType string) *C.AtspiAccessible {
|
||||
if eventType != FocusEvent && eventType != FocusedStateEvent ||
|
||||
!IsLibreOfficeProcess(adapter.applicationProcess(event.source)) {
|
||||
return nil
|
||||
}
|
||||
role := C.atspi_accessible_get_role(event.source, nil)
|
||||
if role == C.ATSPI_ROLE_TABLE {
|
||||
parent := C.atspi_accessible_get_parent(event.source, nil)
|
||||
if parent != nil {
|
||||
if C.atspi_accessible_get_role(parent, nil) == C.ATSPI_ROLE_DOCUMENT_SPREADSHEET {
|
||||
// Orca clears stale table state around Calc focus transitions.
|
||||
C.atspi_accessible_clear_cache_single(event.source)
|
||||
}
|
||||
C.g_object_unref(C.gpointer(parent))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if role != C.ATSPI_ROLE_PANEL && role != C.ATSPI_ROLE_EXTENDED {
|
||||
return nil
|
||||
}
|
||||
parent := C.atspi_accessible_get_parent(event.source, nil)
|
||||
if parent == nil {
|
||||
return nil
|
||||
}
|
||||
spreadsheet := C.atspi_accessible_get_role(parent, nil) == C.ATSPI_ROLE_DOCUMENT_SPREADSHEET
|
||||
C.g_object_unref(C.gpointer(parent))
|
||||
if !spreadsheet {
|
||||
return nil
|
||||
}
|
||||
count := min(int(C.atspi_accessible_get_child_count(event.source, nil)), 4)
|
||||
for index := 0; index < count; index++ {
|
||||
child := C.atspi_accessible_get_child_at_index(event.source, C.gint(index), nil)
|
||||
if child == nil {
|
||||
continue
|
||||
}
|
||||
states := C.atspi_accessible_get_state_set(child)
|
||||
focused := states != nil && C.atspi_state_set_contains(states, C.ATSPI_STATE_FOCUSED) != 0 &&
|
||||
C.atspi_state_set_contains(states, C.ATSPI_STATE_DEFUNCT) == 0
|
||||
if states != nil {
|
||||
C.g_object_unref(C.gpointer(states))
|
||||
}
|
||||
if focused && C.atspi_accessible_get_role(child, nil) == C.ATSPI_ROLE_PARAGRAPH {
|
||||
return child
|
||||
}
|
||||
C.g_object_unref(C.gpointer(child))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func captureLibreOfficeContext(source *C.AtspiAccessible, snapshot *Snapshot) {
|
||||
if !IsLibreOfficeProcess(snapshot.ApplicationProcess) || snapshot.Defunct {
|
||||
return
|
||||
}
|
||||
switch snapshot.Role {
|
||||
case "table", "table cell", "paragraph", "panel", "extended":
|
||||
default:
|
||||
return
|
||||
}
|
||||
context := LibreOfficeContext{}
|
||||
parentRole := C.AtspiRole(C.ATSPI_ROLE_INVALID)
|
||||
grandparentRole := C.AtspiRole(C.ATSPI_ROLE_INVALID)
|
||||
current := (*C.AtspiAccessible)(C.g_object_ref(C.gpointer(source)))
|
||||
for depth := 0; current != nil && depth < 32; depth++ {
|
||||
role := C.atspi_accessible_get_role(current, nil)
|
||||
if depth == 1 {
|
||||
parentRole = role
|
||||
context.EditorParent = nativeObjectID(current)
|
||||
}
|
||||
if depth == 2 {
|
||||
grandparentRole = role
|
||||
}
|
||||
if role == C.ATSPI_ROLE_TABLE {
|
||||
states := C.atspi_accessible_get_state_set(current)
|
||||
if states != nil {
|
||||
context.ContainerFocused = C.atspi_state_set_contains(states, C.ATSPI_STATE_FOCUSED) != 0
|
||||
C.g_object_unref(C.gpointer(states))
|
||||
}
|
||||
}
|
||||
if role == C.ATSPI_ROLE_DOCUMENT_SPREADSHEET {
|
||||
context.InSpreadsheet = true
|
||||
C.g_object_unref(C.gpointer(current))
|
||||
current = nil
|
||||
break
|
||||
}
|
||||
if role == C.ATSPI_ROLE_FRAME || role == C.ATSPI_ROLE_DIALOG || role == C.ATSPI_ROLE_APPLICATION {
|
||||
C.g_object_unref(C.gpointer(current))
|
||||
current = nil
|
||||
break
|
||||
}
|
||||
parent := C.atspi_accessible_get_parent(current, nil)
|
||||
C.g_object_unref(C.gpointer(current))
|
||||
current = parent
|
||||
}
|
||||
if current != nil {
|
||||
C.g_object_unref(C.gpointer(current))
|
||||
}
|
||||
if !context.InSpreadsheet {
|
||||
return
|
||||
}
|
||||
context.Cell = snapshot.Role == "table cell"
|
||||
context.CellEditor = (snapshot.Role == "panel" || snapshot.Role == "extended") &&
|
||||
parentRole == C.ATSPI_ROLE_DOCUMENT_SPREADSHEET ||
|
||||
snapshot.Role == "paragraph" && (parentRole == C.ATSPI_ROLE_PANEL || parentRole == C.ATSPI_ROLE_EXTENDED) &&
|
||||
grandparentRole == C.ATSPI_ROLE_DOCUMENT_SPREADSHEET
|
||||
if context.Cell {
|
||||
context.Coordinates = snapshot.Name
|
||||
attributes := C.atspi_accessible_get_attributes(source, nil)
|
||||
if attributes != nil {
|
||||
columnKey, rowKey := C.CString("colindextext"), C.CString("rowindextext")
|
||||
column := C.GoString((*C.gchar)(C.g_hash_table_lookup(attributes, C.gconstpointer(columnKey))))
|
||||
row := C.GoString((*C.gchar)(C.g_hash_table_lookup(attributes, C.gconstpointer(rowKey))))
|
||||
C.free(unsafe.Pointer(columnKey))
|
||||
C.free(unsafe.Pointer(rowKey))
|
||||
if column != "" && row != "" {
|
||||
context.Coordinates = sanitizeSnapshotField(column + row)
|
||||
}
|
||||
C.g_hash_table_unref(attributes)
|
||||
}
|
||||
text := C.atspi_accessible_get_text_iface(source)
|
||||
if text != nil {
|
||||
// Calc's value is Text, while Name is the coordinate. Cell caret
|
||||
// offsets can be invalid, so capture contents independently.
|
||||
length := max(0, min(int(C.atspi_text_get_character_count(text, nil)), maxSnapshotFieldLength))
|
||||
content := C.atspi_text_get_text(text, 0, C.gint(length), nil)
|
||||
context.CellText = sanitizeTextContext(C.GoString(content))
|
||||
C.g_free(C.gpointer(content))
|
||||
C.g_object_unref(C.gpointer(text))
|
||||
}
|
||||
}
|
||||
snapshot.Spreadsheet = true
|
||||
snapshot.LibreOffice = &context
|
||||
}
|
||||
Reference in new issue
Block a user