1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672 |
- /**************************************************************************/
- /* accessibility_driver_accesskit.cpp */
- /**************************************************************************/
- /* This file is part of: */
- /* GODOT ENGINE */
- /* https://godotengine.org */
- /**************************************************************************/
- /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
- /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
- /* */
- /* Permission is hereby granted, free of charge, to any person obtaining */
- /* a copy of this software and associated documentation files (the */
- /* "Software"), to deal in the Software without restriction, including */
- /* without limitation the rights to use, copy, modify, merge, publish, */
- /* distribute, sublicense, and/or sell copies of the Software, and to */
- /* permit persons to whom the Software is furnished to do so, subject to */
- /* the following conditions: */
- /* */
- /* The above copyright notice and this permission notice shall be */
- /* included in all copies or substantial portions of the Software. */
- /* */
- /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
- /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
- /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
- /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
- /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
- /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
- /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
- /**************************************************************************/
- #ifdef ACCESSKIT_ENABLED
- #include "accessibility_driver_accesskit.h"
- #include "core/config/project_settings.h"
- #include "core/io/file_access.h"
- #include "core/version.h"
- #include "servers/text/text_server.h"
- AccessibilityDriverAccessKit *AccessibilityDriverAccessKit::singleton = nullptr;
- _FORCE_INLINE_ accesskit_role AccessibilityDriverAccessKit::_accessibility_role(DisplayServer::AccessibilityRole p_role) const {
- if (role_map.has(p_role)) {
- return role_map[p_role];
- }
- return ACCESSKIT_ROLE_UNKNOWN;
- }
- _FORCE_INLINE_ accesskit_action AccessibilityDriverAccessKit::_accessibility_action(DisplayServer::AccessibilityAction p_action) const {
- if (action_map.has(p_action)) {
- return action_map[p_action];
- }
- return ACCESSKIT_ACTION_CLICK;
- }
- bool AccessibilityDriverAccessKit::window_create(DisplayServer::WindowID p_window_id, void *p_handle) {
- ERR_FAIL_COND_V(windows.has(p_window_id), false);
- WindowData &wd = windows[p_window_id];
- AccessibilityElement *ae = memnew(AccessibilityElement);
- ae->role = ACCESSKIT_ROLE_WINDOW;
- ae->window_id = p_window_id;
- wd.root_id = rid_owner.make_rid(ae);
- #ifdef WINDOWS_ENABLED
- wd.adapter = accesskit_windows_subclassing_adapter_new(static_cast<HWND>(p_handle), &_accessibility_initial_tree_update_callback, (void *)(size_t)p_window_id, &_accessibility_action_callback, (void *)(size_t)p_window_id);
- #endif
- #ifdef MACOS_ENABLED
- wd.adapter = accesskit_macos_subclassing_adapter_for_window(p_handle, &_accessibility_initial_tree_update_callback, (void *)(size_t)p_window_id, &_accessibility_action_callback, (void *)(size_t)p_window_id);
- #endif
- #ifdef LINUXBSD_ENABLED
- wd.adapter = accesskit_unix_adapter_new(&_accessibility_initial_tree_update_callback, (void *)(size_t)p_window_id, &_accessibility_action_callback, (void *)(size_t)p_window_id, &_accessibility_deactivation_callback, (void *)(size_t)p_window_id);
- #endif
- if (wd.adapter == nullptr) {
- memdelete(ae);
- rid_owner.free(wd.root_id);
- windows.erase(p_window_id);
- return false;
- } else {
- return true;
- }
- }
- void AccessibilityDriverAccessKit::window_destroy(DisplayServer::WindowID p_window_id) {
- WindowData *wd = windows.getptr(p_window_id);
- ERR_FAIL_NULL(wd);
- #ifdef WINDOWS_ENABLED
- accesskit_windows_subclassing_adapter_free(wd->adapter);
- #endif
- #ifdef MACOS_ENABLED
- accesskit_macos_subclassing_adapter_free(wd->adapter);
- #endif
- #ifdef LINUXBSD_ENABLED
- accesskit_unix_adapter_free(wd->adapter);
- #endif
- accessibility_free_element(wd->root_id);
- windows.erase(p_window_id);
- }
- void AccessibilityDriverAccessKit::_accessibility_deactivation_callback(void *p_user_data) {
- // NOP
- }
- void AccessibilityDriverAccessKit::_accessibility_action_callback(struct accesskit_action_request *p_request, void *p_user_data) {
- DisplayServer::WindowID window_id = (DisplayServer::WindowID)(size_t)p_user_data;
- ERR_FAIL_COND(!singleton->windows.has(window_id));
- RID rid = RID::from_uint64(p_request->target);
- AccessibilityElement *ae = singleton->rid_owner.get_or_null(rid);
- ERR_FAIL_NULL(ae);
- Variant rq_data;
- if (!ae->actions.has(p_request->action) && ae->role == ACCESSKIT_ROLE_TEXT_RUN && p_request->action == ACCESSKIT_ACTION_SCROLL_INTO_VIEW) {
- AccessibilityElement *root_ae = singleton->rid_owner.get_or_null(ae->parent);
- ERR_FAIL_NULL(root_ae);
- ae = root_ae;
- rq_data = ae->run;
- }
- if (ae->actions.has(p_request->action)) {
- Callable &cb = ae->actions[p_request->action];
- if (cb.is_valid()) {
- if (p_request->data.has_value) {
- switch (p_request->data.value.tag) {
- case ACCESSKIT_ACTION_DATA_CUSTOM_ACTION: {
- rq_data = p_request->data.value.custom_action;
- } break;
- case ACCESSKIT_ACTION_DATA_VALUE: {
- rq_data = String::utf8(p_request->data.value.value);
- } break;
- case ACCESSKIT_ACTION_DATA_NUMERIC_VALUE: {
- rq_data = p_request->data.value.numeric_value;
- } break;
- case ACCESSKIT_ACTION_DATA_SCROLL_HINT: {
- switch (p_request->data.value.scroll_hint) {
- case ACCESSKIT_SCROLL_HINT_TOP_LEFT: {
- rq_data = DisplayServer::SCROLL_HINT_TOP_LEFT;
- } break;
- case ACCESSKIT_SCROLL_HINT_BOTTOM_RIGHT: {
- rq_data = DisplayServer::SCROLL_HINT_BOTTOM_RIGHT;
- } break;
- case ACCESSKIT_SCROLL_HINT_TOP_EDGE: {
- rq_data = DisplayServer::SCROLL_HINT_TOP_EDGE;
- } break;
- case ACCESSKIT_SCROLL_HINT_BOTTOM_EDGE: {
- rq_data = DisplayServer::SCROLL_HINT_BOTTOM_EDGE;
- } break;
- case ACCESSKIT_SCROLL_HINT_LEFT_EDGE: {
- rq_data = DisplayServer::SCROLL_HINT_LEFT_EDGE;
- } break;
- case ACCESSKIT_SCROLL_HINT_RIGHT_EDGE: {
- rq_data = DisplayServer::SCROLL_HINT_RIGHT_EDGE;
- } break;
- default:
- break;
- }
- } break;
- case ACCESSKIT_ACTION_DATA_SCROLL_UNIT: {
- if (p_request->data.value.scroll_unit == ACCESSKIT_SCROLL_UNIT_ITEM) {
- rq_data = DisplayServer::SCROLL_UNIT_ITEM;
- } else if (p_request->data.value.scroll_unit == ACCESSKIT_SCROLL_UNIT_PAGE) {
- rq_data = DisplayServer::SCROLL_UNIT_PAGE;
- }
- } break;
- case ACCESSKIT_ACTION_DATA_SCROLL_TO_POINT: {
- rq_data = Point2(p_request->data.value.scroll_to_point.x, p_request->data.value.scroll_to_point.y);
- } break;
- case ACCESSKIT_ACTION_DATA_SET_SCROLL_OFFSET: {
- rq_data = Point2(p_request->data.value.set_scroll_offset.x, p_request->data.value.set_scroll_offset.y);
- } break;
- case ACCESSKIT_ACTION_DATA_SET_TEXT_SELECTION: {
- Dictionary sel;
- RID start_rid = RID::from_uint64(p_request->data.value.set_text_selection.anchor.node);
- AccessibilityElement *start_ae = singleton->rid_owner.get_or_null(start_rid);
- ERR_FAIL_NULL(start_ae);
- RID end_rid = RID::from_uint64(p_request->data.value.set_text_selection.focus.node);
- AccessibilityElement *end_ae = singleton->rid_owner.get_or_null(end_rid);
- ERR_FAIL_NULL(end_ae);
- sel["start_element"] = start_ae->parent;
- sel["start_char"] = (int64_t)p_request->data.value.set_text_selection.anchor.character_index + start_ae->run.x;
- sel["end_element"] = end_ae->parent;
- sel["end_char"] = (int64_t)p_request->data.value.set_text_selection.focus.character_index + end_ae->run.x;
- rq_data = sel;
- } break;
- }
- }
- cb.call_deferred(rq_data);
- }
- }
- }
- accesskit_tree_update *AccessibilityDriverAccessKit::_accessibility_initial_tree_update_callback(void *p_user_data) {
- DisplayServer::WindowID window_id = (DisplayServer::WindowID)(size_t)p_user_data;
- WindowData *wd = singleton->windows.getptr(window_id);
- ERR_FAIL_NULL_V(wd, nullptr);
- accesskit_node *win_node = accesskit_node_new(ACCESSKIT_ROLE_WINDOW);
- accesskit_node_set_label(win_node, "Godot Engine");
- accesskit_node_set_busy(win_node);
- accesskit_node_id win_id = (accesskit_node_id)wd->root_id.get_id();
- accesskit_tree_update *tree_update = accesskit_tree_update_with_capacity_and_focus(1, win_id);
- accesskit_tree_update_set_tree(tree_update, accesskit_tree_new(win_id));
- accesskit_tree_update_push_node(tree_update, win_id, win_node);
- return tree_update;
- }
- RID AccessibilityDriverAccessKit::accessibility_create_element(DisplayServer::WindowID p_window_id, DisplayServer::AccessibilityRole p_role) {
- AccessibilityElement *ae = memnew(AccessibilityElement);
- ae->role = _accessibility_role(p_role);
- ae->window_id = p_window_id;
- RID rid = rid_owner.make_rid(ae);
- return rid;
- }
- RID AccessibilityDriverAccessKit::accessibility_create_sub_element(const RID &p_parent_rid, DisplayServer::AccessibilityRole p_role, int p_insert_pos) {
- AccessibilityElement *parent_ae = rid_owner.get_or_null(p_parent_rid);
- ERR_FAIL_NULL_V(parent_ae, RID());
- WindowData *wd = windows.getptr(parent_ae->window_id);
- ERR_FAIL_NULL_V(wd, RID());
- AccessibilityElement *ae = memnew(AccessibilityElement);
- ae->role = _accessibility_role(p_role);
- ae->window_id = parent_ae->window_id;
- ae->parent = p_parent_rid;
- ae->node = accesskit_node_new(ae->role);
- RID rid = rid_owner.make_rid(ae);
- if (p_insert_pos == -1) {
- parent_ae->children.push_back(rid);
- } else {
- parent_ae->children.insert(p_insert_pos, rid);
- }
- wd->update.insert(rid);
- 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) {
- AccessibilityElement *parent_ae = rid_owner.get_or_null(p_parent_rid);
- ERR_FAIL_NULL_V(parent_ae, RID());
- WindowData *wd = windows.getptr(parent_ae->window_id);
- ERR_FAIL_NULL_V(wd, RID());
- AccessibilityElement *root_ae = memnew(AccessibilityElement);
- root_ae->role = ACCESSKIT_ROLE_GENERIC_CONTAINER;
- root_ae->window_id = parent_ae->window_id;
- root_ae->parent = p_parent_rid;
- root_ae->node = accesskit_node_new(root_ae->role);
- RID root_rid = rid_owner.make_rid(root_ae);
- if (p_insert_pos == -1) {
- parent_ae->children.push_back(root_rid);
- } else {
- parent_ae->children.insert(p_insert_pos, root_rid);
- }
- wd->update.insert(root_rid);
- float text_width = 0;
- float text_height = p_min_height;
- Vector<int32_t> words;
- int64_t run_count = 0; // Note: runs in visual order.
- const Glyph *gl = nullptr;
- int64_t gl_count = 0;
- int64_t gl_index = 0;
- float run_off_x = 0.0;
- Vector2i full_range;
- if (p_shaped_text.is_valid()) {
- text_width = TS->shaped_text_get_size(p_shaped_text).x;
- text_height = MAX(text_height, TS->shaped_text_get_size(p_shaped_text).y);
- words = TS->shaped_text_get_word_breaks(p_shaped_text);
- run_count = TS->shaped_get_run_count(p_shaped_text);
- gl = TS->shaped_text_get_glyphs(p_shaped_text);
- gl_count = TS->shaped_text_get_glyph_count(p_shaped_text);
- full_range = TS->shaped_text_get_range(p_shaped_text);
- }
- accesskit_rect root_rect;
- root_rect.x0 = 0;
- root_rect.y0 = 0;
- root_rect.x1 = text_width;
- root_rect.y1 = MAX(p_min_height, text_height);
- accesskit_node_set_bounds(root_ae->node, root_rect);
- // Create text element for each run.
- Vector<AccessibilityElement *> text_elements;
- for (int64_t i = 0; i < run_count; i++) {
- const Vector2i range = TS->shaped_get_run_range(p_shaped_text, i);
- String t = TS->shaped_get_run_text(p_shaped_text, i);
- if (t.is_empty()) {
- continue;
- }
- AccessibilityElement *ae = memnew(AccessibilityElement);
- ae->role = ACCESSKIT_ROLE_TEXT_RUN;
- ae->window_id = parent_ae->window_id;
- ae->parent = root_rid;
- ae->run = Vector3i(range.x, range.y, i);
- ae->node = accesskit_node_new(ae->role);
- text_elements.push_back(ae);
- // UTF-8 text and char lengths.
- Vector<uint8_t> char_lengths;
- CharString text = t.utf8(&char_lengths);
- accesskit_node_set_value(ae->node, text.ptr());
- accesskit_node_set_character_lengths(ae->node, char_lengths.size(), char_lengths.ptr());
- // Word sizes.
- Vector<uint8_t> word_lengths;
- int32_t prev = ae->run.x;
- int32_t total = 0;
- for (int j = 0; j < words.size(); j += 2) {
- if (words[j] < ae->run.x) {
- continue;
- }
- if (words[j] >= ae->run.y) {
- break;
- }
- int32_t wlen = words[j] - prev;
- while (wlen > 255) {
- word_lengths.push_back(255);
- wlen -= 255;
- total += 255;
- }
- if (wlen > 0) {
- word_lengths.push_back(wlen);
- total += wlen;
- }
- prev = words[j];
- }
- if (total < t.length()) {
- word_lengths.push_back(t.length() - total);
- }
- accesskit_node_set_word_lengths(ae->node, word_lengths.size(), word_lengths.ptr());
- // Char widths and positions.
- Vector<float> char_positions;
- Vector<float> char_widths;
- char_positions.resize_initialized(t.length());
- float *positions_ptr = char_positions.ptrw();
- char_widths.resize_initialized(t.length());
- float *widths_ptr = char_widths.ptrw();
- float size_x = 0.0;
- for (int j = gl_index; j < gl_count; j += gl[j].count) {
- if (gl[j].start >= ae->run.y) {
- gl_index = j;
- break;
- }
- float advance = 0.0; // Graphame advance.
- for (int k = 0; k < gl[j].count; k++) {
- advance += gl[j + k].advance;
- }
- int chars = gl[j].end - gl[j].start;
- float adv_per_char = advance / (float)chars;
- for (int k = 0; k < chars; k++) {
- int index = gl[j].start + k - ae->run.x;
- ERR_CONTINUE(index < 0 || index >= t.length());
- positions_ptr[index] = size_x + adv_per_char * k;
- widths_ptr[index] = adv_per_char;
- }
- size_x += advance * gl[j].repeat;
- }
- positions_ptr[t.length() - 1] = size_x;
- widths_ptr[t.length() - 1] = 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());
- RID font_rid = TS->shaped_get_run_font_rid(p_shaped_text, i);
- if (font_rid != RID()) {
- CharString font_name = TS->font_get_name(font_rid).utf8();
- if (font_name.length() > 0) {
- accesskit_node_set_font_family(ae->node, font_name.ptr());
- }
- if (TS->font_get_style(font_rid).has_flag(TextServer::FONT_BOLD)) {
- accesskit_node_set_bold(ae->node);
- }
- if (TS->font_get_style(font_rid).has_flag(TextServer::FONT_ITALIC)) {
- accesskit_node_set_italic(ae->node);
- }
- accesskit_node_set_font_weight(ae->node, TS->font_get_weight(font_rid));
- }
- accesskit_node_set_font_size(ae->node, TS->shaped_get_run_font_size(p_shaped_text, i));
- CharString language = TS->shaped_get_run_language(p_shaped_text, i).utf8();
- if (language.length() > 0) {
- accesskit_node_set_language(ae->node, language.ptr());
- }
- accesskit_node_set_text_direction(ae->node, ACCESSKIT_TEXT_DIRECTION_LEFT_TO_RIGHT);
- accesskit_rect rect;
- rect.x0 = run_off_x;
- rect.y0 = 0;
- rect.x1 = run_off_x + size_x;
- rect.y1 = text_height;
- accesskit_node_set_bounds(ae->node, rect);
- accesskit_node_add_action(ae->node, ACCESSKIT_ACTION_SCROLL_INTO_VIEW);
- run_off_x += size_x;
- }
- {
- // Add "\n" at the end.
- AccessibilityElement *ae = memnew(AccessibilityElement);
- ae->role = ACCESSKIT_ROLE_TEXT_RUN;
- ae->window_id = parent_ae->window_id;
- ae->parent = root_rid;
- ae->run = Vector3i(full_range.y, full_range.y, run_count);
- ae->node = accesskit_node_new(ae->role);
- 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());
- Vector<float> char_positions;
- Vector<float> char_widths;
- 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_text_direction(ae->node, ACCESSKIT_TEXT_DIRECTION_LEFT_TO_RIGHT);
- accesskit_rect rect;
- rect.x0 = run_off_x;
- rect.y0 = 0;
- rect.x1 = run_off_x + 1;
- rect.y1 = text_height;
- accesskit_node_set_bounds(ae->node, rect);
- }
- // Sort runs in logical order.
- struct RunCompare {
- _FORCE_INLINE_ bool operator()(const AccessibilityElement *l, const AccessibilityElement *r) const {
- return l->run.x < r->run.x;
- }
- };
- text_elements.sort_custom<RunCompare>();
- for (AccessibilityElement *text_element : text_elements) {
- RID rid = rid_owner.make_rid(text_element);
- root_ae->children.push_back(rid);
- wd->update.insert(rid);
- }
- return root_rid;
- }
- bool AccessibilityDriverAccessKit::accessibility_has_element(const RID &p_id) const {
- return rid_owner.owns(p_id);
- }
- void AccessibilityDriverAccessKit::_free_recursive(WindowData *p_wd, const RID &p_id) {
- if (p_wd && p_wd->update.has(p_id)) {
- p_wd->update.erase(p_id);
- }
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- for (const RID &rid : ae->children) {
- _free_recursive(p_wd, rid);
- }
- if (ae->node) {
- accesskit_node_free(ae->node);
- }
- memdelete(ae);
- rid_owner.free(p_id);
- }
- void AccessibilityDriverAccessKit::accessibility_free_element(const RID &p_id) {
- ERR_FAIL_COND_MSG(in_accessibility_update, "Element can't be removed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- if (ae) {
- WindowData *wd = windows.getptr(ae->window_id);
- AccessibilityElement *parent_ae = rid_owner.get_or_null(ae->parent);
- if (parent_ae) {
- parent_ae->children.erase(p_id);
- }
- _free_recursive(wd, p_id);
- }
- }
- void AccessibilityDriverAccessKit::accessibility_element_set_meta(const RID &p_id, const Variant &p_meta) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- ae->meta = p_meta;
- }
- Variant AccessibilityDriverAccessKit::accessibility_element_get_meta(const RID &p_id) const {
- const AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL_V(ae, Variant());
- return ae->meta;
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_focus(const RID &p_id) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- if (p_id.is_valid() && rid_owner.owns(p_id)) {
- focus = p_id;
- } else {
- focus = RID();
- }
- }
- RID AccessibilityDriverAccessKit::accessibility_get_window_root(DisplayServer::WindowID p_window_id) const {
- const WindowData *wd = windows.getptr(p_window_id);
- ERR_FAIL_NULL_V(wd, RID());
- return wd->root_id;
- }
- accesskit_tree_update *AccessibilityDriverAccessKit::_accessibility_build_tree_update(void *p_user_data) {
- DisplayServer::WindowID window_id = (DisplayServer::WindowID)(size_t)p_user_data;
- ERR_FAIL_COND_V(!singleton->windows.has(window_id), nullptr);
- WindowData &wd = singleton->windows[window_id];
- singleton->in_accessibility_update = true;
- if (singleton->update_cb.is_valid()) {
- singleton->update_cb.call(window_id);
- }
- singleton->in_accessibility_update = false;
- AccessibilityElement *focus_ae = singleton->rid_owner.get_or_null(singleton->focus);
- uint32_t update_size = wd.update.size();
- accesskit_node_id ac_focus = (accesskit_node_id)wd.root_id.get_id();
- if (focus_ae && focus_ae->window_id == window_id) {
- ac_focus = (accesskit_node_id)singleton->focus.get_id();
- }
- accesskit_tree_update *tree_update = (update_size > 0) ? accesskit_tree_update_with_capacity_and_focus(update_size, ac_focus) : accesskit_tree_update_with_focus(ac_focus);
- for (const RID &rid : wd.update) {
- AccessibilityElement *ae = singleton->rid_owner.get_or_null(rid);
- if (ae && ae->node) {
- for (const RID &child_rid : ae->children) {
- accesskit_node_push_child(ae->node, (accesskit_node_id)child_rid.get_id());
- }
- accesskit_tree_update_push_node(tree_update, (accesskit_node_id)rid.get_id(), ae->node);
- ae->node = nullptr;
- }
- }
- wd.update.clear();
- return tree_update;
- }
- void AccessibilityDriverAccessKit::accessibility_update_if_active(const Callable &p_callable) {
- ERR_FAIL_COND(!p_callable.is_valid());
- update_cb = p_callable;
- for (KeyValue<DisplayServer::WindowID, WindowData> &window : windows) {
- #ifdef WINDOWS_ENABLED
- accesskit_windows_queued_events *events = accesskit_windows_subclassing_adapter_update_if_active(window.value.adapter, _accessibility_build_tree_update, (void *)(size_t)window.key);
- if (events) {
- accesskit_windows_queued_events_raise(events);
- }
- #endif
- #ifdef MACOS_ENABLED
- accesskit_macos_queued_events *events = accesskit_macos_subclassing_adapter_update_if_active(window.value.adapter, _accessibility_build_tree_update, (void *)(size_t)window.key);
- if (events) {
- accesskit_macos_queued_events_raise(events);
- }
- #endif
- #ifdef LINUXBSD_ENABLED
- accesskit_unix_adapter_update_if_active(window.value.adapter, _accessibility_build_tree_update, (void *)(size_t)window.key);
- #endif
- }
- update_cb = Callable();
- }
- _FORCE_INLINE_ void AccessibilityDriverAccessKit::_ensure_node(const RID &p_id, AccessibilityElement *p_ae) {
- if (unlikely(!p_ae->node)) {
- WindowData *wd = windows.getptr(p_ae->window_id);
- ERR_FAIL_NULL(wd);
- wd->update.insert(p_id);
- p_ae->node = accesskit_node_new(p_ae->role);
- }
- }
- void AccessibilityDriverAccessKit::accessibility_set_window_rect(DisplayServer::WindowID p_window_id, const Rect2 &p_rect_out, const Rect2 &p_rect_in) {
- #ifdef LINUXBSD_ENABLED
- const WindowData *wd = windows.getptr(p_window_id);
- ERR_FAIL_NULL(wd);
- accesskit_rect outer_bounds = { p_rect_out.position.x, p_rect_out.position.y, p_rect_out.position.x + p_rect_out.size.width, p_rect_out.position.y + p_rect_out.size.height };
- accesskit_rect inner_bounds = { p_rect_in.position.x, p_rect_in.position.y, p_rect_in.position.x + p_rect_in.size.width, p_rect_in.position.y + p_rect_in.size.height };
- accesskit_unix_adapter_set_root_window_bounds(wd->adapter, outer_bounds, inner_bounds);
- #endif
- }
- void AccessibilityDriverAccessKit::accessibility_set_window_focused(DisplayServer::WindowID p_window_id, bool p_focused) {
- const WindowData *wd = windows.getptr(p_window_id);
- ERR_FAIL_NULL(wd);
- #ifdef LINUXBSD_ENABLED
- accesskit_unix_adapter_update_window_focus_state(wd->adapter, p_focused);
- #endif
- #ifdef MACOS_ENABLED
- accesskit_macos_queued_events *events = accesskit_macos_subclassing_adapter_update_view_focus_state(wd->adapter, p_focused);
- if (events != nullptr) {
- accesskit_macos_queued_events_raise(events);
- }
- #endif
- // Note: On Windows, the subclassing adapter takes care of this.
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_role(const RID &p_id, DisplayServer::AccessibilityRole p_role) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- if (ae->role == _accessibility_role(p_role)) {
- return;
- }
- ae->role = _accessibility_role(p_role);
- _ensure_node(p_id, ae);
- accesskit_node_set_role(ae->node, ae->role);
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_name(const RID &p_id, const String &p_name) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- ae->name = p_name;
- String full_name = ae->name + " " + ae->name_extra_info;
- if (!full_name.is_empty()) {
- accesskit_node_set_label(ae->node, full_name.utf8().ptr());
- } else {
- accesskit_node_clear_label(ae->node);
- }
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_extra_info(const RID &p_id, const String &p_name_extra_info) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- ae->name_extra_info = p_name_extra_info;
- String full_name = ae->name + " " + ae->name_extra_info;
- if (!full_name.is_empty()) {
- accesskit_node_set_label(ae->node, full_name.utf8().ptr());
- } else {
- accesskit_node_clear_label(ae->node);
- }
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_description(const RID &p_id, const String &p_description) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- if (!p_description.is_empty()) {
- accesskit_node_set_description(ae->node, p_description.utf8().ptr());
- } else {
- accesskit_node_clear_description(ae->node);
- }
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_value(const RID &p_id, const String &p_value) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- if (!p_value.is_empty()) {
- Vector<uint8_t> ch_length;
- accesskit_node_set_value(ae->node, p_value.utf8(&ch_length).ptr());
- accesskit_node_set_character_lengths(ae->node, ch_length.size(), ch_length.ptr());
- } else {
- accesskit_node_clear_value(ae->node);
- accesskit_node_clear_character_lengths(ae->node);
- }
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_tooltip(const RID &p_id, const String &p_tooltip) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- if (!p_tooltip.is_empty()) {
- accesskit_node_set_tooltip(ae->node, p_tooltip.utf8().ptr());
- } else {
- accesskit_node_clear_tooltip(ae->node);
- }
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_bounds(const RID &p_id, const Rect2 &p_rect) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_rect rect;
- rect.x0 = p_rect.position.x;
- rect.y0 = p_rect.position.y;
- rect.x1 = p_rect.position.x + p_rect.size.x;
- rect.y1 = p_rect.position.y + p_rect.size.y;
- accesskit_node_set_bounds(ae->node, rect);
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_transform(const RID &p_id, const Transform2D &p_transform) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_affine transform = { p_transform.columns[0][0], p_transform.columns[0][1], p_transform.columns[1][0], p_transform.columns[1][1], p_transform.columns[2][0], p_transform.columns[2][1] };
- accesskit_node_set_transform(ae->node, transform);
- }
- void AccessibilityDriverAccessKit::accessibility_update_add_child(const RID &p_id, const RID &p_child_id) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- AccessibilityElement *other_ae = rid_owner.get_or_null(p_child_id);
- ERR_FAIL_NULL(other_ae);
- ERR_FAIL_COND(other_ae->window_id != ae->window_id);
- _ensure_node(p_id, ae);
- accesskit_node_push_child(ae->node, (accesskit_node_id)p_child_id.get_id());
- }
- void AccessibilityDriverAccessKit::accessibility_update_add_related_controls(const RID &p_id, const RID &p_related_id) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);
- ERR_FAIL_NULL(other_ae);
- ERR_FAIL_COND(other_ae->window_id != ae->window_id);
- _ensure_node(p_id, ae);
- accesskit_node_push_controlled(ae->node, (accesskit_node_id)p_related_id.get_id());
- }
- void AccessibilityDriverAccessKit::accessibility_update_add_related_details(const RID &p_id, const RID &p_related_id) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);
- ERR_FAIL_NULL(other_ae);
- ERR_FAIL_COND(other_ae->window_id != ae->window_id);
- _ensure_node(p_id, ae);
- accesskit_node_push_detail(ae->node, (accesskit_node_id)p_related_id.get_id());
- }
- void AccessibilityDriverAccessKit::accessibility_update_add_related_described_by(const RID &p_id, const RID &p_related_id) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);
- ERR_FAIL_NULL(other_ae);
- ERR_FAIL_COND(other_ae->window_id != ae->window_id);
- _ensure_node(p_id, ae);
- accesskit_node_push_described_by(ae->node, (accesskit_node_id)p_related_id.get_id());
- }
- void AccessibilityDriverAccessKit::accessibility_update_add_related_flow_to(const RID &p_id, const RID &p_related_id) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);
- ERR_FAIL_NULL(other_ae);
- ERR_FAIL_COND(other_ae->window_id != ae->window_id);
- _ensure_node(p_id, ae);
- accesskit_node_push_flow_to(ae->node, (accesskit_node_id)p_related_id.get_id());
- }
- void AccessibilityDriverAccessKit::accessibility_update_add_related_labeled_by(const RID &p_id, const RID &p_related_id) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);
- ERR_FAIL_NULL(other_ae);
- ERR_FAIL_COND(other_ae->window_id != ae->window_id);
- _ensure_node(p_id, ae);
- accesskit_node_push_labelled_by(ae->node, (accesskit_node_id)p_related_id.get_id());
- }
- void AccessibilityDriverAccessKit::accessibility_update_add_related_radio_group(const RID &p_id, const RID &p_related_id) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);
- ERR_FAIL_NULL(other_ae);
- ERR_FAIL_COND(other_ae->window_id != ae->window_id);
- _ensure_node(p_id, ae);
- accesskit_node_push_to_radio_group(ae->node, (accesskit_node_id)p_related_id.get_id());
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_active_descendant(const RID &p_id, const RID &p_other_id) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- AccessibilityElement *other_ae = rid_owner.get_or_null(p_other_id);
- ERR_FAIL_NULL(other_ae);
- ERR_FAIL_COND(other_ae->window_id != ae->window_id);
- _ensure_node(p_id, ae);
- accesskit_node_set_active_descendant(ae->node, (accesskit_node_id)p_other_id.get_id());
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_next_on_line(const RID &p_id, const RID &p_other_id) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- AccessibilityElement *other_ae = rid_owner.get_or_null(p_other_id);
- ERR_FAIL_NULL(other_ae);
- ERR_FAIL_COND(other_ae->window_id != ae->window_id);
- _ensure_node(p_id, ae);
- accesskit_node_set_next_on_line(ae->node, (accesskit_node_id)p_other_id.get_id());
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_previous_on_line(const RID &p_id, const RID &p_other_id) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- AccessibilityElement *other_ae = rid_owner.get_or_null(p_other_id);
- ERR_FAIL_NULL(other_ae);
- ERR_FAIL_COND(other_ae->window_id != ae->window_id);
- _ensure_node(p_id, ae);
- accesskit_node_set_previous_on_line(ae->node, (accesskit_node_id)p_other_id.get_id());
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_member_of(const RID &p_id, const RID &p_group_id) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- AccessibilityElement *other_ae = rid_owner.get_or_null(p_group_id);
- ERR_FAIL_NULL(other_ae);
- ERR_FAIL_COND(other_ae->window_id != ae->window_id);
- _ensure_node(p_id, ae);
- accesskit_node_set_member_of(ae->node, (accesskit_node_id)p_group_id.get_id());
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_in_page_link_target(const RID &p_id, const RID &p_other_id) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- AccessibilityElement *other_ae = rid_owner.get_or_null(p_other_id);
- ERR_FAIL_NULL(other_ae);
- ERR_FAIL_COND(other_ae->window_id != ae->window_id);
- _ensure_node(p_id, ae);
- accesskit_node_set_in_page_link_target(ae->node, (accesskit_node_id)p_other_id.get_id());
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_error_message(const RID &p_id, const RID &p_other_id) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- AccessibilityElement *other_ae = rid_owner.get_or_null(p_other_id);
- ERR_FAIL_NULL(other_ae);
- ERR_FAIL_COND(other_ae->window_id != ae->window_id);
- _ensure_node(p_id, ae);
- accesskit_node_set_error_message(ae->node, (accesskit_node_id)p_other_id.get_id());
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_live(const RID &p_id, DisplayServer::AccessibilityLiveMode p_live) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- switch (p_live) {
- case DisplayServer::AccessibilityLiveMode::LIVE_OFF: {
- accesskit_node_set_live(ae->node, ACCESSKIT_LIVE_OFF);
- } break;
- case DisplayServer::AccessibilityLiveMode::LIVE_POLITE: {
- accesskit_node_set_live(ae->node, ACCESSKIT_LIVE_POLITE);
- } break;
- case DisplayServer::AccessibilityLiveMode::LIVE_ASSERTIVE: {
- accesskit_node_set_live(ae->node, ACCESSKIT_LIVE_ASSERTIVE);
- } break;
- }
- }
- void AccessibilityDriverAccessKit::accessibility_update_add_action(const RID &p_id, DisplayServer::AccessibilityAction p_action, const Callable &p_callable) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- ae->actions[_accessibility_action(p_action)] = p_callable;
- accesskit_node_add_action(ae->node, _accessibility_action(p_action));
- }
- void AccessibilityDriverAccessKit::accessibility_update_add_custom_action(const RID &p_id, int p_action_id, const String &p_action_description) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- if (!p_action_description.is_empty()) {
- accesskit_custom_action ca = accesskit_custom_action_new(p_action_id, p_action_description.utf8().ptr());
- accesskit_node_push_custom_action(ae->node, ca);
- } else {
- String cs_name = vformat("Custom Action %d", p_action_id);
- accesskit_custom_action ca = accesskit_custom_action_new(p_action_id, cs_name.utf8().ptr());
- accesskit_node_push_custom_action(ae->node, ca);
- }
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_table_row_count(const RID &p_id, int p_count) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_row_count(ae->node, p_count);
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_table_column_count(const RID &p_id, int p_count) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_column_count(ae->node, p_count);
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_table_row_index(const RID &p_id, int p_index) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_row_index(ae->node, p_index);
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_table_column_index(const RID &p_id, int p_index) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_column_index(ae->node, p_index);
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_table_cell_position(const RID &p_id, int p_row_index, int p_column_index) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_row_index(ae->node, p_row_index);
- accesskit_node_set_column_index(ae->node, p_column_index);
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_table_cell_span(const RID &p_id, int p_row_span, int p_column_span) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_row_span(ae->node, p_row_span);
- accesskit_node_set_column_span(ae->node, p_column_span);
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_list_item_count(const RID &p_id, int p_size) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_size_of_set(ae->node, p_size);
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_list_item_index(const RID &p_id, int p_index) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_position_in_set(ae->node, p_index);
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_list_item_level(const RID &p_id, int p_level) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_level(ae->node, p_level);
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_list_item_selected(const RID &p_id, bool p_selected) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_selected(ae->node, p_selected);
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_list_item_expanded(const RID &p_id, bool p_expanded) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_expanded(ae->node, p_expanded);
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_popup_type(const RID &p_id, DisplayServer::AccessibilityPopupType p_popup) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- switch (p_popup) {
- case DisplayServer::AccessibilityPopupType::POPUP_MENU: {
- accesskit_node_set_has_popup(ae->node, ACCESSKIT_HAS_POPUP_MENU);
- } break;
- case DisplayServer::AccessibilityPopupType::POPUP_LIST: {
- accesskit_node_set_has_popup(ae->node, ACCESSKIT_HAS_POPUP_LISTBOX);
- } break;
- case DisplayServer::AccessibilityPopupType::POPUP_TREE: {
- accesskit_node_set_has_popup(ae->node, ACCESSKIT_HAS_POPUP_TREE);
- } break;
- case DisplayServer::AccessibilityPopupType::POPUP_DIALOG: {
- accesskit_node_set_has_popup(ae->node, ACCESSKIT_HAS_POPUP_DIALOG);
- } break;
- }
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_checked(const RID &p_id, bool p_checekd) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- if (p_checekd) {
- accesskit_node_set_toggled(ae->node, ACCESSKIT_TOGGLED_TRUE);
- } else {
- accesskit_node_set_toggled(ae->node, ACCESSKIT_TOGGLED_FALSE);
- }
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_num_value(const RID &p_id, double p_position) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_numeric_value(ae->node, p_position);
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_num_range(const RID &p_id, double p_min, double p_max) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_min_numeric_value(ae->node, p_min);
- accesskit_node_set_max_numeric_value(ae->node, p_max);
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_num_step(const RID &p_id, double p_step) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_numeric_value_step(ae->node, p_step);
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_num_jump(const RID &p_id, double p_jump) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_numeric_value_jump(ae->node, p_jump);
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_scroll_x(const RID &p_id, double p_position) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_scroll_x(ae->node, p_position);
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_scroll_x_range(const RID &p_id, double p_min, double p_max) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_scroll_x_min(ae->node, p_min);
- accesskit_node_set_scroll_x_max(ae->node, p_max);
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_scroll_y(const RID &p_id, double p_position) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_scroll_y(ae->node, p_position);
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_scroll_y_range(const RID &p_id, double p_min, double p_max) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_scroll_y_min(ae->node, p_min);
- accesskit_node_set_scroll_y_max(ae->node, p_max);
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_text_decorations(const RID &p_id, bool p_underline, bool p_strikethrough, bool p_overline) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- if (p_underline) {
- accesskit_node_set_underline(ae->node, ACCESSKIT_TEXT_DECORATION_SOLID);
- } else {
- accesskit_node_clear_underline(ae->node);
- }
- if (p_overline) {
- accesskit_node_set_overline(ae->node, ACCESSKIT_TEXT_DECORATION_SOLID);
- } else {
- accesskit_node_clear_overline(ae->node);
- }
- if (p_strikethrough) {
- accesskit_node_set_strikethrough(ae->node, ACCESSKIT_TEXT_DECORATION_SOLID);
- } else {
- accesskit_node_clear_strikethrough(ae->node);
- }
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_text_align(const RID &p_id, HorizontalAlignment p_align) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- switch (p_align) {
- case HORIZONTAL_ALIGNMENT_LEFT: {
- accesskit_node_set_text_align(ae->node, ACCESSKIT_TEXT_ALIGN_LEFT);
- } break;
- case HORIZONTAL_ALIGNMENT_CENTER: {
- accesskit_node_set_text_align(ae->node, ACCESSKIT_TEXT_ALIGN_RIGHT);
- } break;
- case HORIZONTAL_ALIGNMENT_RIGHT: {
- accesskit_node_set_text_align(ae->node, ACCESSKIT_TEXT_ALIGN_CENTER);
- } break;
- case HORIZONTAL_ALIGNMENT_FILL: {
- accesskit_node_set_text_align(ae->node, ACCESSKIT_TEXT_ALIGN_JUSTIFY);
- } break;
- }
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_text_selection(const RID &p_id, const RID &p_text_start_id, int p_start_char, const RID &p_text_end_id, int p_end_char) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- AccessibilityElement *start_ae = rid_owner.get_or_null(p_text_start_id);
- ERR_FAIL_NULL(start_ae);
- ERR_FAIL_COND(start_ae->window_id != ae->window_id);
- AccessibilityElement *end_ae = rid_owner.get_or_null(p_text_end_id);
- ERR_FAIL_NULL(end_ae);
- ERR_FAIL_COND(end_ae->window_id != ae->window_id);
- int start_pos = p_start_char;
- int end_pos = p_end_char;
- RID start_rid;
- RID end_rid;
- for (const RID &rid : start_ae->children) {
- const AccessibilityElement *child_ae = rid_owner.get_or_null(rid);
- if (child_ae && child_ae->role == ACCESSKIT_ROLE_TEXT_RUN) {
- if (p_start_char >= child_ae->run.x && p_start_char <= child_ae->run.y) {
- start_rid = rid;
- start_pos = p_start_char - child_ae->run.x;
- break;
- }
- }
- }
- for (const RID &rid : end_ae->children) {
- const AccessibilityElement *child_ae = rid_owner.get_or_null(rid);
- if (child_ae && child_ae->role == ACCESSKIT_ROLE_TEXT_RUN) {
- if (p_end_char >= child_ae->run.x && p_end_char <= child_ae->run.y) {
- end_rid = rid;
- end_pos = p_end_char - child_ae->run.x;
- break;
- }
- }
- }
- ERR_FAIL_COND(start_rid.is_null() && end_rid.is_null());
- _ensure_node(p_id, ae);
- accesskit_text_selection sel;
- sel.anchor.node = (accesskit_node_id)start_rid.get_id();
- sel.anchor.character_index = start_pos;
- sel.focus.node = (accesskit_node_id)end_rid.get_id();
- sel.focus.character_index = end_pos;
- accesskit_node_set_text_selection(ae->node, sel);
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_flag(const RID &p_id, DisplayServer::AccessibilityFlags p_flag, bool p_value) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- switch (p_flag) {
- case DisplayServer::AccessibilityFlags::FLAG_HIDDEN: {
- if (p_value) {
- accesskit_node_set_hidden(ae->node);
- } else {
- accesskit_node_clear_hidden(ae->node);
- }
- } break;
- case DisplayServer::AccessibilityFlags::FLAG_MULTISELECTABLE: {
- if (p_value) {
- accesskit_node_set_multiselectable(ae->node);
- } else {
- accesskit_node_clear_multiselectable(ae->node);
- }
- } break;
- case DisplayServer::AccessibilityFlags::FLAG_REQUIRED: {
- if (p_value) {
- accesskit_node_set_required(ae->node);
- } else {
- accesskit_node_clear_required(ae->node);
- }
- } break;
- case DisplayServer::AccessibilityFlags::FLAG_VISITED: {
- if (p_value) {
- accesskit_node_set_visited(ae->node);
- } else {
- accesskit_node_clear_visited(ae->node);
- }
- } break;
- case DisplayServer::AccessibilityFlags::FLAG_BUSY: {
- if (p_value) {
- accesskit_node_set_busy(ae->node);
- } else {
- accesskit_node_clear_busy(ae->node);
- }
- } break;
- case DisplayServer::AccessibilityFlags::FLAG_MODAL: {
- if (p_value) {
- accesskit_node_set_modal(ae->node);
- } else {
- accesskit_node_clear_modal(ae->node);
- }
- } break;
- case DisplayServer::AccessibilityFlags::FLAG_TOUCH_PASSTHROUGH: {
- if (p_value) {
- accesskit_node_set_touch_transparent(ae->node);
- } else {
- accesskit_node_clear_touch_transparent(ae->node);
- }
- } break;
- case DisplayServer::AccessibilityFlags::FLAG_READONLY: {
- if (p_value) {
- accesskit_node_set_read_only(ae->node);
- } else {
- accesskit_node_clear_read_only(ae->node);
- }
- } break;
- case DisplayServer::AccessibilityFlags::FLAG_DISABLED: {
- if (p_value) {
- accesskit_node_set_disabled(ae->node);
- } else {
- accesskit_node_clear_disabled(ae->node);
- }
- } break;
- case DisplayServer::AccessibilityFlags::FLAG_CLIPS_CHILDREN: {
- if (p_value) {
- accesskit_node_set_clips_children(ae->node);
- } else {
- accesskit_node_clear_clips_children(ae->node);
- }
- } break;
- }
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_classname(const RID &p_id, const String &p_classname) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- if (!p_classname.is_empty()) {
- accesskit_node_set_class_name(ae->node, p_classname.utf8().ptr());
- } else {
- accesskit_node_clear_class_name(ae->node);
- }
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_placeholder(const RID &p_id, const String &p_placeholder) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- if (!p_placeholder.is_empty()) {
- accesskit_node_set_placeholder(ae->node, p_placeholder.utf8().ptr());
- } else {
- accesskit_node_clear_placeholder(ae->node);
- }
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_language(const RID &p_id, const String &p_language) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_language(ae->node, p_language.utf8().ptr());
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_text_orientation(const RID &p_id, bool p_vertical) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- if (p_vertical) {
- accesskit_node_set_text_direction(ae->node, ACCESSKIT_TEXT_DIRECTION_TOP_TO_BOTTOM);
- } else {
- accesskit_node_set_text_direction(ae->node, ACCESSKIT_TEXT_DIRECTION_LEFT_TO_RIGHT);
- }
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_list_orientation(const RID &p_id, bool p_vertical) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- if (p_vertical) {
- accesskit_node_set_orientation(ae->node, ACCESSKIT_ORIENTATION_VERTICAL);
- } else {
- accesskit_node_set_orientation(ae->node, ACCESSKIT_ORIENTATION_HORIZONTAL);
- }
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_shortcut(const RID &p_id, const String &p_shortcut) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- if (!p_shortcut.is_empty()) {
- accesskit_node_set_keyboard_shortcut(ae->node, p_shortcut.utf8().ptr());
- } else {
- accesskit_node_clear_keyboard_shortcut(ae->node);
- }
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_url(const RID &p_id, const String &p_url) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- if (!p_url.is_empty()) {
- accesskit_node_set_url(ae->node, p_url.utf8().ptr());
- } else {
- accesskit_node_clear_url(ae->node);
- }
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_role_description(const RID &p_id, const String &p_description) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- if (!p_description.is_empty()) {
- accesskit_node_set_role_description(ae->node, p_description.utf8().ptr());
- } else {
- accesskit_node_clear_role_description(ae->node);
- }
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_state_description(const RID &p_id, const String &p_description) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- if (!p_description.is_empty()) {
- accesskit_node_set_state_description(ae->node, p_description.utf8().ptr());
- } else {
- accesskit_node_clear_state_description(ae->node);
- }
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_color_value(const RID &p_id, const Color &p_color) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_color_value(ae->node, p_color.to_rgba32());
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_background_color(const RID &p_id, const Color &p_color) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_background_color(ae->node, p_color.to_rgba32());
- }
- void AccessibilityDriverAccessKit::accessibility_update_set_foreground_color(const RID &p_id, const Color &p_color) {
- ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
- AccessibilityElement *ae = rid_owner.get_or_null(p_id);
- ERR_FAIL_NULL(ae);
- _ensure_node(p_id, ae);
- accesskit_node_set_foreground_color(ae->node, p_color.to_rgba32());
- }
- Error AccessibilityDriverAccessKit::init() {
- #ifdef ACCESSKIT_DYNAMIC
- #ifdef DEBUG_ENABLED
- int dylibloader_verbose = 1;
- #else
- int dylibloader_verbose = 0;
- #endif
- void *library_handle = nullptr;
- String path;
- String arch = Engine::get_singleton()->get_architecture_name();
- #ifdef LINUXBSD_ENABLED
- path = OS::get_singleton()->get_executable_path().get_base_dir().path_join("libaccesskit." + arch + ".so");
- if (!FileAccess::exists(path)) {
- path = OS::get_singleton()->get_executable_path().get_base_dir().path_join("../lib").path_join("libaccesskit." + arch + ".so");
- }
- if (!FileAccess::exists(path)) {
- path = OS::get_singleton()->get_executable_path().get_base_dir().path_join("libaccesskit.so");
- }
- if (!FileAccess::exists(path)) {
- path = OS::get_singleton()->get_executable_path().get_base_dir().path_join("../lib").path_join("libaccesskit.so");
- }
- if (!FileAccess::exists(path)) {
- return ERR_CANT_CREATE;
- }
- #endif
- #ifdef MACOS_ENABLED
- path = OS::get_singleton()->get_executable_path().get_base_dir().path_join("libaccesskit." + arch + ".dylib");
- if (!FileAccess::exists(path)) {
- path = OS::get_singleton()->get_executable_path().get_base_dir().path_join("../Frameworks").path_join("libaccesskit." + arch + ".dylib");
- }
- if (!FileAccess::exists(path)) {
- path = OS::get_singleton()->get_executable_path().get_base_dir().path_join("libaccesskit.dylib");
- }
- if (!FileAccess::exists(path)) {
- path = OS::get_singleton()->get_executable_path().get_base_dir().path_join("../Frameworks").path_join("libaccesskit.dylib");
- }
- if (!FileAccess::exists(path)) {
- return ERR_CANT_CREATE;
- }
- #endif
- #ifdef WINDOWS_ENABLED
- path = OS::get_singleton()->get_executable_path().get_base_dir().path_join("accesskit." + arch + ".dll");
- if (!FileAccess::exists(path)) {
- path = OS::get_singleton()->get_executable_path().get_base_dir().path_join("accesskit.dll");
- }
- if (!FileAccess::exists(path)) {
- return ERR_CANT_CREATE;
- }
- #endif
- Error err = OS::get_singleton()->open_dynamic_library(path, library_handle);
- if (err == OK && initialize_libaccesskit(dylibloader_verbose, library_handle) == 0) {
- print_verbose("AccessKit loaded.");
- } else {
- return ERR_CANT_CREATE;
- }
- #endif
- #ifdef MACOS_ENABLED
- //accesskit_macos_add_focus_forwarder_to_window_class("GodotWindow");
- #endif
- return OK;
- }
- AccessibilityDriverAccessKit::AccessibilityDriverAccessKit() {
- singleton = this;
- role_map[DisplayServer::AccessibilityRole::ROLE_UNKNOWN] = ACCESSKIT_ROLE_UNKNOWN;
- role_map[DisplayServer::AccessibilityRole::ROLE_DEFAULT_BUTTON] = ACCESSKIT_ROLE_DEFAULT_BUTTON;
- role_map[DisplayServer::AccessibilityRole::ROLE_AUDIO] = ACCESSKIT_ROLE_AUDIO;
- role_map[DisplayServer::AccessibilityRole::ROLE_VIDEO] = ACCESSKIT_ROLE_VIDEO;
- role_map[DisplayServer::AccessibilityRole::ROLE_STATIC_TEXT] = ACCESSKIT_ROLE_LABEL;
- role_map[DisplayServer::AccessibilityRole::ROLE_CONTAINER] = ACCESSKIT_ROLE_GENERIC_CONTAINER;
- role_map[DisplayServer::AccessibilityRole::ROLE_PANEL] = ACCESSKIT_ROLE_PANE;
- role_map[DisplayServer::AccessibilityRole::ROLE_BUTTON] = ACCESSKIT_ROLE_BUTTON;
- role_map[DisplayServer::AccessibilityRole::ROLE_LINK] = ACCESSKIT_ROLE_LINK;
- role_map[DisplayServer::AccessibilityRole::ROLE_CHECK_BOX] = ACCESSKIT_ROLE_CHECK_BOX;
- role_map[DisplayServer::AccessibilityRole::ROLE_RADIO_BUTTON] = ACCESSKIT_ROLE_RADIO_BUTTON;
- role_map[DisplayServer::AccessibilityRole::ROLE_CHECK_BUTTON] = ACCESSKIT_ROLE_SWITCH;
- role_map[DisplayServer::AccessibilityRole::ROLE_SCROLL_BAR] = ACCESSKIT_ROLE_SCROLL_BAR;
- role_map[DisplayServer::AccessibilityRole::ROLE_SCROLL_VIEW] = ACCESSKIT_ROLE_SCROLL_VIEW;
- role_map[DisplayServer::AccessibilityRole::ROLE_SPLITTER] = ACCESSKIT_ROLE_SPLITTER;
- role_map[DisplayServer::AccessibilityRole::ROLE_SLIDER] = ACCESSKIT_ROLE_SLIDER;
- role_map[DisplayServer::AccessibilityRole::ROLE_SPIN_BUTTON] = ACCESSKIT_ROLE_SPIN_BUTTON;
- role_map[DisplayServer::AccessibilityRole::ROLE_PROGRESS_INDICATOR] = ACCESSKIT_ROLE_PROGRESS_INDICATOR;
- role_map[DisplayServer::AccessibilityRole::ROLE_TEXT_FIELD] = ACCESSKIT_ROLE_TEXT_INPUT;
- role_map[DisplayServer::AccessibilityRole::ROLE_MULTILINE_TEXT_FIELD] = ACCESSKIT_ROLE_MULTILINE_TEXT_INPUT;
- role_map[DisplayServer::AccessibilityRole::ROLE_COLOR_PICKER] = ACCESSKIT_ROLE_COLOR_WELL;
- role_map[DisplayServer::AccessibilityRole::ROLE_TABLE] = ACCESSKIT_ROLE_TABLE;
- role_map[DisplayServer::AccessibilityRole::ROLE_CELL] = ACCESSKIT_ROLE_CELL;
- role_map[DisplayServer::AccessibilityRole::ROLE_ROW] = ACCESSKIT_ROLE_ROW;
- role_map[DisplayServer::AccessibilityRole::ROLE_ROW_GROUP] = ACCESSKIT_ROLE_ROW_GROUP;
- role_map[DisplayServer::AccessibilityRole::ROLE_ROW_HEADER] = ACCESSKIT_ROLE_ROW_HEADER;
- role_map[DisplayServer::AccessibilityRole::ROLE_COLUMN_HEADER] = ACCESSKIT_ROLE_COLUMN_HEADER;
- role_map[DisplayServer::AccessibilityRole::ROLE_TREE] = ACCESSKIT_ROLE_TREE;
- role_map[DisplayServer::AccessibilityRole::ROLE_TREE_ITEM] = ACCESSKIT_ROLE_TREE_ITEM;
- role_map[DisplayServer::AccessibilityRole::ROLE_LIST] = ACCESSKIT_ROLE_LIST;
- role_map[DisplayServer::AccessibilityRole::ROLE_LIST_ITEM] = ACCESSKIT_ROLE_LIST_ITEM;
- role_map[DisplayServer::AccessibilityRole::ROLE_LIST_BOX] = ACCESSKIT_ROLE_LIST_BOX;
- role_map[DisplayServer::AccessibilityRole::ROLE_LIST_BOX_OPTION] = ACCESSKIT_ROLE_LIST_BOX_OPTION;
- role_map[DisplayServer::AccessibilityRole::ROLE_TAB_BAR] = ACCESSKIT_ROLE_TAB_LIST;
- role_map[DisplayServer::AccessibilityRole::ROLE_TAB] = ACCESSKIT_ROLE_TAB;
- role_map[DisplayServer::AccessibilityRole::ROLE_TAB_PANEL] = ACCESSKIT_ROLE_TAB_PANEL;
- role_map[DisplayServer::AccessibilityRole::ROLE_MENU_BAR] = ACCESSKIT_ROLE_MENU_BAR;
- role_map[DisplayServer::AccessibilityRole::ROLE_MENU] = ACCESSKIT_ROLE_MENU;
- role_map[DisplayServer::AccessibilityRole::ROLE_MENU_ITEM] = ACCESSKIT_ROLE_MENU_ITEM;
- role_map[DisplayServer::AccessibilityRole::ROLE_MENU_ITEM_CHECK_BOX] = ACCESSKIT_ROLE_MENU_ITEM_CHECK_BOX;
- role_map[DisplayServer::AccessibilityRole::ROLE_MENU_ITEM_RADIO] = ACCESSKIT_ROLE_MENU_ITEM_RADIO;
- role_map[DisplayServer::AccessibilityRole::ROLE_IMAGE] = ACCESSKIT_ROLE_IMAGE;
- role_map[DisplayServer::AccessibilityRole::ROLE_WINDOW] = ACCESSKIT_ROLE_WINDOW;
- role_map[DisplayServer::AccessibilityRole::ROLE_TITLE_BAR] = ACCESSKIT_ROLE_TITLE_BAR;
- role_map[DisplayServer::AccessibilityRole::ROLE_DIALOG] = ACCESSKIT_ROLE_DIALOG;
- role_map[DisplayServer::AccessibilityRole::ROLE_TOOLTIP] = ACCESSKIT_ROLE_TOOLTIP;
- action_map[DisplayServer::AccessibilityAction::ACTION_CLICK] = ACCESSKIT_ACTION_CLICK;
- action_map[DisplayServer::AccessibilityAction::ACTION_FOCUS] = ACCESSKIT_ACTION_FOCUS;
- action_map[DisplayServer::AccessibilityAction::ACTION_BLUR] = ACCESSKIT_ACTION_BLUR;
- action_map[DisplayServer::AccessibilityAction::ACTION_COLLAPSE] = ACCESSKIT_ACTION_COLLAPSE;
- action_map[DisplayServer::AccessibilityAction::ACTION_EXPAND] = ACCESSKIT_ACTION_EXPAND;
- action_map[DisplayServer::AccessibilityAction::ACTION_DECREMENT] = ACCESSKIT_ACTION_DECREMENT;
- action_map[DisplayServer::AccessibilityAction::ACTION_INCREMENT] = ACCESSKIT_ACTION_INCREMENT;
- action_map[DisplayServer::AccessibilityAction::ACTION_HIDE_TOOLTIP] = ACCESSKIT_ACTION_HIDE_TOOLTIP;
- action_map[DisplayServer::AccessibilityAction::ACTION_SHOW_TOOLTIP] = ACCESSKIT_ACTION_SHOW_TOOLTIP;
- //action_map[DisplayServer::AccessibilityAction::ACTION_INVALIDATE_TREE] = ACCESSKIT_ACTION_INVALIDATE_TREE;
- //action_map[DisplayServer::AccessibilityAction::ACTION_LOAD_INLINE_TEXT_BOXES] = ACCESSKIT_ACTION_LOAD_INLINE_TEXT_BOXES;
- action_map[DisplayServer::AccessibilityAction::ACTION_SET_TEXT_SELECTION] = ACCESSKIT_ACTION_SET_TEXT_SELECTION;
- action_map[DisplayServer::AccessibilityAction::ACTION_REPLACE_SELECTED_TEXT] = ACCESSKIT_ACTION_REPLACE_SELECTED_TEXT;
- action_map[DisplayServer::AccessibilityAction::ACTION_SCROLL_BACKWARD] = ACCESSKIT_ACTION_SCROLL_UP;
- action_map[DisplayServer::AccessibilityAction::ACTION_SCROLL_DOWN] = ACCESSKIT_ACTION_SCROLL_DOWN;
- action_map[DisplayServer::AccessibilityAction::ACTION_SCROLL_FORWARD] = ACCESSKIT_ACTION_SCROLL_DOWN;
- action_map[DisplayServer::AccessibilityAction::ACTION_SCROLL_LEFT] = ACCESSKIT_ACTION_SCROLL_LEFT;
- action_map[DisplayServer::AccessibilityAction::ACTION_SCROLL_RIGHT] = ACCESSKIT_ACTION_SCROLL_RIGHT;
- action_map[DisplayServer::AccessibilityAction::ACTION_SCROLL_UP] = ACCESSKIT_ACTION_SCROLL_UP;
- action_map[DisplayServer::AccessibilityAction::ACTION_SCROLL_INTO_VIEW] = ACCESSKIT_ACTION_SCROLL_INTO_VIEW;
- action_map[DisplayServer::AccessibilityAction::ACTION_SCROLL_TO_POINT] = ACCESSKIT_ACTION_SCROLL_TO_POINT;
- action_map[DisplayServer::AccessibilityAction::ACTION_SET_SCROLL_OFFSET] = ACCESSKIT_ACTION_SET_SCROLL_OFFSET;
- //action_map[DisplayServer::AccessibilityAction::ACTION_SET_SEQUENTIAL_FOCUS_NAVIGATION_STARTING_POINT] = ACCESSKIT_ACTION_SET_SEQUENTIAL_FOCUS_NAVIGATION_STARTING_POINT;
- action_map[DisplayServer::AccessibilityAction::ACTION_SET_VALUE] = ACCESSKIT_ACTION_SET_VALUE;
- action_map[DisplayServer::AccessibilityAction::ACTION_SHOW_CONTEXT_MENU] = ACCESSKIT_ACTION_SHOW_CONTEXT_MENU;
- action_map[DisplayServer::AccessibilityAction::ACTION_CUSTOM] = ACCESSKIT_ACTION_CUSTOM_ACTION;
- }
- AccessibilityDriverAccessKit::~AccessibilityDriverAccessKit() {
- singleton = nullptr;
- }
- #endif // ACCESSKIT_ENABLED
|