You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-12-31 18:41:20 +00:00
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:
@@ -250,7 +250,7 @@ RID AccessibilityDriverAccessKit::accessibility_create_sub_element(const RID &p_
|
||||
return rid;
|
||||
}
|
||||
|
||||
RID AccessibilityDriverAccessKit::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 AccessibilityDriverAccessKit::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) {
|
||||
AccessibilityElement *parent_ae = rid_owner.get_or_null(p_parent_rid);
|
||||
ERR_FAIL_NULL_V(parent_ae, RID());
|
||||
|
||||
@@ -421,7 +421,7 @@ RID AccessibilityDriverAccessKit::accessibility_create_sub_text_edit_elements(co
|
||||
|
||||
run_off_x += size_x;
|
||||
}
|
||||
{
|
||||
if (!p_is_last_line || text_elements.is_empty()) {
|
||||
// Add "\n" at the end.
|
||||
AccessibilityElement *ae = memnew(AccessibilityElement);
|
||||
ae->role = ACCESSKIT_ROLE_TEXT_RUN;
|
||||
@@ -432,18 +432,22 @@ RID AccessibilityDriverAccessKit::accessibility_create_sub_text_edit_elements(co
|
||||
|
||||
text_elements.push_back(ae);
|
||||
|
||||
Vector<uint8_t> char_lengths;
|
||||
char_lengths.push_back(1);
|
||||
accesskit_node_set_value(ae->node, "\n");
|
||||
accesskit_node_set_character_lengths(ae->node, char_lengths.size(), char_lengths.ptr());
|
||||
if (!p_is_last_line) {
|
||||
accesskit_node_set_value(ae->node, "\n");
|
||||
|
||||
Vector<float> char_positions;
|
||||
Vector<float> char_widths;
|
||||
char_positions.push_back(0.0);
|
||||
char_widths.push_back(1.0);
|
||||
Vector<uint8_t> char_lengths;
|
||||
Vector<float> char_positions;
|
||||
Vector<float> char_widths;
|
||||
char_lengths.push_back(1);
|
||||
char_positions.push_back(0.0);
|
||||
char_widths.push_back(1.0);
|
||||
|
||||
accesskit_node_set_character_positions(ae->node, char_positions.size(), char_positions.ptr());
|
||||
accesskit_node_set_character_widths(ae->node, char_widths.size(), char_widths.ptr());
|
||||
accesskit_node_set_character_lengths(ae->node, char_lengths.size(), char_lengths.ptr());
|
||||
accesskit_node_set_character_positions(ae->node, char_positions.size(), char_positions.ptr());
|
||||
accesskit_node_set_character_widths(ae->node, char_widths.size(), char_widths.ptr());
|
||||
} else {
|
||||
accesskit_node_set_value(ae->node, "");
|
||||
}
|
||||
accesskit_node_set_text_direction(ae->node, ACCESSKIT_TEXT_DIRECTION_LEFT_TO_RIGHT);
|
||||
|
||||
accesskit_rect rect;
|
||||
@@ -461,10 +465,18 @@ RID AccessibilityDriverAccessKit::accessibility_create_sub_text_edit_elements(co
|
||||
}
|
||||
};
|
||||
text_elements.sort_custom<RunCompare>();
|
||||
for (AccessibilityElement *text_element : text_elements) {
|
||||
RID rid = rid_owner.make_rid(text_element);
|
||||
for (int i = 0; i < text_elements.size(); i++) {
|
||||
RID rid = rid_owner.make_rid(text_elements[i]);
|
||||
root_ae->children.push_back(rid);
|
||||
wd->update.insert(rid);
|
||||
|
||||
// Link adjacent TextRuns on the same line.
|
||||
if (i > 0) {
|
||||
RID prev_rid = root_ae->children[i - 1];
|
||||
AccessibilityElement *prev_ae = rid_owner.get_or_null(prev_rid);
|
||||
accesskit_node_set_previous_on_line(text_elements[i]->node, (accesskit_node_id)prev_rid.get_id());
|
||||
accesskit_node_set_next_on_line(prev_ae->node, (accesskit_node_id)rid.get_id());
|
||||
}
|
||||
}
|
||||
|
||||
return root_rid;
|
||||
|
||||
@@ -113,7 +113,7 @@ public:
|
||||
|
||||
RID accessibility_create_element(DisplayServer::WindowID p_window_id, DisplayServer::AccessibilityRole p_role) override;
|
||||
RID accessibility_create_sub_element(const RID &p_parent_rid, DisplayServer::AccessibilityRole p_role, int p_insert_pos = -1) override;
|
||||
virtual RID accessibility_create_sub_text_edit_elements(const RID &p_parent_rid, const RID &p_shaped_text, float p_min_height, int p_insert_pos = -1) override;
|
||||
virtual RID accessibility_create_sub_text_edit_elements(const RID &p_parent_rid, const RID &p_shaped_text, float p_min_height, int p_insert_pos = -1, bool p_is_last_line = false) override;
|
||||
bool accessibility_has_element(const RID &p_id) const override;
|
||||
void accessibility_free_element(const RID &p_id) override;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user