Skip to content

Commit 73dfed7

Browse files
committed
GUI: Add accessibility region role for landmark navigation
Adds ROLE_REGION to allow controls to be marked as accessibility regions/landmarks. - Add `accessibility_region` property to Control - Add ROLE_REGION to DisplayServer and AccessKit mapping - Prevent Container/ScrollContainer from overriding region role - Fix TabContainer to update accessibility when tabs change - Mark editor docks, main screen, bottom panel, and scene tabs as regions
1 parent f9c9859 commit 73dfed7

13 files changed

Lines changed: 57 additions & 2 deletions

doc/classes/Container.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@
4040
</method>
4141
</methods>
4242
<members>
43+
<member name="accessibility_region" type="bool" setter="set_accessibility_region" getter="is_accessibility_region" default="false">
44+
If [code]true[/code], this container is marked as a region for accessibility. Use [member Control.accessibility_name] to give the region a descriptive name. Screen readers can navigate between regions using landmark navigation.
45+
</member>
4346
<member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" overrides="Control" enum="Control.MouseFilter" default="1" />
4447
</members>
4548
<signals>

doc/classes/DisplayServer.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2775,6 +2775,9 @@
27752775
<constant name="ROLE_TOOLTIP" value="45" enum="AccessibilityRole">
27762776
Tooltip element.
27772777
</constant>
2778+
<constant name="ROLE_REGION" value="46" enum="AccessibilityRole">
2779+
Region/landmark element. Screen readers can navigate between regions using landmark navigation.
2780+
</constant>
27782781
<constant name="POPUP_MENU" value="0" enum="AccessibilityPopupType">
27792782
Popup menu.
27802783
</constant>

drivers/accesskit/accessibility_driver_accesskit.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1657,6 +1657,7 @@ AccessibilityDriverAccessKit::AccessibilityDriverAccessKit() {
16571657
role_map[DisplayServer::AccessibilityRole::ROLE_TITLE_BAR] = ACCESSKIT_ROLE_TITLE_BAR;
16581658
role_map[DisplayServer::AccessibilityRole::ROLE_DIALOG] = ACCESSKIT_ROLE_DIALOG;
16591659
role_map[DisplayServer::AccessibilityRole::ROLE_TOOLTIP] = ACCESSKIT_ROLE_TOOLTIP;
1660+
role_map[DisplayServer::AccessibilityRole::ROLE_REGION] = ACCESSKIT_ROLE_REGION;
16601661

16611662
action_map[DisplayServer::AccessibilityAction::ACTION_CLICK] = ACCESSKIT_ACTION_CLICK;
16621663
action_map[DisplayServer::AccessibilityAction::ACTION_FOCUS] = ACCESSKIT_ACTION_FOCUS;

editor/docks/editor_dock.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,15 @@ void EditorDock::_emit_changed() {
4343
emit_signal(SNAME("_tab_style_changed"));
4444
}
4545

46+
void EditorDock::_notification(int p_what) {
47+
switch (p_what) {
48+
case NOTIFICATION_READY: {
49+
set_accessibility_region(true);
50+
set_accessibility_name(get_display_title());
51+
} break;
52+
}
53+
}
54+
4655
void EditorDock::_bind_methods() {
4756
ClassDB::bind_method(D_METHOD("open"), &EditorDock::open);
4857
ClassDB::bind_method(D_METHOD("make_visible"), &EditorDock::make_visible);
@@ -142,6 +151,7 @@ void EditorDock::set_title(const String &p_title) {
142151
return;
143152
}
144153
title = p_title;
154+
set_accessibility_name(get_display_title());
145155
_emit_changed();
146156
}
147157

editor/docks/editor_dock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ class EditorDock : public MarginContainer {
9494
void _emit_changed();
9595

9696
protected:
97+
void _notification(int p_what);
9798
static void _bind_methods();
9899

99100
GDVIRTUAL1(_update_layout, int)

editor/editor_main_screen.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
void EditorMainScreen::_notification(int p_what) {
4242
switch (p_what) {
4343
case NOTIFICATION_READY: {
44+
set_accessibility_region(true);
4445
if (EDITOR_3D < buttons.size() && buttons[EDITOR_3D]->is_visible()) {
4546
// If the 3D editor is enabled, use this as the default.
4647
select(EDITOR_3D);
@@ -194,6 +195,7 @@ void EditorMainScreen::select(int p_index) {
194195
selected_plugin = new_editor;
195196
selected_plugin->make_visible(true);
196197
selected_plugin->selected_notify();
198+
set_accessibility_name(selected_plugin->get_plugin_name());
197199

198200
EditorData &editor_data = EditorNode::get_editor_data();
199201
int plugin_count = editor_data.get_editor_plugin_count();

editor/gui/editor_bottom_panel.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
void EditorBottomPanel::_notification(int p_what) {
4848
switch (p_what) {
4949
case NOTIFICATION_READY: {
50+
set_accessibility_region(true);
5051
layout_popup = get_popup();
5152
} break;
5253

@@ -60,6 +61,9 @@ void EditorBottomPanel::_notification(int p_what) {
6061
void EditorBottomPanel::_on_tab_changed(int p_idx) {
6162
_update_center_split_offset();
6263
_repaint();
64+
if (p_idx >= 0 && p_idx < get_tab_count()) {
65+
set_accessibility_name(get_tab_title(p_idx));
66+
}
6367
}
6468

6569
void EditorBottomPanel::_theme_changed() {

scene/gui/container.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,11 @@ void Container::_notification(int p_what) {
188188
RID ae = get_accessibility_element();
189189
ERR_FAIL_COND(ae.is_null());
190190

191-
DisplayServer::get_singleton()->accessibility_update_set_role(ae, DisplayServer::AccessibilityRole::ROLE_CONTAINER);
191+
if (accessibility_region) {
192+
DisplayServer::get_singleton()->accessibility_update_set_role(ae, DisplayServer::AccessibilityRole::ROLE_REGION);
193+
} else {
194+
DisplayServer::get_singleton()->accessibility_update_set_role(ae, DisplayServer::AccessibilityRole::ROLE_CONTAINER);
195+
}
192196
} break;
193197

194198
case NOTIFICATION_RESIZED:
@@ -204,6 +208,18 @@ void Container::_notification(int p_what) {
204208
}
205209
}
206210

211+
void Container::set_accessibility_region(bool p_region) {
212+
ERR_MAIN_THREAD_GUARD;
213+
if (accessibility_region != p_region) {
214+
accessibility_region = p_region;
215+
queue_accessibility_update();
216+
}
217+
}
218+
219+
bool Container::is_accessibility_region() const {
220+
return accessibility_region;
221+
}
222+
207223
PackedStringArray Container::get_configuration_warnings() const {
208224
PackedStringArray warnings = Control::get_configuration_warnings();
209225

@@ -217,6 +233,8 @@ PackedStringArray Container::get_configuration_warnings() const {
217233
void Container::_bind_methods() {
218234
ClassDB::bind_method(D_METHOD("queue_sort"), &Container::queue_sort);
219235
ClassDB::bind_method(D_METHOD("fit_child_in_rect", "child", "rect"), &Container::fit_child_in_rect);
236+
ClassDB::bind_method(D_METHOD("set_accessibility_region", "region"), &Container::set_accessibility_region);
237+
ClassDB::bind_method(D_METHOD("is_accessibility_region"), &Container::is_accessibility_region);
220238

221239
GDVIRTUAL_BIND(_get_allowed_size_flags_horizontal);
222240
GDVIRTUAL_BIND(_get_allowed_size_flags_vertical);
@@ -226,6 +244,8 @@ void Container::_bind_methods() {
226244

227245
ADD_SIGNAL(MethodInfo("pre_sort_children"));
228246
ADD_SIGNAL(MethodInfo("sort_children"));
247+
248+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "accessibility_region"), "set_accessibility_region", "is_accessibility_region");
229249
}
230250

231251
Container::Container() {

scene/gui/container.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class Container : public Control {
3636
GDCLASS(Container, Control);
3737

3838
bool pending_sort = false;
39+
bool accessibility_region = false;
3940
void _sort_children();
4041
void _child_minsize_changed();
4142

@@ -72,5 +73,8 @@ class Container : public Control {
7273

7374
PackedStringArray get_configuration_warnings() const override;
7475

76+
void set_accessibility_region(bool p_region);
77+
bool is_accessibility_region() const;
78+
7579
Container();
7680
};

scene/gui/scroll_container.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,11 @@ void ScrollContainer::_notification(int p_what) {
434434
RID ae = get_accessibility_element();
435435
ERR_FAIL_COND(ae.is_null());
436436

437-
DisplayServer::get_singleton()->accessibility_update_set_role(ae, DisplayServer::AccessibilityRole::ROLE_SCROLL_VIEW);
437+
if (is_accessibility_region()) {
438+
DisplayServer::get_singleton()->accessibility_update_set_role(ae, DisplayServer::AccessibilityRole::ROLE_REGION);
439+
} else {
440+
DisplayServer::get_singleton()->accessibility_update_set_role(ae, DisplayServer::AccessibilityRole::ROLE_SCROLL_VIEW);
441+
}
438442

439443
DisplayServer::get_singleton()->accessibility_update_add_action(ae, DisplayServer::AccessibilityAction::ACTION_SCROLL_DOWN, callable_mp(this, &ScrollContainer::_accessibility_action_scroll_down));
440444
DisplayServer::get_singleton()->accessibility_update_add_action(ae, DisplayServer::AccessibilityAction::ACTION_SCROLL_LEFT, callable_mp(this, &ScrollContainer::_accessibility_action_scroll_left));

0 commit comments

Comments
 (0)