From d0bc7d8a3a571c061df9a869b7620fafade2c5a3 Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Mon, 23 Mar 2026 12:46:27 -0400 Subject: [PATCH] I tested these changes for so long I actually forgot what they were, but they seem to work, so committing. --- src/cthulhu/ax_hypertext.py | 39 +++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/src/cthulhu/ax_hypertext.py b/src/cthulhu/ax_hypertext.py index 2222ac9..f2e741b 100644 --- a/src/cthulhu/ax_hypertext.py +++ b/src/cthulhu/ax_hypertext.py @@ -204,10 +204,21 @@ class AXHypertext: @staticmethod def find_child_at_offset(obj: Atspi.Accessible, offset: int) -> Optional[Atspi.Accessible]: - """Attempts to correct for off-by-one brokenness in implementations""" + """Returns the child at offset, correcting for broken hypertext offset mappings.""" if child := AXHypertext.get_child_at_offset(obj, offset): - return child + offset_in_parent = AXHypertext.get_character_offset_in_parent(child) + if offset_in_parent == offset: + return child + + tokens = [ + f"AXHypertext: Child at offset {offset} in", + obj, + "is", + child, + f"but reports offset {offset_in_parent}", + ] + debug.print_tokens(debug.LEVEL_INFO, tokens, True) if child_before := AXHypertext.get_child_at_offset(obj, offset - 1): offset_in_parent = AXHypertext.get_character_offset_in_parent(child_before) @@ -225,6 +236,30 @@ class AXHypertext: debug.print_tokens(debug.LEVEL_INFO, tokens, True) return child_after + for i in range(AXHypertext._get_link_count(obj)): + link = AXHypertext._get_link_at_index(obj, i) + if link is None or AXHypertext.get_link_start_offset(link) != offset: + continue + + try: + child = Atspi.Hyperlink.get_object(link, 0) + except GLib.GError as error: + msg = f"AXHypertext: Exception in find_child_at_offset: {error}" + debug.print_message(debug.LEVEL_INFO, msg, True) + continue + + if child is None: + continue + + tokens = [ + f"AXHypertext: Child at offset {offset} in", + obj, + "found via link enumeration:", + child, + ] + debug.print_tokens(debug.LEVEL_INFO, tokens, True) + return child + return None @staticmethod