Accessibility: Fix text field character count and line navigation

Two fixes for text field accessibility:

1. Fix character count being off by one due to trailing newline always
   being appended to the last line. Add `is_last_line` parameter to
   `accessibility_create_sub_text_edit_elements()` to control this.

2. Link adjacent TextRuns via `previous_on_line`/`next_on_line` so
   screen readers can properly navigate lines. Without these links,
   AccessKit treats each TextRun as a separate line, causing incorrect
   announcements when arrowing through multi-line text.
This commit is contained in:
Nolan Darilek
2025-12-02 14:54:14 -05:00
parent 7a228b4b91
commit 6304e9f876
10 changed files with 50 additions and 28 deletions

View File

@@ -648,9 +648,9 @@ RID DisplayServer::accessibility_create_sub_element(const RID &p_parent_rid, Dis
}
}
RID DisplayServer::accessibility_create_sub_text_edit_elements(const RID &p_parent_rid, const RID &p_shaped_text, float p_min_height, int p_insert_pos) {
RID DisplayServer::accessibility_create_sub_text_edit_elements(const RID &p_parent_rid, const RID &p_shaped_text, float p_min_height, int p_insert_pos, bool p_is_last_line) {
if (accessibility_driver) {
return accessibility_driver->accessibility_create_sub_text_edit_elements(p_parent_rid, p_shaped_text, p_min_height, p_insert_pos);
return accessibility_driver->accessibility_create_sub_text_edit_elements(p_parent_rid, p_shaped_text, p_min_height, p_insert_pos, p_is_last_line);
} else {
return RID();
}
@@ -1485,7 +1485,7 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("accessibility_create_element", "window_id", "role"), &DisplayServer::accessibility_create_element);
ClassDB::bind_method(D_METHOD("accessibility_create_sub_element", "parent_rid", "role", "insert_pos"), &DisplayServer::accessibility_create_sub_element, DEFVAL(-1));
ClassDB::bind_method(D_METHOD("accessibility_create_sub_text_edit_elements", "parent_rid", "shaped_text", "min_height", "insert_pos"), &DisplayServer::accessibility_create_sub_text_edit_elements, DEFVAL(-1));
ClassDB::bind_method(D_METHOD("accessibility_create_sub_text_edit_elements", "parent_rid", "shaped_text", "min_height", "insert_pos", "is_last_line"), &DisplayServer::accessibility_create_sub_text_edit_elements, DEFVAL(-1), DEFVAL(false));
ClassDB::bind_method(D_METHOD("accessibility_has_element", "id"), &DisplayServer::accessibility_has_element);
ClassDB::bind_method(D_METHOD("accessibility_free_element", "id"), &DisplayServer::accessibility_free_element);
ClassDB::bind_method(D_METHOD("accessibility_element_set_meta", "id", "meta"), &DisplayServer::accessibility_element_set_meta);