Path: blob/master/drivers/accesskit/accessibility_server_accesskit.cpp
45997 views
/**************************************************************************/1/* accessibility_server_accesskit.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#ifdef ACCESSKIT_ENABLED3132#include "accessibility_server_accesskit.h"3334#include "servers/text/text_server.h"3536_FORCE_INLINE_ accesskit_role AccessibilityServerAccessKit::_accessibility_role(AccessibilityServerEnums::AccessibilityRole p_role) const {37if (role_map.has(p_role)) {38return role_map[p_role];39}40return ACCESSKIT_ROLE_UNKNOWN;41}4243_FORCE_INLINE_ accesskit_action AccessibilityServerAccessKit::_accessibility_action(AccessibilityServerEnums::AccessibilityAction p_action) const {44if (action_map.has(p_action)) {45return action_map[p_action];46}47return ACCESSKIT_ACTION_CLICK;48}4950bool AccessibilityServerAccessKit::window_create(DisplayServerEnums::WindowID p_window_id, void *p_handle) {51ERR_FAIL_COND_V(windows.has(p_window_id), false);5253WindowData &wd = windows[p_window_id];5455AccessibilityElement *ae = memnew(AccessibilityElement);56ae->role = ACCESSKIT_ROLE_WINDOW;57ae->window_id = p_window_id;58wd.root_id = rid_owner.make_rid(ae);5960#ifdef WINDOWS_ENABLED61wd.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);62#endif63#ifdef MACOS_ENABLED64wd.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);65#endif66#ifdef LINUXBSD_ENABLED67wd.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);68#endif69print_verbose(vformat("Accessibility: window %d adapter created.", p_window_id));7071if (wd.adapter == nullptr) {72memdelete(ae);73rid_owner.free(wd.root_id);74windows.erase(p_window_id);7576return false;77} else {78return true;79}80}8182void AccessibilityServerAccessKit::window_destroy(DisplayServerEnums::WindowID p_window_id) {83WindowData *wd = windows.getptr(p_window_id);84ERR_FAIL_NULL(wd);8586print_verbose(vformat("Accessibility: window %d adapter destroyed.", p_window_id));8788#ifdef WINDOWS_ENABLED89accesskit_windows_subclassing_adapter_free(wd->adapter);90#endif91#ifdef MACOS_ENABLED92accesskit_macos_subclassing_adapter_free(wd->adapter);93#endif94#ifdef LINUXBSD_ENABLED95accesskit_unix_adapter_free(wd->adapter);96#endif97free_element(wd->root_id);9899windows.erase(p_window_id);100}101102void AccessibilityServerAccessKit::_accessibility_deactivation_callback(void *p_user_data) {103DisplayServerEnums::WindowID window_id = (DisplayServerEnums::WindowID)(size_t)p_user_data;104WindowData *wd = static_cast<AccessibilityServerAccessKit *>(get_singleton())->windows.getptr(window_id);105ERR_FAIL_NULL(wd);106107print_verbose(vformat("Accessibility: window %d adapter deactivated.", window_id));108109if (static_cast<AccessibilityServerAccessKit *>(get_singleton())->focus.is_valid()) {110AccessibilityElement *ae = static_cast<AccessibilityServerAccessKit *>(get_singleton())->rid_owner.get_or_null(static_cast<AccessibilityServerAccessKit *>(get_singleton())->focus);111if (ae && ae->window_id == window_id) {112static_cast<AccessibilityServerAccessKit *>(get_singleton())->focus = RID();113}114}115if (wd->deactivate.is_valid()) {116wd->deactivate.call_deferred(); // Should be called on main thread only.117}118119wd->activated = false;120wd->update.clear();121}122123void AccessibilityServerAccessKit::_accessibility_action_callback(struct accesskit_action_request *p_request, void *p_user_data) {124DisplayServerEnums::WindowID window_id = (DisplayServerEnums::WindowID)(size_t)p_user_data;125ERR_FAIL_COND(!static_cast<AccessibilityServerAccessKit *>(get_singleton())->windows.has(window_id));126127RID rid = RID::from_uint64(p_request->target_node);128AccessibilityElement *ae = static_cast<AccessibilityServerAccessKit *>(get_singleton())->rid_owner.get_or_null(rid);129ERR_FAIL_NULL(ae);130131Variant rq_data;132if (!ae->actions.has(p_request->action) && ae->role == ACCESSKIT_ROLE_TEXT_RUN && p_request->action == ACCESSKIT_ACTION_SCROLL_INTO_VIEW) {133AccessibilityElement *root_ae = static_cast<AccessibilityServerAccessKit *>(get_singleton())->rid_owner.get_or_null(ae->parent);134ERR_FAIL_NULL(root_ae);135ae = root_ae;136rq_data = ae->run;137}138139if (ae->actions.has(p_request->action)) {140Callable &cb = ae->actions[p_request->action];141if (cb.is_valid()) {142if (p_request->data.has_value) {143switch (p_request->data.value.tag) {144case ACCESSKIT_ACTION_DATA_CUSTOM_ACTION: {145rq_data = p_request->data.value.custom_action;146} break;147case ACCESSKIT_ACTION_DATA_VALUE: {148rq_data = String::utf8(p_request->data.value.value);149} break;150case ACCESSKIT_ACTION_DATA_NUMERIC_VALUE: {151rq_data = p_request->data.value.numeric_value;152} break;153case ACCESSKIT_ACTION_DATA_SCROLL_HINT: {154switch (p_request->data.value.scroll_hint) {155case ACCESSKIT_SCROLL_HINT_TOP_LEFT: {156rq_data = AccessibilityServerEnums::SCROLL_HINT_TOP_LEFT;157} break;158case ACCESSKIT_SCROLL_HINT_BOTTOM_RIGHT: {159rq_data = AccessibilityServerEnums::SCROLL_HINT_BOTTOM_RIGHT;160} break;161case ACCESSKIT_SCROLL_HINT_TOP_EDGE: {162rq_data = AccessibilityServerEnums::SCROLL_HINT_TOP_EDGE;163} break;164case ACCESSKIT_SCROLL_HINT_BOTTOM_EDGE: {165rq_data = AccessibilityServerEnums::SCROLL_HINT_BOTTOM_EDGE;166} break;167case ACCESSKIT_SCROLL_HINT_LEFT_EDGE: {168rq_data = AccessibilityServerEnums::SCROLL_HINT_LEFT_EDGE;169} break;170case ACCESSKIT_SCROLL_HINT_RIGHT_EDGE: {171rq_data = AccessibilityServerEnums::SCROLL_HINT_RIGHT_EDGE;172} break;173default:174break;175}176} break;177case ACCESSKIT_ACTION_DATA_SCROLL_UNIT: {178if (p_request->data.value.scroll_unit == ACCESSKIT_SCROLL_UNIT_ITEM) {179rq_data = AccessibilityServerEnums::SCROLL_UNIT_ITEM;180} else if (p_request->data.value.scroll_unit == ACCESSKIT_SCROLL_UNIT_PAGE) {181rq_data = AccessibilityServerEnums::SCROLL_UNIT_PAGE;182}183} break;184case ACCESSKIT_ACTION_DATA_SCROLL_TO_POINT: {185rq_data = Point2(p_request->data.value.scroll_to_point.x, p_request->data.value.scroll_to_point.y);186} break;187case ACCESSKIT_ACTION_DATA_SET_SCROLL_OFFSET: {188rq_data = Point2(p_request->data.value.set_scroll_offset.x, p_request->data.value.set_scroll_offset.y);189} break;190case ACCESSKIT_ACTION_DATA_SET_TEXT_SELECTION: {191Dictionary sel;192193RID start_rid = RID::from_uint64(p_request->data.value.set_text_selection.anchor.node);194AccessibilityElement *start_ae = static_cast<AccessibilityServerAccessKit *>(get_singleton())->rid_owner.get_or_null(start_rid);195ERR_FAIL_NULL(start_ae);196197RID end_rid = RID::from_uint64(p_request->data.value.set_text_selection.focus.node);198AccessibilityElement *end_ae = static_cast<AccessibilityServerAccessKit *>(get_singleton())->rid_owner.get_or_null(end_rid);199ERR_FAIL_NULL(end_ae);200201sel["start_element"] = start_ae->parent;202sel["start_char"] = (int64_t)p_request->data.value.set_text_selection.anchor.character_index + start_ae->run.x;203sel["end_element"] = end_ae->parent;204sel["end_char"] = (int64_t)p_request->data.value.set_text_selection.focus.character_index + end_ae->run.x;205rq_data = sel;206} break;207}208}209210cb.call_deferred(rq_data);211}212}213}214215accesskit_tree_update *AccessibilityServerAccessKit::_accessibility_initial_tree_update_callback(void *p_user_data) {216DisplayServerEnums::WindowID window_id = (DisplayServerEnums::WindowID)(size_t)p_user_data;217WindowData *wd = static_cast<AccessibilityServerAccessKit *>(get_singleton())->windows.getptr(window_id);218ERR_FAIL_NULL_V(wd, nullptr);219220accesskit_node *win_node = accesskit_node_new(ACCESSKIT_ROLE_WINDOW);221accesskit_node_set_label(win_node, "Godot Engine");222accesskit_node_set_busy(win_node);223224accesskit_node_id win_id = (accesskit_node_id)wd->root_id.get_id();225226accesskit_tree_update *tree_update = accesskit_tree_update_with_capacity_and_focus(1, win_id);227228accesskit_tree_update_set_tree(tree_update, accesskit_tree_new(win_id));229accesskit_tree_update_push_node(tree_update, win_id, win_node);230231print_verbose(vformat("Accessibility: window %d adapter activated.", window_id));232233if (wd->activate.is_valid()) {234wd->activate.call_deferred(); // Should be called on main thread only.235}236wd->activated = true;237238return tree_update;239}240241void AccessibilityServerAccessKit::set_window_callbacks(DisplayServerEnums::WindowID p_window_id, const Callable &p_activate_callable, const Callable &p_deativate_callable) {242WindowData *wd = static_cast<AccessibilityServerAccessKit *>(get_singleton())->windows.getptr(p_window_id);243ERR_FAIL_NULL(wd);244245wd->activate = p_activate_callable;246wd->deactivate = p_deativate_callable;247}248249void AccessibilityServerAccessKit::window_activation_completed(DisplayServerEnums::WindowID p_window_id) {250WindowData *wd = static_cast<AccessibilityServerAccessKit *>(get_singleton())->windows.getptr(p_window_id);251if (!wd) {252return;253}254255print_verbose(vformat("Accessibility: window %d adapter initial update completed.", p_window_id));256257wd->initial_update_completed = true;258}259260void AccessibilityServerAccessKit::window_deactivation_completed(DisplayServerEnums::WindowID p_window_id) {261WindowData *wd = static_cast<AccessibilityServerAccessKit *>(get_singleton())->windows.getptr(p_window_id);262if (!wd) {263return;264}265266print_verbose(vformat("Accessibility: window %d adapter deactivation completed.", p_window_id));267268#ifdef DEV_ENABLED269LocalVector<RID> to_delete;270for (const RID &rid : rid_owner.get_owned_list()) {271AccessibilityElement *ae = rid_owner.get_or_null(rid);272if (rid != wd->root_id && ae && ae->window_id == p_window_id) {273ERR_PRINT(vformat("Accessibility/BUG: Accessibility element %d was not deleted on window %d adapter deactivation.", rid.get_id(), p_window_id));274to_delete.push_back(rid);275}276}277for (const RID &rid : to_delete) {278_free_recursive(wd, rid);279}280#endif281wd->initial_update_completed = false;282}283284RID AccessibilityServerAccessKit::create_element(DisplayServerEnums::WindowID p_window_id, AccessibilityServerEnums::AccessibilityRole p_role) {285AccessibilityElement *ae = memnew(AccessibilityElement);286ae->role = _accessibility_role(p_role);287ae->window_id = p_window_id;288RID rid = rid_owner.make_rid(ae);289290return rid;291}292293RID AccessibilityServerAccessKit::create_sub_element(const RID &p_parent_rid, AccessibilityServerEnums::AccessibilityRole p_role, int p_insert_pos) {294AccessibilityElement *parent_ae = rid_owner.get_or_null(p_parent_rid);295ERR_FAIL_NULL_V(parent_ae, RID());296297WindowData *wd = windows.getptr(parent_ae->window_id);298ERR_FAIL_NULL_V(wd, RID());299300AccessibilityElement *ae = memnew(AccessibilityElement);301ae->role = _accessibility_role(p_role);302ae->window_id = parent_ae->window_id;303ae->parent = p_parent_rid;304ae->node = accesskit_node_new(ae->role);305RID rid = rid_owner.make_rid(ae);306if (p_insert_pos == -1) {307parent_ae->children.push_back(rid);308} else {309parent_ae->children.insert(p_insert_pos, rid);310}311wd->update.insert(rid);312313return rid;314}315316RID AccessibilityServerAccessKit::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) {317AccessibilityElement *parent_ae = rid_owner.get_or_null(p_parent_rid);318ERR_FAIL_NULL_V(parent_ae, RID());319320WindowData *wd = windows.getptr(parent_ae->window_id);321ERR_FAIL_NULL_V(wd, RID());322323AccessibilityElement *root_ae = memnew(AccessibilityElement);324root_ae->role = ACCESSKIT_ROLE_GENERIC_CONTAINER;325root_ae->window_id = parent_ae->window_id;326root_ae->parent = p_parent_rid;327root_ae->node = accesskit_node_new(root_ae->role);328RID root_rid = rid_owner.make_rid(root_ae);329if (p_insert_pos == -1) {330parent_ae->children.push_back(root_rid);331} else {332parent_ae->children.insert(p_insert_pos, root_rid);333}334wd->update.insert(root_rid);335336float text_width = 0;337float text_height = p_min_height;338Vector<int32_t> words;339int64_t run_count = 0; // Note: runs in visual order.340const Glyph *gl = nullptr;341float run_off_x = 0.0;342Vector2i full_range;343344if (p_shaped_text.is_valid()) {345text_width = TS->shaped_text_get_size(p_shaped_text).x;346text_height = MAX(text_height, TS->shaped_text_get_size(p_shaped_text).y);347words = TS->shaped_text_get_word_breaks(p_shaped_text);348run_count = TS->shaped_get_run_count(p_shaped_text);349gl = TS->shaped_text_get_glyphs(p_shaped_text);350full_range = TS->shaped_text_get_range(p_shaped_text);351}352353accesskit_rect root_rect;354root_rect.x0 = 0;355root_rect.y0 = 0;356root_rect.x1 = text_width;357root_rect.y1 = MAX(p_min_height, text_height);358accesskit_node_set_bounds(root_ae->node, root_rect);359360// Create text element for each run.361Vector<AccessibilityElement *> text_elements;362for (int64_t i = 0; i < run_count; i++) {363const Vector2i range = TS->shaped_get_run_range(p_shaped_text, i);364const Vector2i gl_range = TS->shaped_get_run_glyph_range(p_shaped_text, i);365String run_t = TS->shaped_get_run_text(p_shaped_text, i);366TextServer::Direction dir = TS->shaped_get_run_direction(p_shaped_text, i);367368if (run_t.is_empty()) {369continue;370}371372// Split long runs in to < 254 char subruns due to AccessKit limitation.373Vector<Vector2i> subrun_ranges;374Vector<Vector<uint8_t>> subrun_word_starts;375{376Vector2i cur_range = range;377bool slice = false;378do {379// Word starts.380Vector<uint8_t> word_starts;381word_starts.push_back(0);382383slice = false;384for (int j = 0; j < words.size(); j += 2) {385if (words[j] <= cur_range.x) {386continue;387}388if (words[j] >= cur_range.y) {389break;390}391int32_t wstart = words[j] - cur_range.x;392int32_t wend = words[j + 1] - cur_range.x;393if (wend >= 254) {394cur_range.y = words[j];395slice = true;396break;397}398word_starts.push_back(wstart);399}400subrun_ranges.push_back(cur_range);401subrun_word_starts.push_back(word_starts);402403if (slice) {404cur_range.x = cur_range.y;405cur_range.y = range.y;406}407} while (slice);408}409410// Process subruns.411int start, end, delta;412if (dir == TextServer::DIRECTION_LTR) {413start = 0;414end = subrun_ranges.size();415delta = +1;416} else {417start = subrun_ranges.size() - 1;418end = -1;419delta = -1;420}421for (int rr = start; rr != end; rr += delta) {422// Word starts.423const Vector<uint8_t> &word_starts = subrun_word_starts[rr];424const Vector2i &cur_range = subrun_ranges[rr];425426AccessibilityElement *ae = memnew(AccessibilityElement);427ae->role = ACCESSKIT_ROLE_TEXT_RUN;428ae->window_id = parent_ae->window_id;429ae->parent = root_rid;430ae->run = Vector3i(cur_range.x, cur_range.y, i);431ae->node = accesskit_node_new(ae->role);432433text_elements.push_back(ae);434435String sub_t = run_t.substr(cur_range.x - range.x, cur_range.y - cur_range.x);436if (sub_t.is_empty()) {437continue;438}439440// UTF-8 text and char lengths.441Vector<uint8_t> char_lengths;442CharString text = sub_t.utf8(&char_lengths);443444ae->value = sub_t;445accesskit_node_set_value(ae->node, text.ptr());446accesskit_node_set_character_lengths(ae->node, char_lengths.size(), char_lengths.ptr());447448accesskit_node_set_word_starts(ae->node, word_starts.size(), word_starts.ptr());449450// Char widths and positions.451Vector<float> char_positions;452Vector<float> char_widths;453454char_positions.resize_initialized(sub_t.length());455float *positions_ptr = char_positions.ptrw();456457char_widths.resize_initialized(sub_t.length());458float *widths_ptr = char_widths.ptrw();459460float size_x = 0.0;461for (int j = gl_range.x; j <= gl_range.y; j += gl[j].count) {462if (gl[j].start >= ae->run.y || gl[j].start < ae->run.x) {463continue;464}465466float advance = 0.0; // Graphame advance.467for (int k = 0; k < gl[j].count; k++) {468advance += gl[j + k].advance;469}470int chars = gl[j].end - gl[j].start;471float adv_per_char = advance / (float)chars;472473for (int k = 0; k < chars; k++) {474int index = gl[j].start + k - ae->run.x;475ERR_CONTINUE(index < 0 || index >= sub_t.length());476positions_ptr[index] = size_x + adv_per_char * k;477widths_ptr[index] = adv_per_char;478}479size_x += advance * gl[j].repeat;480}481positions_ptr[sub_t.length() - 1] = size_x;482widths_ptr[sub_t.length() - 1] = 1.0;483484accesskit_node_set_character_positions(ae->node, char_positions.size(), char_positions.ptr());485accesskit_node_set_character_widths(ae->node, char_widths.size(), char_widths.ptr());486487RID font_rid = TS->shaped_get_run_font_rid(p_shaped_text, i);488if (font_rid != RID()) {489CharString font_name = TS->font_get_name(font_rid).utf8();490if (font_name.length() > 0) {491accesskit_node_set_font_family(ae->node, font_name.ptr());492}493if (TS->font_get_style(font_rid).has_flag(TextServer::FONT_ITALIC)) {494accesskit_node_set_italic(ae->node);495}496accesskit_node_set_font_weight(ae->node, TS->font_get_weight(font_rid));497}498accesskit_node_set_font_size(ae->node, TS->shaped_get_run_font_size(p_shaped_text, i));499CharString language = TS->shaped_get_run_language(p_shaped_text, i).utf8();500if (language.length() > 0) {501accesskit_node_set_language(ae->node, language.ptr());502}503accesskit_node_set_text_direction(ae->node, ACCESSKIT_TEXT_DIRECTION_LEFT_TO_RIGHT);504505accesskit_rect rect;506rect.x0 = run_off_x;507rect.y0 = 0;508rect.x1 = run_off_x + size_x;509rect.y1 = text_height;510accesskit_node_set_bounds(ae->node, rect);511accesskit_node_add_action(ae->node, ACCESSKIT_ACTION_SCROLL_INTO_VIEW);512513run_off_x += size_x;514}515}516if (!p_is_last_line || text_elements.is_empty()) {517// Add "\n" at the end.518AccessibilityElement *ae = memnew(AccessibilityElement);519ae->role = ACCESSKIT_ROLE_TEXT_RUN;520ae->window_id = parent_ae->window_id;521ae->parent = root_rid;522ae->run = Vector3i(full_range.y, full_range.y, run_count);523ae->node = accesskit_node_new(ae->role);524525text_elements.push_back(ae);526527ae->value = String();528if (!p_is_last_line) {529accesskit_node_set_value(ae->node, "\n");530531Vector<uint8_t> char_lengths;532Vector<float> char_positions;533Vector<float> char_widths;534char_lengths.push_back(1);535char_positions.push_back(0.0);536char_widths.push_back(1.0);537538accesskit_node_set_character_lengths(ae->node, char_lengths.size(), char_lengths.ptr());539accesskit_node_set_character_positions(ae->node, char_positions.size(), char_positions.ptr());540accesskit_node_set_character_widths(ae->node, char_widths.size(), char_widths.ptr());541} else {542accesskit_node_set_value(ae->node, "");543}544accesskit_node_set_text_direction(ae->node, ACCESSKIT_TEXT_DIRECTION_LEFT_TO_RIGHT);545546accesskit_rect rect;547rect.x0 = run_off_x;548rect.y0 = 0;549rect.x1 = run_off_x + 1;550rect.y1 = text_height;551accesskit_node_set_bounds(ae->node, rect);552}553554// Sort runs in logical order.555struct RunCompare {556_FORCE_INLINE_ bool operator()(const AccessibilityElement *l, const AccessibilityElement *r) const {557return l->run.x < r->run.x;558}559};560text_elements.sort_custom<RunCompare>();561for (int i = 0; i < text_elements.size(); i++) {562RID rid = rid_owner.make_rid(text_elements[i]);563root_ae->children.push_back(rid);564wd->update.insert(rid);565566// Link adjacent TextRuns on the same line.567if (i > 0) {568RID prev_rid = root_ae->children[i - 1];569AccessibilityElement *prev_ae = rid_owner.get_or_null(prev_rid);570accesskit_node_set_previous_on_line(text_elements[i]->node, (accesskit_node_id)prev_rid.get_id());571accesskit_node_set_next_on_line(prev_ae->node, (accesskit_node_id)rid.get_id());572}573}574575return root_rid;576}577578bool AccessibilityServerAccessKit::has_element(const RID &p_id) const {579return rid_owner.owns(p_id);580}581582void AccessibilityServerAccessKit::_free_recursive(WindowData *p_wd, const RID &p_id) {583if (p_wd && p_wd->update.has(p_id)) {584p_wd->update.erase(p_id);585}586AccessibilityElement *ae = rid_owner.get_or_null(p_id);587for (const RID &rid : ae->children) {588_free_recursive(p_wd, rid);589}590if (ae->node) {591accesskit_node_free(ae->node);592}593memdelete(ae);594rid_owner.free(p_id);595}596597void AccessibilityServerAccessKit::free_element(const RID &p_id) {598ERR_FAIL_COND_MSG(in_accessibility_update, "Element can't be removed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification.");599600AccessibilityElement *ae = rid_owner.get_or_null(p_id);601if (ae) {602WindowData *wd = windows.getptr(ae->window_id);603AccessibilityElement *parent_ae = rid_owner.get_or_null(ae->parent);604if (parent_ae) {605parent_ae->children.erase(p_id);606}607_free_recursive(wd, p_id);608}609}610611void AccessibilityServerAccessKit::element_set_meta(const RID &p_id, const Variant &p_meta) {612ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");613614AccessibilityElement *ae = rid_owner.get_or_null(p_id);615ERR_FAIL_NULL(ae);616ae->meta = p_meta;617}618619Variant AccessibilityServerAccessKit::element_get_meta(const RID &p_id) const {620const AccessibilityElement *ae = rid_owner.get_or_null(p_id);621ERR_FAIL_NULL_V(ae, Variant());622return ae->meta;623}624625void AccessibilityServerAccessKit::update_set_focus(const RID &p_id) {626ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");627628if (p_id.is_valid() && rid_owner.owns(p_id)) {629focus = p_id;630} else {631focus = RID();632}633}634635RID AccessibilityServerAccessKit::get_window_root(DisplayServerEnums::WindowID p_window_id) const {636const WindowData *wd = windows.getptr(p_window_id);637ERR_FAIL_NULL_V(wd, RID());638639return wd->root_id;640}641642accesskit_tree_update *AccessibilityServerAccessKit::_accessibility_build_tree_update(void *p_user_data) {643DisplayServerEnums::WindowID window_id = (DisplayServerEnums::WindowID)(size_t)p_user_data;644645ERR_FAIL_COND_V(!static_cast<AccessibilityServerAccessKit *>(get_singleton())->windows.has(window_id), nullptr);646WindowData &wd = static_cast<AccessibilityServerAccessKit *>(get_singleton())->windows[window_id];647648static_cast<AccessibilityServerAccessKit *>(get_singleton())->in_accessibility_update = true;649if (static_cast<AccessibilityServerAccessKit *>(get_singleton())->update_cb.is_valid()) {650static_cast<AccessibilityServerAccessKit *>(get_singleton())->update_cb.call(window_id);651}652static_cast<AccessibilityServerAccessKit *>(get_singleton())->in_accessibility_update = false;653654AccessibilityElement *focus_ae = static_cast<AccessibilityServerAccessKit *>(get_singleton())->rid_owner.get_or_null(static_cast<AccessibilityServerAccessKit *>(get_singleton())->focus);655uint32_t update_size = wd.update.size();656657accesskit_node_id ac_focus = (accesskit_node_id)wd.root_id.get_id();658if (focus_ae && focus_ae->window_id == window_id) {659ac_focus = (accesskit_node_id) static_cast<AccessibilityServerAccessKit *>(get_singleton())->focus.get_id();660}661accesskit_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);662for (const RID &rid : wd.update) {663AccessibilityElement *ae = static_cast<AccessibilityServerAccessKit *>(get_singleton())->rid_owner.get_or_null(rid);664if (ae && ae->node) {665for (const RID &child_rid : ae->children) {666accesskit_node_push_child(ae->node, (accesskit_node_id)child_rid.get_id());667}668accesskit_tree_update_push_node(tree_update, (accesskit_node_id)rid.get_id(), ae->node);669ae->node = nullptr;670}671}672wd.update.clear();673674return tree_update;675}676677void AccessibilityServerAccessKit::update_if_active(const Callable &p_callable) {678ERR_FAIL_COND(!p_callable.is_valid());679update_cb = p_callable;680for (KeyValue<DisplayServerEnums::WindowID, WindowData> &window : windows) {681#ifdef WINDOWS_ENABLED682accesskit_windows_queued_events *events = accesskit_windows_subclassing_adapter_update_if_active(window.value.adapter, _accessibility_build_tree_update, (void *)(size_t)window.key);683if (events) {684accesskit_windows_queued_events_raise(events);685}686#endif687#ifdef MACOS_ENABLED688accesskit_macos_queued_events *events = accesskit_macos_subclassing_adapter_update_if_active(window.value.adapter, _accessibility_build_tree_update, (void *)(size_t)window.key);689if (events) {690accesskit_macos_queued_events_raise(events);691}692#endif693#ifdef LINUXBSD_ENABLED694accesskit_unix_adapter_update_if_active(window.value.adapter, _accessibility_build_tree_update, (void *)(size_t)window.key);695#endif696}697update_cb = Callable();698}699700_FORCE_INLINE_ void AccessibilityServerAccessKit::_ensure_node(const RID &p_id, AccessibilityElement *p_ae) {701if (unlikely(!p_ae->node)) {702WindowData *wd = windows.getptr(p_ae->window_id);703ERR_FAIL_NULL(wd);704705wd->update.insert(p_id);706p_ae->node = accesskit_node_new(p_ae->role);707708// Re-apply stored name if any, so nodes recreated by _ensure_node709// retain their label even if the caller doesn't re-set all properties.710String full_name = (p_ae->name + " " + p_ae->name_extra_info).strip_edges();711if (!full_name.is_empty()) {712accesskit_node_set_label(p_ae->node, full_name.utf8().ptr());713}714}715}716717void AccessibilityServerAccessKit::set_window_rect(DisplayServerEnums::WindowID p_window_id, const Rect2 &p_rect_out, const Rect2 &p_rect_in) {718#ifdef LINUXBSD_ENABLED719const WindowData *wd = windows.getptr(p_window_id);720ERR_FAIL_NULL(wd);721722accesskit_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 };723accesskit_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 };724accesskit_unix_adapter_set_root_window_bounds(wd->adapter, outer_bounds, inner_bounds);725#endif726}727728void AccessibilityServerAccessKit::set_window_focused(DisplayServerEnums::WindowID p_window_id, bool p_focused) {729const WindowData *wd = windows.getptr(p_window_id);730ERR_FAIL_NULL(wd);731732#ifdef LINUXBSD_ENABLED733accesskit_unix_adapter_update_window_focus_state(wd->adapter, p_focused);734#endif735#ifdef MACOS_ENABLED736accesskit_macos_queued_events *events = accesskit_macos_subclassing_adapter_update_view_focus_state(wd->adapter, p_focused);737if (events != nullptr) {738accesskit_macos_queued_events_raise(events);739}740#endif741// Note: On Windows, the subclassing adapter takes care of this.742}743744void AccessibilityServerAccessKit::update_set_role(const RID &p_id, AccessibilityServerEnums::AccessibilityRole p_role) {745ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");746747AccessibilityElement *ae = rid_owner.get_or_null(p_id);748ERR_FAIL_NULL(ae);749if (ae->role == _accessibility_role(p_role)) {750return;751}752ae->role = _accessibility_role(p_role);753_ensure_node(p_id, ae);754755accesskit_node_set_role(ae->node, ae->role);756}757758void AccessibilityServerAccessKit::update_set_name(const RID &p_id, const String &p_name) {759ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");760761AccessibilityElement *ae = rid_owner.get_or_null(p_id);762ERR_FAIL_NULL(ae);763_ensure_node(p_id, ae);764765ae->name = p_name;766String full_name = (ae->name + " " + ae->name_extra_info).strip_edges();767if (!full_name.is_empty()) {768accesskit_node_set_label(ae->node, full_name.utf8().ptr());769} else {770accesskit_node_clear_label(ae->node);771}772}773774void AccessibilityServerAccessKit::update_set_braille_label(const RID &p_id, const String &p_name) {775ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");776777AccessibilityElement *ae = rid_owner.get_or_null(p_id);778ERR_FAIL_NULL(ae);779_ensure_node(p_id, ae);780781if (!p_name.is_empty()) {782accesskit_node_set_braille_label(ae->node, p_name.utf8().ptr());783} else {784accesskit_node_clear_braille_label(ae->node);785}786}787788void AccessibilityServerAccessKit::update_set_braille_role_description(const RID &p_id, const String &p_description) {789ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");790791AccessibilityElement *ae = rid_owner.get_or_null(p_id);792ERR_FAIL_NULL(ae);793_ensure_node(p_id, ae);794795if (!p_description.is_empty()) {796accesskit_node_set_braille_role_description(ae->node, p_description.utf8().ptr());797} else {798accesskit_node_clear_braille_role_description(ae->node);799}800}801802void AccessibilityServerAccessKit::update_set_extra_info(const RID &p_id, const String &p_name_extra_info) {803ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");804805AccessibilityElement *ae = rid_owner.get_or_null(p_id);806ERR_FAIL_NULL(ae);807_ensure_node(p_id, ae);808809ae->name_extra_info = p_name_extra_info;810String full_name = (ae->name + " " + ae->name_extra_info).strip_edges();811if (!full_name.is_empty()) {812accesskit_node_set_label(ae->node, full_name.utf8().ptr());813} else {814accesskit_node_clear_label(ae->node);815}816}817818void AccessibilityServerAccessKit::update_set_description(const RID &p_id, const String &p_description) {819ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");820821AccessibilityElement *ae = rid_owner.get_or_null(p_id);822ERR_FAIL_NULL(ae);823_ensure_node(p_id, ae);824825if (!p_description.is_empty()) {826accesskit_node_set_description(ae->node, p_description.utf8().ptr());827} else {828accesskit_node_clear_description(ae->node);829}830}831832void AccessibilityServerAccessKit::update_set_value(const RID &p_id, const String &p_value) {833ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");834835AccessibilityElement *ae = rid_owner.get_or_null(p_id);836ERR_FAIL_NULL(ae);837_ensure_node(p_id, ae);838839if (!p_value.is_empty()) {840Vector<uint8_t> ch_length;841ae->value = p_value;842accesskit_node_set_value(ae->node, p_value.utf8(&ch_length).ptr());843accesskit_node_set_character_lengths(ae->node, ch_length.size(), ch_length.ptr());844} else {845ae->value = String();846accesskit_node_clear_value(ae->node);847accesskit_node_clear_character_lengths(ae->node);848}849}850851void AccessibilityServerAccessKit::update_set_tooltip(const RID &p_id, const String &p_tooltip) {852ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");853854AccessibilityElement *ae = rid_owner.get_or_null(p_id);855ERR_FAIL_NULL(ae);856_ensure_node(p_id, ae);857858if (!p_tooltip.is_empty()) {859accesskit_node_set_tooltip(ae->node, p_tooltip.utf8().ptr());860} else {861accesskit_node_clear_tooltip(ae->node);862}863}864865void AccessibilityServerAccessKit::update_set_bounds(const RID &p_id, const Rect2 &p_rect) {866ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");867868AccessibilityElement *ae = rid_owner.get_or_null(p_id);869ERR_FAIL_NULL(ae);870_ensure_node(p_id, ae);871872accesskit_rect rect;873rect.x0 = p_rect.position.x;874rect.y0 = p_rect.position.y;875rect.x1 = p_rect.position.x + p_rect.size.x;876rect.y1 = p_rect.position.y + p_rect.size.y;877accesskit_node_set_bounds(ae->node, rect);878}879880void AccessibilityServerAccessKit::update_set_transform(const RID &p_id, const Transform2D &p_transform) {881ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");882883AccessibilityElement *ae = rid_owner.get_or_null(p_id);884ERR_FAIL_NULL(ae);885_ensure_node(p_id, ae);886887accesskit_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] };888accesskit_node_set_transform(ae->node, transform);889}890891void AccessibilityServerAccessKit::update_add_child(const RID &p_id, const RID &p_child_id) {892ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");893894AccessibilityElement *ae = rid_owner.get_or_null(p_id);895ERR_FAIL_NULL(ae);896AccessibilityElement *other_ae = rid_owner.get_or_null(p_child_id);897ERR_FAIL_NULL(other_ae);898ERR_FAIL_COND(other_ae->window_id != ae->window_id);899_ensure_node(p_id, ae);900901accesskit_node_push_child(ae->node, (accesskit_node_id)p_child_id.get_id());902}903904void AccessibilityServerAccessKit::update_add_related_controls(const RID &p_id, const RID &p_related_id) {905ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");906907AccessibilityElement *ae = rid_owner.get_or_null(p_id);908ERR_FAIL_NULL(ae);909AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);910ERR_FAIL_NULL(other_ae);911ERR_FAIL_COND(other_ae->window_id != ae->window_id);912_ensure_node(p_id, ae);913914accesskit_node_push_controlled(ae->node, (accesskit_node_id)p_related_id.get_id());915}916917void AccessibilityServerAccessKit::update_add_related_details(const RID &p_id, const RID &p_related_id) {918ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");919920AccessibilityElement *ae = rid_owner.get_or_null(p_id);921ERR_FAIL_NULL(ae);922AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);923ERR_FAIL_NULL(other_ae);924ERR_FAIL_COND(other_ae->window_id != ae->window_id);925_ensure_node(p_id, ae);926927accesskit_node_push_detail(ae->node, (accesskit_node_id)p_related_id.get_id());928}929930void AccessibilityServerAccessKit::update_add_related_described_by(const RID &p_id, const RID &p_related_id) {931ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");932933AccessibilityElement *ae = rid_owner.get_or_null(p_id);934ERR_FAIL_NULL(ae);935AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);936ERR_FAIL_NULL(other_ae);937ERR_FAIL_COND(other_ae->window_id != ae->window_id);938_ensure_node(p_id, ae);939940accesskit_node_push_described_by(ae->node, (accesskit_node_id)p_related_id.get_id());941}942943void AccessibilityServerAccessKit::update_add_related_flow_to(const RID &p_id, const RID &p_related_id) {944ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");945946AccessibilityElement *ae = rid_owner.get_or_null(p_id);947ERR_FAIL_NULL(ae);948AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);949ERR_FAIL_NULL(other_ae);950ERR_FAIL_COND(other_ae->window_id != ae->window_id);951_ensure_node(p_id, ae);952953accesskit_node_push_flow_to(ae->node, (accesskit_node_id)p_related_id.get_id());954}955956void AccessibilityServerAccessKit::update_add_related_labeled_by(const RID &p_id, const RID &p_related_id) {957ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");958959AccessibilityElement *ae = rid_owner.get_or_null(p_id);960ERR_FAIL_NULL(ae);961AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);962ERR_FAIL_NULL(other_ae);963ERR_FAIL_COND(other_ae->window_id != ae->window_id);964_ensure_node(p_id, ae);965966accesskit_node_push_labelled_by(ae->node, (accesskit_node_id)p_related_id.get_id());967}968969void AccessibilityServerAccessKit::update_add_related_radio_group(const RID &p_id, const RID &p_related_id) {970ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");971972AccessibilityElement *ae = rid_owner.get_or_null(p_id);973ERR_FAIL_NULL(ae);974AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);975ERR_FAIL_NULL(other_ae);976ERR_FAIL_COND(other_ae->window_id != ae->window_id);977_ensure_node(p_id, ae);978979accesskit_node_push_to_radio_group(ae->node, (accesskit_node_id)p_related_id.get_id());980}981982void AccessibilityServerAccessKit::update_set_active_descendant(const RID &p_id, const RID &p_other_id) {983ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");984985AccessibilityElement *ae = rid_owner.get_or_null(p_id);986ERR_FAIL_NULL(ae);987AccessibilityElement *other_ae = rid_owner.get_or_null(p_other_id);988ERR_FAIL_NULL(other_ae);989ERR_FAIL_COND(other_ae->window_id != ae->window_id);990_ensure_node(p_id, ae);991992accesskit_node_set_active_descendant(ae->node, (accesskit_node_id)p_other_id.get_id());993}994995void AccessibilityServerAccessKit::update_set_next_on_line(const RID &p_id, const RID &p_other_id) {996ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");997998AccessibilityElement *ae = rid_owner.get_or_null(p_id);999ERR_FAIL_NULL(ae);1000AccessibilityElement *other_ae = rid_owner.get_or_null(p_other_id);1001ERR_FAIL_NULL(other_ae);1002ERR_FAIL_COND(other_ae->window_id != ae->window_id);1003_ensure_node(p_id, ae);10041005accesskit_node_set_next_on_line(ae->node, (accesskit_node_id)p_other_id.get_id());1006}10071008void AccessibilityServerAccessKit::update_set_previous_on_line(const RID &p_id, const RID &p_other_id) {1009ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");10101011AccessibilityElement *ae = rid_owner.get_or_null(p_id);1012ERR_FAIL_NULL(ae);1013AccessibilityElement *other_ae = rid_owner.get_or_null(p_other_id);1014ERR_FAIL_NULL(other_ae);1015ERR_FAIL_COND(other_ae->window_id != ae->window_id);1016_ensure_node(p_id, ae);10171018accesskit_node_set_previous_on_line(ae->node, (accesskit_node_id)p_other_id.get_id());1019}10201021void AccessibilityServerAccessKit::update_set_member_of(const RID &p_id, const RID &p_group_id) {1022ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");10231024AccessibilityElement *ae = rid_owner.get_or_null(p_id);1025ERR_FAIL_NULL(ae);1026AccessibilityElement *other_ae = rid_owner.get_or_null(p_group_id);1027ERR_FAIL_NULL(other_ae);1028ERR_FAIL_COND(other_ae->window_id != ae->window_id);1029_ensure_node(p_id, ae);10301031accesskit_node_set_member_of(ae->node, (accesskit_node_id)p_group_id.get_id());1032}10331034void AccessibilityServerAccessKit::update_set_in_page_link_target(const RID &p_id, const RID &p_other_id) {1035ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");10361037AccessibilityElement *ae = rid_owner.get_or_null(p_id);1038ERR_FAIL_NULL(ae);1039AccessibilityElement *other_ae = rid_owner.get_or_null(p_other_id);1040ERR_FAIL_NULL(other_ae);1041ERR_FAIL_COND(other_ae->window_id != ae->window_id);1042_ensure_node(p_id, ae);10431044accesskit_node_set_in_page_link_target(ae->node, (accesskit_node_id)p_other_id.get_id());1045}10461047void AccessibilityServerAccessKit::update_set_error_message(const RID &p_id, const RID &p_other_id) {1048ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");10491050AccessibilityElement *ae = rid_owner.get_or_null(p_id);1051ERR_FAIL_NULL(ae);1052AccessibilityElement *other_ae = rid_owner.get_or_null(p_other_id);1053ERR_FAIL_NULL(other_ae);1054ERR_FAIL_COND(other_ae->window_id != ae->window_id);1055_ensure_node(p_id, ae);10561057accesskit_node_set_error_message(ae->node, (accesskit_node_id)p_other_id.get_id());1058}10591060void AccessibilityServerAccessKit::update_set_live(const RID &p_id, AccessibilityServerEnums::AccessibilityLiveMode p_live) {1061ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");10621063AccessibilityElement *ae = rid_owner.get_or_null(p_id);1064ERR_FAIL_NULL(ae);1065_ensure_node(p_id, ae);10661067switch (p_live) {1068case AccessibilityServerEnums::AccessibilityLiveMode::LIVE_OFF: {1069accesskit_node_set_live(ae->node, ACCESSKIT_LIVE_OFF);1070} break;1071case AccessibilityServerEnums::AccessibilityLiveMode::LIVE_POLITE: {1072accesskit_node_set_live(ae->node, ACCESSKIT_LIVE_POLITE);1073} break;1074case AccessibilityServerEnums::AccessibilityLiveMode::LIVE_ASSERTIVE: {1075accesskit_node_set_live(ae->node, ACCESSKIT_LIVE_ASSERTIVE);1076} break;1077}1078}10791080void AccessibilityServerAccessKit::update_add_action(const RID &p_id, AccessibilityServerEnums::AccessibilityAction p_action, const Callable &p_callable) {1081ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");10821083AccessibilityElement *ae = rid_owner.get_or_null(p_id);1084ERR_FAIL_NULL(ae);1085_ensure_node(p_id, ae);10861087ae->actions[_accessibility_action(p_action)] = p_callable;10881089accesskit_node_add_action(ae->node, _accessibility_action(p_action));1090}10911092void AccessibilityServerAccessKit::update_add_custom_action(const RID &p_id, int p_action_id, const String &p_action_description) {1093ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");10941095AccessibilityElement *ae = rid_owner.get_or_null(p_id);1096ERR_FAIL_NULL(ae);1097_ensure_node(p_id, ae);10981099if (!p_action_description.is_empty()) {1100accesskit_custom_action *ca = accesskit_custom_action_new(p_action_id);1101accesskit_custom_action_set_description(ca, p_action_description.utf8().ptr());1102accesskit_node_push_custom_action(ae->node, ca);1103} else {1104String cs_name = vformat("Custom Action %d", p_action_id);1105accesskit_custom_action *ca = accesskit_custom_action_new(p_action_id);1106accesskit_custom_action_set_description(ca, cs_name.utf8().ptr());1107accesskit_node_push_custom_action(ae->node, ca);1108}1109}11101111void AccessibilityServerAccessKit::update_set_table_row_count(const RID &p_id, int p_count) {1112ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");11131114AccessibilityElement *ae = rid_owner.get_or_null(p_id);1115ERR_FAIL_NULL(ae);1116_ensure_node(p_id, ae);11171118accesskit_node_set_row_count(ae->node, p_count);1119}11201121void AccessibilityServerAccessKit::update_set_table_column_count(const RID &p_id, int p_count) {1122ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");11231124AccessibilityElement *ae = rid_owner.get_or_null(p_id);1125ERR_FAIL_NULL(ae);1126_ensure_node(p_id, ae);11271128accesskit_node_set_column_count(ae->node, p_count);1129}11301131void AccessibilityServerAccessKit::update_set_table_row_index(const RID &p_id, int p_index) {1132ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");11331134AccessibilityElement *ae = rid_owner.get_or_null(p_id);1135ERR_FAIL_NULL(ae);1136_ensure_node(p_id, ae);11371138accesskit_node_set_row_index(ae->node, p_index);1139}11401141void AccessibilityServerAccessKit::update_set_table_column_index(const RID &p_id, int p_index) {1142ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");11431144AccessibilityElement *ae = rid_owner.get_or_null(p_id);1145ERR_FAIL_NULL(ae);1146_ensure_node(p_id, ae);11471148accesskit_node_set_column_index(ae->node, p_index);1149}11501151void AccessibilityServerAccessKit::update_set_table_cell_position(const RID &p_id, int p_row_index, int p_column_index) {1152ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");11531154AccessibilityElement *ae = rid_owner.get_or_null(p_id);1155ERR_FAIL_NULL(ae);1156_ensure_node(p_id, ae);11571158accesskit_node_set_row_index(ae->node, p_row_index);1159accesskit_node_set_column_index(ae->node, p_column_index);1160}11611162void AccessibilityServerAccessKit::update_set_table_cell_span(const RID &p_id, int p_row_span, int p_column_span) {1163ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");11641165AccessibilityElement *ae = rid_owner.get_or_null(p_id);1166ERR_FAIL_NULL(ae);1167_ensure_node(p_id, ae);11681169accesskit_node_set_row_span(ae->node, p_row_span);1170accesskit_node_set_column_span(ae->node, p_column_span);1171}11721173void AccessibilityServerAccessKit::update_set_list_item_count(const RID &p_id, int p_size) {1174ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");11751176AccessibilityElement *ae = rid_owner.get_or_null(p_id);1177ERR_FAIL_NULL(ae);1178_ensure_node(p_id, ae);11791180accesskit_node_set_size_of_set(ae->node, p_size);1181}11821183void AccessibilityServerAccessKit::update_set_list_item_index(const RID &p_id, int p_index) {1184ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");11851186AccessibilityElement *ae = rid_owner.get_or_null(p_id);1187ERR_FAIL_NULL(ae);1188_ensure_node(p_id, ae);11891190accesskit_node_set_position_in_set(ae->node, p_index);1191}11921193void AccessibilityServerAccessKit::update_set_list_item_level(const RID &p_id, int p_level) {1194ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");11951196AccessibilityElement *ae = rid_owner.get_or_null(p_id);1197ERR_FAIL_NULL(ae);1198_ensure_node(p_id, ae);11991200accesskit_node_set_level(ae->node, p_level);1201}12021203void AccessibilityServerAccessKit::update_set_list_item_selected(const RID &p_id, bool p_selected) {1204ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");12051206AccessibilityElement *ae = rid_owner.get_or_null(p_id);1207ERR_FAIL_NULL(ae);1208_ensure_node(p_id, ae);12091210accesskit_node_set_selected(ae->node, p_selected);1211}12121213void AccessibilityServerAccessKit::update_set_list_item_expanded(const RID &p_id, bool p_expanded) {1214ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");12151216AccessibilityElement *ae = rid_owner.get_or_null(p_id);1217ERR_FAIL_NULL(ae);1218_ensure_node(p_id, ae);12191220accesskit_node_set_expanded(ae->node, p_expanded);1221}12221223void AccessibilityServerAccessKit::update_set_popup_type(const RID &p_id, AccessibilityServerEnums::AccessibilityPopupType p_popup) {1224ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");12251226AccessibilityElement *ae = rid_owner.get_or_null(p_id);1227ERR_FAIL_NULL(ae);1228_ensure_node(p_id, ae);12291230switch (p_popup) {1231case AccessibilityServerEnums::AccessibilityPopupType::POPUP_MENU: {1232accesskit_node_set_has_popup(ae->node, ACCESSKIT_HAS_POPUP_MENU);1233} break;1234case AccessibilityServerEnums::AccessibilityPopupType::POPUP_LIST: {1235accesskit_node_set_has_popup(ae->node, ACCESSKIT_HAS_POPUP_LISTBOX);1236} break;1237case AccessibilityServerEnums::AccessibilityPopupType::POPUP_TREE: {1238accesskit_node_set_has_popup(ae->node, ACCESSKIT_HAS_POPUP_TREE);1239} break;1240case AccessibilityServerEnums::AccessibilityPopupType::POPUP_DIALOG: {1241accesskit_node_set_has_popup(ae->node, ACCESSKIT_HAS_POPUP_DIALOG);1242} break;1243}1244}12451246void AccessibilityServerAccessKit::update_set_checked(const RID &p_id, bool p_checekd) {1247ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");12481249AccessibilityElement *ae = rid_owner.get_or_null(p_id);1250ERR_FAIL_NULL(ae);1251_ensure_node(p_id, ae);12521253if (p_checekd) {1254accesskit_node_set_toggled(ae->node, ACCESSKIT_TOGGLED_TRUE);1255} else {1256accesskit_node_set_toggled(ae->node, ACCESSKIT_TOGGLED_FALSE);1257}1258}12591260void AccessibilityServerAccessKit::update_set_num_value(const RID &p_id, double p_position) {1261ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");12621263AccessibilityElement *ae = rid_owner.get_or_null(p_id);1264ERR_FAIL_NULL(ae);1265_ensure_node(p_id, ae);12661267accesskit_node_set_numeric_value(ae->node, p_position);1268ae->value = p_position;1269}12701271void AccessibilityServerAccessKit::update_set_num_range(const RID &p_id, double p_min, double p_max) {1272ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");12731274AccessibilityElement *ae = rid_owner.get_or_null(p_id);1275ERR_FAIL_NULL(ae);1276_ensure_node(p_id, ae);12771278accesskit_node_set_min_numeric_value(ae->node, p_min);1279accesskit_node_set_max_numeric_value(ae->node, p_max);1280}12811282void AccessibilityServerAccessKit::update_set_num_step(const RID &p_id, double p_step) {1283ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");12841285AccessibilityElement *ae = rid_owner.get_or_null(p_id);1286ERR_FAIL_NULL(ae);1287_ensure_node(p_id, ae);12881289accesskit_node_set_numeric_value_step(ae->node, p_step);1290}12911292void AccessibilityServerAccessKit::update_set_num_jump(const RID &p_id, double p_jump) {1293ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");12941295AccessibilityElement *ae = rid_owner.get_or_null(p_id);1296ERR_FAIL_NULL(ae);1297_ensure_node(p_id, ae);12981299accesskit_node_set_numeric_value_jump(ae->node, p_jump);1300}13011302void AccessibilityServerAccessKit::update_set_scroll_x(const RID &p_id, double p_position) {1303ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");13041305AccessibilityElement *ae = rid_owner.get_or_null(p_id);1306ERR_FAIL_NULL(ae);1307_ensure_node(p_id, ae);13081309accesskit_node_set_scroll_x(ae->node, p_position);1310}13111312void AccessibilityServerAccessKit::update_set_scroll_x_range(const RID &p_id, double p_min, double p_max) {1313ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");13141315AccessibilityElement *ae = rid_owner.get_or_null(p_id);1316ERR_FAIL_NULL(ae);1317_ensure_node(p_id, ae);13181319accesskit_node_set_scroll_x_min(ae->node, p_min);1320accesskit_node_set_scroll_x_max(ae->node, p_max);1321}13221323void AccessibilityServerAccessKit::update_set_scroll_y(const RID &p_id, double p_position) {1324ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");13251326AccessibilityElement *ae = rid_owner.get_or_null(p_id);1327ERR_FAIL_NULL(ae);1328_ensure_node(p_id, ae);13291330accesskit_node_set_scroll_y(ae->node, p_position);1331}13321333void AccessibilityServerAccessKit::update_set_scroll_y_range(const RID &p_id, double p_min, double p_max) {1334ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");13351336AccessibilityElement *ae = rid_owner.get_or_null(p_id);1337ERR_FAIL_NULL(ae);1338_ensure_node(p_id, ae);13391340accesskit_node_set_scroll_y_min(ae->node, p_min);1341accesskit_node_set_scroll_y_max(ae->node, p_max);1342}13431344void AccessibilityServerAccessKit::update_set_text_decorations(const RID &p_id, bool p_underline, bool p_strikethrough, bool p_overline, const Color &p_color) {1345ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");13461347AccessibilityElement *ae = rid_owner.get_or_null(p_id);1348ERR_FAIL_NULL(ae);1349_ensure_node(p_id, ae);13501351accesskit_color color;1352color.red = p_color.get_r8();1353color.blue = p_color.get_b8();1354color.green = p_color.get_g8();1355color.alpha = p_color.get_a8();13561357if (p_underline) {1358accesskit_node_set_underline(ae->node, { ACCESSKIT_TEXT_DECORATION_STYLE_SOLID, color });1359} else {1360accesskit_node_clear_underline(ae->node);1361}1362if (p_overline) {1363accesskit_node_set_overline(ae->node, { ACCESSKIT_TEXT_DECORATION_STYLE_SOLID, color });1364} else {1365accesskit_node_clear_overline(ae->node);1366}1367if (p_strikethrough) {1368accesskit_node_set_strikethrough(ae->node, { ACCESSKIT_TEXT_DECORATION_STYLE_SOLID, color });1369} else {1370accesskit_node_clear_strikethrough(ae->node);1371}1372}13731374void AccessibilityServerAccessKit::update_set_text_align(const RID &p_id, HorizontalAlignment p_align) {1375ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");13761377AccessibilityElement *ae = rid_owner.get_or_null(p_id);1378ERR_FAIL_NULL(ae);1379_ensure_node(p_id, ae);13801381switch (p_align) {1382case HORIZONTAL_ALIGNMENT_LEFT: {1383accesskit_node_set_text_align(ae->node, ACCESSKIT_TEXT_ALIGN_LEFT);1384} break;1385case HORIZONTAL_ALIGNMENT_CENTER: {1386accesskit_node_set_text_align(ae->node, ACCESSKIT_TEXT_ALIGN_RIGHT);1387} break;1388case HORIZONTAL_ALIGNMENT_RIGHT: {1389accesskit_node_set_text_align(ae->node, ACCESSKIT_TEXT_ALIGN_CENTER);1390} break;1391case HORIZONTAL_ALIGNMENT_FILL: {1392accesskit_node_set_text_align(ae->node, ACCESSKIT_TEXT_ALIGN_JUSTIFY);1393} break;1394}1395}13961397void AccessibilityServerAccessKit::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) {1398ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");13991400AccessibilityElement *ae = rid_owner.get_or_null(p_id);1401ERR_FAIL_NULL(ae);1402AccessibilityElement *start_ae = rid_owner.get_or_null(p_text_start_id);1403ERR_FAIL_NULL(start_ae);1404ERR_FAIL_COND(start_ae->window_id != ae->window_id);1405AccessibilityElement *end_ae = rid_owner.get_or_null(p_text_end_id);1406ERR_FAIL_NULL(end_ae);1407ERR_FAIL_COND(end_ae->window_id != ae->window_id);14081409int start_pos = p_start_char;1410int end_pos = p_end_char;1411RID start_rid;1412RID end_rid;1413for (const RID &rid : start_ae->children) {1414const AccessibilityElement *child_ae = rid_owner.get_or_null(rid);1415if (child_ae && child_ae->role == ACCESSKIT_ROLE_TEXT_RUN) {1416if (p_start_char >= child_ae->run.x && p_start_char <= child_ae->run.y) {1417start_rid = rid;1418start_pos = p_start_char - child_ae->run.x;1419break;1420}1421}1422}1423for (const RID &rid : end_ae->children) {1424const AccessibilityElement *child_ae = rid_owner.get_or_null(rid);1425if (child_ae && child_ae->role == ACCESSKIT_ROLE_TEXT_RUN) {1426if (p_end_char >= child_ae->run.x && p_end_char <= child_ae->run.y) {1427end_rid = rid;1428end_pos = p_end_char - child_ae->run.x;1429break;1430}1431}1432}1433ERR_FAIL_COND(start_rid.is_null() && end_rid.is_null());1434_ensure_node(p_id, ae);14351436accesskit_text_selection sel;1437sel.anchor.node = (accesskit_node_id)start_rid.get_id();1438sel.anchor.character_index = start_pos;1439sel.focus.node = (accesskit_node_id)end_rid.get_id();1440sel.focus.character_index = end_pos;1441accesskit_node_set_text_selection(ae->node, sel);1442}14431444void AccessibilityServerAccessKit::update_set_flag(const RID &p_id, AccessibilityServerEnums::AccessibilityFlags p_flag, bool p_value) {1445ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");14461447AccessibilityElement *ae = rid_owner.get_or_null(p_id);1448ERR_FAIL_NULL(ae);1449_ensure_node(p_id, ae);14501451if (p_value) {1452ae->flags |= (1ULL << (uint64_t)p_flag);1453} else {1454ae->flags &= ~(1ULL << (uint64_t)p_flag);1455}1456switch (p_flag) {1457case AccessibilityServerEnums::AccessibilityFlags::FLAG_HIDDEN: {1458if (p_value) {1459accesskit_node_set_hidden(ae->node);1460} else {1461accesskit_node_clear_hidden(ae->node);1462}1463} break;1464case AccessibilityServerEnums::AccessibilityFlags::FLAG_MULTISELECTABLE: {1465if (p_value) {1466accesskit_node_set_multiselectable(ae->node);1467} else {1468accesskit_node_clear_multiselectable(ae->node);1469}1470} break;1471case AccessibilityServerEnums::AccessibilityFlags::FLAG_REQUIRED: {1472if (p_value) {1473accesskit_node_set_required(ae->node);1474} else {1475accesskit_node_clear_required(ae->node);1476}1477} break;1478case AccessibilityServerEnums::AccessibilityFlags::FLAG_VISITED: {1479if (p_value) {1480accesskit_node_set_visited(ae->node);1481} else {1482accesskit_node_clear_visited(ae->node);1483}1484} break;1485case AccessibilityServerEnums::AccessibilityFlags::FLAG_BUSY: {1486if (p_value) {1487accesskit_node_set_busy(ae->node);1488} else {1489accesskit_node_clear_busy(ae->node);1490}1491} break;1492case AccessibilityServerEnums::AccessibilityFlags::FLAG_MODAL: {1493if (p_value) {1494accesskit_node_set_modal(ae->node);1495} else {1496accesskit_node_clear_modal(ae->node);1497}1498} break;1499case AccessibilityServerEnums::AccessibilityFlags::FLAG_TOUCH_PASSTHROUGH: {1500if (p_value) {1501accesskit_node_set_touch_transparent(ae->node);1502} else {1503accesskit_node_clear_touch_transparent(ae->node);1504}1505} break;1506case AccessibilityServerEnums::AccessibilityFlags::FLAG_READONLY: {1507if (p_value) {1508accesskit_node_set_read_only(ae->node);1509} else {1510accesskit_node_clear_read_only(ae->node);1511}1512} break;1513case AccessibilityServerEnums::AccessibilityFlags::FLAG_DISABLED: {1514if (p_value) {1515accesskit_node_set_disabled(ae->node);1516} else {1517accesskit_node_clear_disabled(ae->node);1518}1519} break;1520case AccessibilityServerEnums::AccessibilityFlags::FLAG_CLIPS_CHILDREN: {1521if (p_value) {1522accesskit_node_set_clips_children(ae->node);1523} else {1524accesskit_node_clear_clips_children(ae->node);1525}1526} break;1527}1528}15291530void AccessibilityServerAccessKit::update_set_classname(const RID &p_id, const String &p_classname) {1531ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");15321533AccessibilityElement *ae = rid_owner.get_or_null(p_id);1534ERR_FAIL_NULL(ae);1535_ensure_node(p_id, ae);15361537if (!p_classname.is_empty()) {1538accesskit_node_set_class_name(ae->node, p_classname.utf8().ptr());1539} else {1540accesskit_node_clear_class_name(ae->node);1541}1542}15431544void AccessibilityServerAccessKit::update_set_placeholder(const RID &p_id, const String &p_placeholder) {1545ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");15461547AccessibilityElement *ae = rid_owner.get_or_null(p_id);1548ERR_FAIL_NULL(ae);1549_ensure_node(p_id, ae);15501551if (!p_placeholder.is_empty()) {1552accesskit_node_set_placeholder(ae->node, p_placeholder.utf8().ptr());1553} else {1554accesskit_node_clear_placeholder(ae->node);1555}1556}15571558void AccessibilityServerAccessKit::update_set_language(const RID &p_id, const String &p_language) {1559ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");15601561AccessibilityElement *ae = rid_owner.get_or_null(p_id);1562ERR_FAIL_NULL(ae);1563_ensure_node(p_id, ae);15641565accesskit_node_set_language(ae->node, p_language.utf8().ptr());1566}15671568void AccessibilityServerAccessKit::update_set_text_orientation(const RID &p_id, bool p_vertical) {1569ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");15701571AccessibilityElement *ae = rid_owner.get_or_null(p_id);1572ERR_FAIL_NULL(ae);1573_ensure_node(p_id, ae);15741575if (p_vertical) {1576accesskit_node_set_text_direction(ae->node, ACCESSKIT_TEXT_DIRECTION_TOP_TO_BOTTOM);1577} else {1578accesskit_node_set_text_direction(ae->node, ACCESSKIT_TEXT_DIRECTION_LEFT_TO_RIGHT);1579}1580}15811582void AccessibilityServerAccessKit::update_set_list_orientation(const RID &p_id, bool p_vertical) {1583ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");15841585AccessibilityElement *ae = rid_owner.get_or_null(p_id);1586ERR_FAIL_NULL(ae);1587_ensure_node(p_id, ae);15881589if (p_vertical) {1590accesskit_node_set_orientation(ae->node, ACCESSKIT_ORIENTATION_VERTICAL);1591} else {1592accesskit_node_set_orientation(ae->node, ACCESSKIT_ORIENTATION_HORIZONTAL);1593}1594}15951596void AccessibilityServerAccessKit::update_set_shortcut(const RID &p_id, const String &p_shortcut) {1597ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");15981599AccessibilityElement *ae = rid_owner.get_or_null(p_id);1600ERR_FAIL_NULL(ae);1601_ensure_node(p_id, ae);16021603if (!p_shortcut.is_empty()) {1604accesskit_node_set_keyboard_shortcut(ae->node, p_shortcut.utf8().ptr());1605} else {1606accesskit_node_clear_keyboard_shortcut(ae->node);1607}1608}16091610void AccessibilityServerAccessKit::update_set_url(const RID &p_id, const String &p_url) {1611ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");16121613AccessibilityElement *ae = rid_owner.get_or_null(p_id);1614ERR_FAIL_NULL(ae);1615_ensure_node(p_id, ae);16161617if (!p_url.is_empty()) {1618accesskit_node_set_url(ae->node, p_url.utf8().ptr());1619} else {1620accesskit_node_clear_url(ae->node);1621}1622}16231624void AccessibilityServerAccessKit::update_set_role_description(const RID &p_id, const String &p_description) {1625ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");16261627AccessibilityElement *ae = rid_owner.get_or_null(p_id);1628ERR_FAIL_NULL(ae);1629_ensure_node(p_id, ae);16301631if (!p_description.is_empty()) {1632accesskit_node_set_role_description(ae->node, p_description.utf8().ptr());1633} else {1634accesskit_node_clear_role_description(ae->node);1635}1636}16371638void AccessibilityServerAccessKit::update_set_state_description(const RID &p_id, const String &p_description) {1639ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");16401641AccessibilityElement *ae = rid_owner.get_or_null(p_id);1642ERR_FAIL_NULL(ae);1643_ensure_node(p_id, ae);16441645if (!p_description.is_empty()) {1646accesskit_node_set_state_description(ae->node, p_description.utf8().ptr());1647} else {1648accesskit_node_clear_state_description(ae->node);1649}1650}16511652void AccessibilityServerAccessKit::update_set_color_value(const RID &p_id, const Color &p_color) {1653ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");16541655AccessibilityElement *ae = rid_owner.get_or_null(p_id);1656ERR_FAIL_NULL(ae);1657_ensure_node(p_id, ae);16581659ae->value = p_color;16601661accesskit_color color;1662color.red = p_color.get_r8();1663color.blue = p_color.get_b8();1664color.green = p_color.get_g8();1665color.alpha = p_color.get_a8();16661667accesskit_node_set_color_value(ae->node, color);1668}16691670void AccessibilityServerAccessKit::update_set_background_color(const RID &p_id, const Color &p_color) {1671ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");16721673AccessibilityElement *ae = rid_owner.get_or_null(p_id);1674ERR_FAIL_NULL(ae);1675_ensure_node(p_id, ae);16761677accesskit_color color;1678color.red = p_color.get_r8();1679color.blue = p_color.get_b8();1680color.green = p_color.get_g8();1681color.alpha = p_color.get_a8();16821683accesskit_node_set_background_color(ae->node, color);1684}16851686void AccessibilityServerAccessKit::update_set_foreground_color(const RID &p_id, const Color &p_color) {1687ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");16881689AccessibilityElement *ae = rid_owner.get_or_null(p_id);1690ERR_FAIL_NULL(ae);1691_ensure_node(p_id, ae);16921693accesskit_color color;1694color.red = p_color.get_r8();1695color.blue = p_color.get_b8();1696color.green = p_color.get_g8();1697color.alpha = p_color.get_a8();16981699accesskit_node_set_foreground_color(ae->node, color);1700}17011702AccessibilityServer *AccessibilityServerAccessKit::create_func(Error &r_error) {1703print_verbose("Accessibility: AccessKit driver loaded.");1704r_error = OK;1705return memnew(AccessibilityServerAccessKit);1706}17071708AccessibilityServerAccessKit::AccessibilityServerAccessKit() {1709role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_UNKNOWN] = ACCESSKIT_ROLE_UNKNOWN;1710role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_DEFAULT_BUTTON] = ACCESSKIT_ROLE_DEFAULT_BUTTON;1711role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_AUDIO] = ACCESSKIT_ROLE_AUDIO;1712role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_VIDEO] = ACCESSKIT_ROLE_VIDEO;1713role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_STATIC_TEXT] = ACCESSKIT_ROLE_LABEL;1714role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_CONTAINER] = ACCESSKIT_ROLE_GENERIC_CONTAINER;1715role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_PANEL] = ACCESSKIT_ROLE_PANE;1716role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_BUTTON] = ACCESSKIT_ROLE_BUTTON;1717role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_LINK] = ACCESSKIT_ROLE_LINK;1718role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_CHECK_BOX] = ACCESSKIT_ROLE_CHECK_BOX;1719role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_RADIO_BUTTON] = ACCESSKIT_ROLE_RADIO_BUTTON;1720role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_CHECK_BUTTON] = ACCESSKIT_ROLE_SWITCH;1721role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_SCROLL_BAR] = ACCESSKIT_ROLE_SCROLL_BAR;1722role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_SCROLL_VIEW] = ACCESSKIT_ROLE_SCROLL_VIEW;1723role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_SPLITTER] = ACCESSKIT_ROLE_SPLITTER;1724role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_SLIDER] = ACCESSKIT_ROLE_SLIDER;1725role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_SPIN_BUTTON] = ACCESSKIT_ROLE_SPIN_BUTTON;1726role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_PROGRESS_INDICATOR] = ACCESSKIT_ROLE_PROGRESS_INDICATOR;1727role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_TEXT_FIELD] = ACCESSKIT_ROLE_TEXT_INPUT;1728role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_MULTILINE_TEXT_FIELD] = ACCESSKIT_ROLE_MULTILINE_TEXT_INPUT;1729role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_COLOR_PICKER] = ACCESSKIT_ROLE_COLOR_WELL;1730role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_TABLE] = ACCESSKIT_ROLE_TABLE;1731role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_CELL] = ACCESSKIT_ROLE_CELL;1732role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_ROW] = ACCESSKIT_ROLE_ROW;1733role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_ROW_GROUP] = ACCESSKIT_ROLE_ROW_GROUP;1734role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_ROW_HEADER] = ACCESSKIT_ROLE_ROW_HEADER;1735role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_COLUMN_HEADER] = ACCESSKIT_ROLE_COLUMN_HEADER;1736role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_TREE] = ACCESSKIT_ROLE_TREE;1737role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_TREE_ITEM] = ACCESSKIT_ROLE_TREE_ITEM;1738role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_LIST] = ACCESSKIT_ROLE_LIST;1739role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_LIST_ITEM] = ACCESSKIT_ROLE_LIST_ITEM;1740role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_LIST_BOX] = ACCESSKIT_ROLE_LIST_BOX;1741role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_LIST_BOX_OPTION] = ACCESSKIT_ROLE_LIST_BOX_OPTION;1742role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_TAB_BAR] = ACCESSKIT_ROLE_TAB_LIST;1743role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_TAB] = ACCESSKIT_ROLE_TAB;1744role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_TAB_PANEL] = ACCESSKIT_ROLE_TAB_PANEL;1745role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_MENU_BAR] = ACCESSKIT_ROLE_MENU_BAR;1746role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_MENU] = ACCESSKIT_ROLE_MENU;1747role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_MENU_ITEM] = ACCESSKIT_ROLE_MENU_ITEM;1748role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_MENU_ITEM_CHECK_BOX] = ACCESSKIT_ROLE_MENU_ITEM_CHECK_BOX;1749role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_MENU_ITEM_RADIO] = ACCESSKIT_ROLE_MENU_ITEM_RADIO;1750role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_IMAGE] = ACCESSKIT_ROLE_IMAGE;1751role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_WINDOW] = ACCESSKIT_ROLE_WINDOW;1752role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_TITLE_BAR] = ACCESSKIT_ROLE_TITLE_BAR;1753role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_DIALOG] = ACCESSKIT_ROLE_DIALOG;1754role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_TOOLTIP] = ACCESSKIT_ROLE_TOOLTIP;1755role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_REGION] = ACCESSKIT_ROLE_REGION;1756role_map[AccessibilityServerEnums::AccessibilityRole::ROLE_TEXT_RUN] = ACCESSKIT_ROLE_TEXT_RUN;17571758action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_CLICK] = ACCESSKIT_ACTION_CLICK;1759action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_FOCUS] = ACCESSKIT_ACTION_FOCUS;1760action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_BLUR] = ACCESSKIT_ACTION_BLUR;1761action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_COLLAPSE] = ACCESSKIT_ACTION_COLLAPSE;1762action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_EXPAND] = ACCESSKIT_ACTION_EXPAND;1763action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_DECREMENT] = ACCESSKIT_ACTION_DECREMENT;1764action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_INCREMENT] = ACCESSKIT_ACTION_INCREMENT;1765action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_HIDE_TOOLTIP] = ACCESSKIT_ACTION_HIDE_TOOLTIP;1766action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SHOW_TOOLTIP] = ACCESSKIT_ACTION_SHOW_TOOLTIP;1767//action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_INVALIDATE_TREE] = ACCESSKIT_ACTION_INVALIDATE_TREE;1768//action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_LOAD_INLINE_TEXT_BOXES] = ACCESSKIT_ACTION_LOAD_INLINE_TEXT_BOXES;1769action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SET_TEXT_SELECTION] = ACCESSKIT_ACTION_SET_TEXT_SELECTION;1770action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_REPLACE_SELECTED_TEXT] = ACCESSKIT_ACTION_REPLACE_SELECTED_TEXT;1771action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SCROLL_BACKWARD] = ACCESSKIT_ACTION_SCROLL_UP;1772action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SCROLL_DOWN] = ACCESSKIT_ACTION_SCROLL_DOWN;1773action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SCROLL_FORWARD] = ACCESSKIT_ACTION_SCROLL_DOWN;1774action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SCROLL_LEFT] = ACCESSKIT_ACTION_SCROLL_LEFT;1775action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SCROLL_RIGHT] = ACCESSKIT_ACTION_SCROLL_RIGHT;1776action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SCROLL_UP] = ACCESSKIT_ACTION_SCROLL_UP;1777action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SCROLL_INTO_VIEW] = ACCESSKIT_ACTION_SCROLL_INTO_VIEW;1778action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SCROLL_TO_POINT] = ACCESSKIT_ACTION_SCROLL_TO_POINT;1779action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SET_SCROLL_OFFSET] = ACCESSKIT_ACTION_SET_SCROLL_OFFSET;1780//action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SET_SEQUENTIAL_FOCUS_NAVIGATION_STARTING_POINT] = ACCESSKIT_ACTION_SET_SEQUENTIAL_FOCUS_NAVIGATION_STARTING_POINT;1781action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SET_VALUE] = ACCESSKIT_ACTION_SET_VALUE;1782action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_SHOW_CONTEXT_MENU] = ACCESSKIT_ACTION_SHOW_CONTEXT_MENU;1783action_map[AccessibilityServerEnums::AccessibilityAction::ACTION_CUSTOM] = ACCESSKIT_ACTION_CUSTOM_ACTION;1784}17851786AccessibilityServerAccessKit::~AccessibilityServerAccessKit() {}17871788void AccessibilityServerAccessKit::register_create_func() {1789register_create_function("accesskit", create_func);1790}17911792#endif // ACCESSKIT_ENABLED179317941795