Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/drivers/accesskit/accessibility_driver_accesskit.cpp
9973 views
1
/**************************************************************************/
2
/* accessibility_driver_accesskit.cpp */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#ifdef ACCESSKIT_ENABLED
32
33
#include "accessibility_driver_accesskit.h"
34
35
#include "core/config/project_settings.h"
36
#include "core/version.h"
37
38
#include "servers/text_server.h"
39
40
AccessibilityDriverAccessKit *AccessibilityDriverAccessKit::singleton = nullptr;
41
42
_FORCE_INLINE_ accesskit_role AccessibilityDriverAccessKit::_accessibility_role(DisplayServer::AccessibilityRole p_role) const {
43
if (role_map.has(p_role)) {
44
return role_map[p_role];
45
}
46
return ACCESSKIT_ROLE_UNKNOWN;
47
}
48
49
_FORCE_INLINE_ accesskit_action AccessibilityDriverAccessKit::_accessibility_action(DisplayServer::AccessibilityAction p_action) const {
50
if (action_map.has(p_action)) {
51
return action_map[p_action];
52
}
53
return ACCESSKIT_ACTION_CLICK;
54
}
55
56
bool AccessibilityDriverAccessKit::window_create(DisplayServer::WindowID p_window_id, void *p_handle) {
57
ERR_FAIL_COND_V(windows.has(p_window_id), false);
58
59
WindowData &wd = windows[p_window_id];
60
61
AccessibilityElement *ae = memnew(AccessibilityElement);
62
ae->role = ACCESSKIT_ROLE_WINDOW;
63
ae->window_id = p_window_id;
64
wd.root_id = rid_owner.make_rid(ae);
65
66
#ifdef WINDOWS_ENABLED
67
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);
68
#endif
69
#ifdef MACOS_ENABLED
70
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);
71
#endif
72
#ifdef LINUXBSD_ENABLED
73
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);
74
#endif
75
76
if (wd.adapter == nullptr) {
77
memdelete(ae);
78
rid_owner.free(wd.root_id);
79
windows.erase(p_window_id);
80
81
return false;
82
} else {
83
return true;
84
}
85
}
86
87
void AccessibilityDriverAccessKit::window_destroy(DisplayServer::WindowID p_window_id) {
88
WindowData *wd = windows.getptr(p_window_id);
89
ERR_FAIL_NULL(wd);
90
91
#ifdef WINDOWS_ENABLED
92
accesskit_windows_subclassing_adapter_free(wd->adapter);
93
#endif
94
#ifdef MACOS_ENABLED
95
accesskit_macos_subclassing_adapter_free(wd->adapter);
96
#endif
97
#ifdef LINUXBSD_ENABLED
98
accesskit_unix_adapter_free(wd->adapter);
99
#endif
100
accessibility_free_element(wd->root_id);
101
102
windows.erase(p_window_id);
103
}
104
105
void AccessibilityDriverAccessKit::_accessibility_deactivation_callback(void *p_user_data) {
106
// NOP
107
}
108
109
void AccessibilityDriverAccessKit::_accessibility_action_callback(struct accesskit_action_request *p_request, void *p_user_data) {
110
DisplayServer::WindowID window_id = (DisplayServer::WindowID)(size_t)p_user_data;
111
ERR_FAIL_COND(!singleton->windows.has(window_id));
112
113
RID rid = RID::from_uint64(p_request->target);
114
AccessibilityElement *ae = singleton->rid_owner.get_or_null(rid);
115
ERR_FAIL_NULL(ae);
116
117
Variant rq_data;
118
if (!ae->actions.has(p_request->action) && ae->role == ACCESSKIT_ROLE_TEXT_RUN && p_request->action == ACCESSKIT_ACTION_SCROLL_INTO_VIEW) {
119
AccessibilityElement *root_ae = singleton->rid_owner.get_or_null(ae->parent);
120
ERR_FAIL_NULL(root_ae);
121
ae = root_ae;
122
rq_data = ae->run;
123
}
124
125
if (ae->actions.has(p_request->action)) {
126
Callable &cb = ae->actions[p_request->action];
127
if (cb.is_valid()) {
128
if (p_request->data.has_value) {
129
switch (p_request->data.value.tag) {
130
case ACCESSKIT_ACTION_DATA_CUSTOM_ACTION: {
131
rq_data = p_request->data.value.custom_action;
132
} break;
133
case ACCESSKIT_ACTION_DATA_VALUE: {
134
rq_data = String::utf8(p_request->data.value.value);
135
} break;
136
case ACCESSKIT_ACTION_DATA_NUMERIC_VALUE: {
137
rq_data = p_request->data.value.numeric_value;
138
} break;
139
case ACCESSKIT_ACTION_DATA_SCROLL_HINT: {
140
switch (p_request->data.value.scroll_hint) {
141
case ACCESSKIT_SCROLL_HINT_TOP_LEFT: {
142
rq_data = DisplayServer::SCROLL_HINT_TOP_LEFT;
143
} break;
144
case ACCESSKIT_SCROLL_HINT_BOTTOM_RIGHT: {
145
rq_data = DisplayServer::SCROLL_HINT_BOTTOM_RIGHT;
146
} break;
147
case ACCESSKIT_SCROLL_HINT_TOP_EDGE: {
148
rq_data = DisplayServer::SCROLL_HINT_TOP_EDGE;
149
} break;
150
case ACCESSKIT_SCROLL_HINT_BOTTOM_EDGE: {
151
rq_data = DisplayServer::SCROLL_HINT_BOTTOM_EDGE;
152
} break;
153
case ACCESSKIT_SCROLL_HINT_LEFT_EDGE: {
154
rq_data = DisplayServer::SCROLL_HINT_LEFT_EDGE;
155
} break;
156
case ACCESSKIT_SCROLL_HINT_RIGHT_EDGE: {
157
rq_data = DisplayServer::SCROLL_HINT_RIGHT_EDGE;
158
} break;
159
default:
160
break;
161
}
162
} break;
163
case ACCESSKIT_ACTION_DATA_SCROLL_UNIT: {
164
if (p_request->data.value.scroll_unit == ACCESSKIT_SCROLL_UNIT_ITEM) {
165
rq_data = DisplayServer::SCROLL_UNIT_ITEM;
166
} else if (p_request->data.value.scroll_unit == ACCESSKIT_SCROLL_UNIT_PAGE) {
167
rq_data = DisplayServer::SCROLL_UNIT_PAGE;
168
}
169
} break;
170
case ACCESSKIT_ACTION_DATA_SCROLL_TO_POINT: {
171
rq_data = Point2(p_request->data.value.scroll_to_point.x, p_request->data.value.scroll_to_point.y);
172
} break;
173
case ACCESSKIT_ACTION_DATA_SET_SCROLL_OFFSET: {
174
rq_data = Point2(p_request->data.value.set_scroll_offset.x, p_request->data.value.set_scroll_offset.y);
175
} break;
176
case ACCESSKIT_ACTION_DATA_SET_TEXT_SELECTION: {
177
Dictionary sel;
178
179
RID start_rid = RID::from_uint64(p_request->data.value.set_text_selection.anchor.node);
180
AccessibilityElement *start_ae = singleton->rid_owner.get_or_null(start_rid);
181
ERR_FAIL_NULL(start_ae);
182
183
RID end_rid = RID::from_uint64(p_request->data.value.set_text_selection.focus.node);
184
AccessibilityElement *end_ae = singleton->rid_owner.get_or_null(end_rid);
185
ERR_FAIL_NULL(end_ae);
186
187
sel["start_element"] = start_ae->parent;
188
sel["start_char"] = (int64_t)p_request->data.value.set_text_selection.anchor.character_index + start_ae->run.x;
189
sel["end_element"] = end_ae->parent;
190
sel["end_char"] = (int64_t)p_request->data.value.set_text_selection.focus.character_index + end_ae->run.x;
191
rq_data = sel;
192
} break;
193
}
194
}
195
196
cb.call_deferred(rq_data);
197
}
198
}
199
}
200
201
accesskit_tree_update *AccessibilityDriverAccessKit::_accessibility_initial_tree_update_callback(void *p_user_data) {
202
DisplayServer::WindowID window_id = (DisplayServer::WindowID)(size_t)p_user_data;
203
WindowData *wd = singleton->windows.getptr(window_id);
204
ERR_FAIL_NULL_V(wd, nullptr);
205
206
accesskit_node *win_node = accesskit_node_new(ACCESSKIT_ROLE_WINDOW);
207
accesskit_node_set_label(win_node, "Godot Engine");
208
accesskit_node_set_busy(win_node);
209
210
accesskit_node_id win_id = (accesskit_node_id)wd->root_id.get_id();
211
212
accesskit_tree_update *tree_update = accesskit_tree_update_with_capacity_and_focus(1, win_id);
213
214
accesskit_tree_update_set_tree(tree_update, accesskit_tree_new(win_id));
215
accesskit_tree_update_push_node(tree_update, win_id, win_node);
216
217
return tree_update;
218
}
219
220
RID AccessibilityDriverAccessKit::accessibility_create_element(DisplayServer::WindowID p_window_id, DisplayServer::AccessibilityRole p_role) {
221
AccessibilityElement *ae = memnew(AccessibilityElement);
222
ae->role = _accessibility_role(p_role);
223
ae->window_id = p_window_id;
224
RID rid = rid_owner.make_rid(ae);
225
226
return rid;
227
}
228
229
RID AccessibilityDriverAccessKit::accessibility_create_sub_element(const RID &p_parent_rid, DisplayServer::AccessibilityRole p_role, int p_insert_pos) {
230
AccessibilityElement *parent_ae = rid_owner.get_or_null(p_parent_rid);
231
ERR_FAIL_NULL_V(parent_ae, RID());
232
233
WindowData *wd = windows.getptr(parent_ae->window_id);
234
ERR_FAIL_NULL_V(wd, RID());
235
236
AccessibilityElement *ae = memnew(AccessibilityElement);
237
ae->role = _accessibility_role(p_role);
238
ae->window_id = parent_ae->window_id;
239
ae->parent = p_parent_rid;
240
ae->node = accesskit_node_new(ae->role);
241
RID rid = rid_owner.make_rid(ae);
242
if (p_insert_pos == -1) {
243
parent_ae->children.push_back(rid);
244
} else {
245
parent_ae->children.insert(p_insert_pos, rid);
246
}
247
wd->update.insert(rid);
248
249
return rid;
250
}
251
252
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) {
253
AccessibilityElement *parent_ae = rid_owner.get_or_null(p_parent_rid);
254
ERR_FAIL_NULL_V(parent_ae, RID());
255
256
WindowData *wd = windows.getptr(parent_ae->window_id);
257
ERR_FAIL_NULL_V(wd, RID());
258
259
AccessibilityElement *root_ae = memnew(AccessibilityElement);
260
root_ae->role = ACCESSKIT_ROLE_GENERIC_CONTAINER;
261
root_ae->window_id = parent_ae->window_id;
262
root_ae->parent = p_parent_rid;
263
root_ae->node = accesskit_node_new(root_ae->role);
264
RID root_rid = rid_owner.make_rid(root_ae);
265
if (p_insert_pos == -1) {
266
parent_ae->children.push_back(root_rid);
267
} else {
268
parent_ae->children.insert(p_insert_pos, root_rid);
269
}
270
wd->update.insert(root_rid);
271
272
float text_width = 0;
273
float text_height = p_min_height;
274
Vector<int32_t> words;
275
int64_t run_count = 0; // Note: runs in visual order.
276
const Glyph *gl = nullptr;
277
int64_t gl_count = 0;
278
int64_t gl_index = 0;
279
float run_off_x = 0.0;
280
Vector2i full_range;
281
282
if (p_shaped_text.is_valid()) {
283
text_width = TS->shaped_text_get_size(p_shaped_text).x;
284
text_height = MAX(text_height, TS->shaped_text_get_size(p_shaped_text).y);
285
words = TS->shaped_text_get_word_breaks(p_shaped_text);
286
run_count = TS->shaped_get_run_count(p_shaped_text);
287
gl = TS->shaped_text_get_glyphs(p_shaped_text);
288
gl_count = TS->shaped_text_get_glyph_count(p_shaped_text);
289
full_range = TS->shaped_text_get_range(p_shaped_text);
290
}
291
292
accesskit_rect root_rect;
293
root_rect.x0 = 0;
294
root_rect.y0 = 0;
295
root_rect.x1 = text_width;
296
root_rect.y1 = MAX(p_min_height, text_height);
297
accesskit_node_set_bounds(root_ae->node, root_rect);
298
299
// Create text element for each run.
300
Vector<AccessibilityElement *> text_elements;
301
for (int64_t i = 0; i < run_count; i++) {
302
const Vector2i range = TS->shaped_get_run_range(p_shaped_text, i);
303
String t = TS->shaped_get_run_text(p_shaped_text, i);
304
305
if (t.is_empty()) {
306
continue;
307
}
308
309
AccessibilityElement *ae = memnew(AccessibilityElement);
310
ae->role = ACCESSKIT_ROLE_TEXT_RUN;
311
ae->window_id = parent_ae->window_id;
312
ae->parent = root_rid;
313
ae->run = Vector3i(range.x, range.y, i);
314
ae->node = accesskit_node_new(ae->role);
315
316
text_elements.push_back(ae);
317
318
// UTF-8 text and char lengths.
319
Vector<uint8_t> char_lengths;
320
CharString text = t.utf8(&char_lengths);
321
322
accesskit_node_set_value(ae->node, text.ptr());
323
accesskit_node_set_character_lengths(ae->node, char_lengths.size(), char_lengths.ptr());
324
325
// Word sizes.
326
Vector<uint8_t> word_lengths;
327
328
int32_t prev = ae->run.x;
329
int32_t total = 0;
330
for (int j = 0; j < words.size(); j += 2) {
331
if (words[j] < ae->run.x) {
332
continue;
333
}
334
if (words[j] >= ae->run.y) {
335
break;
336
}
337
int32_t wlen = words[j] - prev;
338
while (wlen > 255) {
339
word_lengths.push_back(255);
340
wlen -= 255;
341
total += 255;
342
}
343
if (wlen > 0) {
344
word_lengths.push_back(wlen);
345
total += wlen;
346
}
347
prev = words[j];
348
}
349
if (total < t.length()) {
350
word_lengths.push_back(t.length() - total);
351
}
352
accesskit_node_set_word_lengths(ae->node, word_lengths.size(), word_lengths.ptr());
353
354
// Char widths and positions.
355
Vector<float> char_positions;
356
Vector<float> char_widths;
357
358
char_positions.resize_initialized(t.length());
359
float *positions_ptr = char_positions.ptrw();
360
361
char_widths.resize_initialized(t.length());
362
float *widths_ptr = char_widths.ptrw();
363
364
float size_x = 0.0;
365
for (int j = gl_index; j < gl_count; j += gl[j].count) {
366
if (gl[j].start >= ae->run.y) {
367
gl_index = j;
368
break;
369
}
370
371
float advance = 0.0; // Graphame advance.
372
for (int k = 0; k < gl[j].count; k++) {
373
advance += gl[j + k].advance;
374
}
375
int chars = gl[j].end - gl[j].start;
376
float adv_per_char = advance / (float)chars;
377
378
for (int k = 0; k < chars; k++) {
379
int index = gl[j].start + k - ae->run.x;
380
ERR_CONTINUE(index < 0 || index >= t.length());
381
positions_ptr[index] = size_x + adv_per_char * k;
382
widths_ptr[index] = adv_per_char;
383
}
384
size_x += advance * gl[j].repeat;
385
}
386
positions_ptr[t.length() - 1] = size_x;
387
widths_ptr[t.length() - 1] = 1.0;
388
389
accesskit_node_set_character_positions(ae->node, char_positions.size(), char_positions.ptr());
390
accesskit_node_set_character_widths(ae->node, char_widths.size(), char_widths.ptr());
391
392
RID font_rid = TS->shaped_get_run_font_rid(p_shaped_text, i);
393
if (font_rid != RID()) {
394
CharString font_name = TS->font_get_name(font_rid).utf8();
395
if (font_name.length() > 0) {
396
accesskit_node_set_font_family(ae->node, font_name.ptr());
397
}
398
if (TS->font_get_style(font_rid).has_flag(TextServer::FONT_BOLD)) {
399
accesskit_node_set_bold(ae->node);
400
}
401
if (TS->font_get_style(font_rid).has_flag(TextServer::FONT_ITALIC)) {
402
accesskit_node_set_italic(ae->node);
403
}
404
accesskit_node_set_font_weight(ae->node, TS->font_get_weight(font_rid));
405
}
406
accesskit_node_set_font_size(ae->node, TS->shaped_get_run_font_size(p_shaped_text, i));
407
CharString language = TS->shaped_get_run_language(p_shaped_text, i).utf8();
408
if (language.length() > 0) {
409
accesskit_node_set_language(ae->node, language.ptr());
410
}
411
accesskit_node_set_text_direction(ae->node, ACCESSKIT_TEXT_DIRECTION_LEFT_TO_RIGHT);
412
413
accesskit_rect rect;
414
rect.x0 = run_off_x;
415
rect.y0 = 0;
416
rect.x1 = run_off_x + size_x;
417
rect.y1 = text_height;
418
accesskit_node_set_bounds(ae->node, rect);
419
accesskit_node_add_action(ae->node, ACCESSKIT_ACTION_SCROLL_INTO_VIEW);
420
421
run_off_x += size_x;
422
}
423
{
424
// Add "\n" at the end.
425
AccessibilityElement *ae = memnew(AccessibilityElement);
426
ae->role = ACCESSKIT_ROLE_TEXT_RUN;
427
ae->window_id = parent_ae->window_id;
428
ae->parent = root_rid;
429
ae->run = Vector3i(full_range.y, full_range.y, run_count);
430
ae->node = accesskit_node_new(ae->role);
431
432
text_elements.push_back(ae);
433
434
Vector<uint8_t> char_lengths;
435
char_lengths.push_back(1);
436
accesskit_node_set_value(ae->node, "\n");
437
accesskit_node_set_character_lengths(ae->node, char_lengths.size(), char_lengths.ptr());
438
439
Vector<float> char_positions;
440
Vector<float> char_widths;
441
char_positions.push_back(0.0);
442
char_widths.push_back(1.0);
443
444
accesskit_node_set_character_positions(ae->node, char_positions.size(), char_positions.ptr());
445
accesskit_node_set_character_widths(ae->node, char_widths.size(), char_widths.ptr());
446
accesskit_node_set_text_direction(ae->node, ACCESSKIT_TEXT_DIRECTION_LEFT_TO_RIGHT);
447
448
accesskit_rect rect;
449
rect.x0 = run_off_x;
450
rect.y0 = 0;
451
rect.x1 = run_off_x + 1;
452
rect.y1 = text_height;
453
accesskit_node_set_bounds(ae->node, rect);
454
}
455
456
// Sort runs in logical order.
457
struct RunCompare {
458
_FORCE_INLINE_ bool operator()(const AccessibilityElement *l, const AccessibilityElement *r) const {
459
return l->run.x < r->run.x;
460
}
461
};
462
text_elements.sort_custom<RunCompare>();
463
for (AccessibilityElement *text_element : text_elements) {
464
RID rid = rid_owner.make_rid(text_element);
465
root_ae->children.push_back(rid);
466
wd->update.insert(rid);
467
}
468
469
return root_rid;
470
}
471
472
bool AccessibilityDriverAccessKit::accessibility_has_element(const RID &p_id) const {
473
return rid_owner.owns(p_id);
474
}
475
476
void AccessibilityDriverAccessKit::_free_recursive(WindowData *p_wd, const RID &p_id) {
477
if (p_wd && p_wd->update.has(p_id)) {
478
p_wd->update.erase(p_id);
479
}
480
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
481
for (const RID &rid : ae->children) {
482
_free_recursive(p_wd, rid);
483
}
484
if (ae->node) {
485
accesskit_node_free(ae->node);
486
}
487
memdelete(ae);
488
rid_owner.free(p_id);
489
}
490
491
void AccessibilityDriverAccessKit::accessibility_free_element(const RID &p_id) {
492
ERR_FAIL_COND_MSG(in_accessibility_update, "Element can't be removed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
493
494
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
495
if (ae) {
496
WindowData *wd = windows.getptr(ae->window_id);
497
AccessibilityElement *parent_ae = rid_owner.get_or_null(ae->parent);
498
if (parent_ae) {
499
parent_ae->children.erase(p_id);
500
}
501
_free_recursive(wd, p_id);
502
}
503
}
504
505
void AccessibilityDriverAccessKit::accessibility_element_set_meta(const RID &p_id, const Variant &p_meta) {
506
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
507
508
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
509
ERR_FAIL_NULL(ae);
510
ae->meta = p_meta;
511
}
512
513
Variant AccessibilityDriverAccessKit::accessibility_element_get_meta(const RID &p_id) const {
514
const AccessibilityElement *ae = rid_owner.get_or_null(p_id);
515
ERR_FAIL_NULL_V(ae, Variant());
516
return ae->meta;
517
}
518
519
void AccessibilityDriverAccessKit::accessibility_update_set_focus(const RID &p_id) {
520
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
521
522
if (p_id.is_valid() && rid_owner.owns(p_id)) {
523
focus = p_id;
524
} else {
525
focus = RID();
526
}
527
}
528
529
RID AccessibilityDriverAccessKit::accessibility_get_window_root(DisplayServer::WindowID p_window_id) const {
530
const WindowData *wd = windows.getptr(p_window_id);
531
ERR_FAIL_NULL_V(wd, RID());
532
533
return wd->root_id;
534
}
535
536
accesskit_tree_update *AccessibilityDriverAccessKit::_accessibility_build_tree_update(void *p_user_data) {
537
DisplayServer::WindowID window_id = (DisplayServer::WindowID)(size_t)p_user_data;
538
539
ERR_FAIL_COND_V(!singleton->windows.has(window_id), nullptr);
540
WindowData &wd = singleton->windows[window_id];
541
542
singleton->in_accessibility_update = true;
543
if (singleton->update_cb.is_valid()) {
544
singleton->update_cb.call(window_id);
545
}
546
singleton->in_accessibility_update = false;
547
548
AccessibilityElement *focus_ae = singleton->rid_owner.get_or_null(singleton->focus);
549
uint32_t update_size = wd.update.size();
550
551
accesskit_node_id ac_focus = (accesskit_node_id)wd.root_id.get_id();
552
if (focus_ae && focus_ae->window_id == window_id) {
553
ac_focus = (accesskit_node_id)singleton->focus.get_id();
554
}
555
556
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);
557
for (const RID &rid : wd.update) {
558
AccessibilityElement *ae = singleton->rid_owner.get_or_null(rid);
559
if (ae && ae->node) {
560
for (const RID &child_rid : ae->children) {
561
accesskit_node_push_child(ae->node, (accesskit_node_id)child_rid.get_id());
562
}
563
accesskit_tree_update_push_node(tree_update, (accesskit_node_id)rid.get_id(), ae->node);
564
ae->node = nullptr;
565
}
566
}
567
wd.update.clear();
568
569
return tree_update;
570
}
571
572
void AccessibilityDriverAccessKit::accessibility_update_if_active(const Callable &p_callable) {
573
ERR_FAIL_COND(!p_callable.is_valid());
574
update_cb = p_callable;
575
for (KeyValue<DisplayServer::WindowID, WindowData> &window : windows) {
576
#ifdef WINDOWS_ENABLED
577
accesskit_windows_queued_events *events = accesskit_windows_subclassing_adapter_update_if_active(window.value.adapter, _accessibility_build_tree_update, (void *)(size_t)window.key);
578
if (events) {
579
accesskit_windows_queued_events_raise(events);
580
}
581
#endif
582
#ifdef MACOS_ENABLED
583
accesskit_macos_queued_events *events = accesskit_macos_subclassing_adapter_update_if_active(window.value.adapter, _accessibility_build_tree_update, (void *)(size_t)window.key);
584
if (events) {
585
accesskit_macos_queued_events_raise(events);
586
}
587
#endif
588
#ifdef LINUXBSD_ENABLED
589
accesskit_unix_adapter_update_if_active(window.value.adapter, _accessibility_build_tree_update, (void *)(size_t)window.key);
590
#endif
591
}
592
update_cb = Callable();
593
}
594
595
_FORCE_INLINE_ void AccessibilityDriverAccessKit::_ensure_node(const RID &p_id, AccessibilityElement *p_ae) {
596
if (unlikely(!p_ae->node)) {
597
WindowData *wd = windows.getptr(p_ae->window_id);
598
ERR_FAIL_NULL(wd);
599
600
wd->update.insert(p_id);
601
p_ae->node = accesskit_node_new(p_ae->role);
602
}
603
}
604
605
void AccessibilityDriverAccessKit::accessibility_set_window_rect(DisplayServer::WindowID p_window_id, const Rect2 &p_rect_out, const Rect2 &p_rect_in) {
606
#ifdef LINUXBSD_ENABLED
607
const WindowData *wd = windows.getptr(p_window_id);
608
ERR_FAIL_NULL(wd);
609
610
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 };
611
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 };
612
accesskit_unix_adapter_set_root_window_bounds(wd->adapter, outer_bounds, inner_bounds);
613
#endif
614
}
615
616
void AccessibilityDriverAccessKit::accessibility_set_window_focused(DisplayServer::WindowID p_window_id, bool p_focused) {
617
const WindowData *wd = windows.getptr(p_window_id);
618
ERR_FAIL_NULL(wd);
619
620
#ifdef LINUXBSD_ENABLED
621
accesskit_unix_adapter_update_window_focus_state(wd->adapter, p_focused);
622
#endif
623
#ifdef MACOS_ENABLED
624
accesskit_macos_queued_events *events = accesskit_macos_subclassing_adapter_update_view_focus_state(wd->adapter, p_focused);
625
if (events != nullptr) {
626
accesskit_macos_queued_events_raise(events);
627
}
628
#endif
629
// Note: On Windows, the subclassing adapter takes care of this.
630
}
631
632
void AccessibilityDriverAccessKit::accessibility_update_set_role(const RID &p_id, DisplayServer::AccessibilityRole p_role) {
633
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
634
635
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
636
ERR_FAIL_NULL(ae);
637
if (ae->role == _accessibility_role(p_role)) {
638
return;
639
}
640
ae->role = _accessibility_role(p_role);
641
_ensure_node(p_id, ae);
642
643
accesskit_node_set_role(ae->node, ae->role);
644
}
645
646
void AccessibilityDriverAccessKit::accessibility_update_set_name(const RID &p_id, const String &p_name) {
647
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
648
649
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
650
ERR_FAIL_NULL(ae);
651
_ensure_node(p_id, ae);
652
653
ae->name = p_name;
654
String full_name = ae->name + " " + ae->name_extra_info;
655
if (!full_name.is_empty()) {
656
accesskit_node_set_label(ae->node, full_name.utf8().ptr());
657
} else {
658
accesskit_node_clear_label(ae->node);
659
}
660
}
661
662
void AccessibilityDriverAccessKit::accessibility_update_set_extra_info(const RID &p_id, const String &p_name_extra_info) {
663
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
664
665
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
666
ERR_FAIL_NULL(ae);
667
_ensure_node(p_id, ae);
668
669
ae->name_extra_info = p_name_extra_info;
670
String full_name = ae->name + " " + ae->name_extra_info;
671
if (!full_name.is_empty()) {
672
accesskit_node_set_label(ae->node, full_name.utf8().ptr());
673
} else {
674
accesskit_node_clear_label(ae->node);
675
}
676
}
677
678
void AccessibilityDriverAccessKit::accessibility_update_set_description(const RID &p_id, const String &p_description) {
679
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
680
681
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
682
ERR_FAIL_NULL(ae);
683
_ensure_node(p_id, ae);
684
685
if (!p_description.is_empty()) {
686
accesskit_node_set_description(ae->node, p_description.utf8().ptr());
687
} else {
688
accesskit_node_clear_description(ae->node);
689
}
690
}
691
692
void AccessibilityDriverAccessKit::accessibility_update_set_value(const RID &p_id, const String &p_value) {
693
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
694
695
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
696
ERR_FAIL_NULL(ae);
697
_ensure_node(p_id, ae);
698
699
if (!p_value.is_empty()) {
700
Vector<uint8_t> ch_length;
701
accesskit_node_set_value(ae->node, p_value.utf8(&ch_length).ptr());
702
accesskit_node_set_character_lengths(ae->node, ch_length.size(), ch_length.ptr());
703
} else {
704
accesskit_node_clear_value(ae->node);
705
accesskit_node_clear_character_lengths(ae->node);
706
}
707
}
708
709
void AccessibilityDriverAccessKit::accessibility_update_set_tooltip(const RID &p_id, const String &p_tooltip) {
710
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
711
712
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
713
ERR_FAIL_NULL(ae);
714
_ensure_node(p_id, ae);
715
716
if (!p_tooltip.is_empty()) {
717
accesskit_node_set_tooltip(ae->node, p_tooltip.utf8().ptr());
718
} else {
719
accesskit_node_clear_tooltip(ae->node);
720
}
721
}
722
723
void AccessibilityDriverAccessKit::accessibility_update_set_bounds(const RID &p_id, const Rect2 &p_rect) {
724
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
725
726
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
727
ERR_FAIL_NULL(ae);
728
_ensure_node(p_id, ae);
729
730
accesskit_rect rect;
731
rect.x0 = p_rect.position.x;
732
rect.y0 = p_rect.position.y;
733
rect.x1 = p_rect.position.x + p_rect.size.x;
734
rect.y1 = p_rect.position.y + p_rect.size.y;
735
accesskit_node_set_bounds(ae->node, rect);
736
}
737
738
void AccessibilityDriverAccessKit::accessibility_update_set_transform(const RID &p_id, const Transform2D &p_transform) {
739
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
740
741
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
742
ERR_FAIL_NULL(ae);
743
_ensure_node(p_id, ae);
744
745
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] };
746
accesskit_node_set_transform(ae->node, transform);
747
}
748
749
void AccessibilityDriverAccessKit::accessibility_update_add_child(const RID &p_id, const RID &p_child_id) {
750
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
751
752
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
753
ERR_FAIL_NULL(ae);
754
AccessibilityElement *other_ae = rid_owner.get_or_null(p_child_id);
755
ERR_FAIL_NULL(other_ae);
756
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
757
_ensure_node(p_id, ae);
758
759
accesskit_node_push_child(ae->node, (accesskit_node_id)p_child_id.get_id());
760
}
761
762
void AccessibilityDriverAccessKit::accessibility_update_add_related_controls(const RID &p_id, const RID &p_related_id) {
763
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
764
765
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
766
ERR_FAIL_NULL(ae);
767
AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);
768
ERR_FAIL_NULL(other_ae);
769
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
770
_ensure_node(p_id, ae);
771
772
accesskit_node_push_controlled(ae->node, (accesskit_node_id)p_related_id.get_id());
773
}
774
775
void AccessibilityDriverAccessKit::accessibility_update_add_related_details(const RID &p_id, const RID &p_related_id) {
776
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
777
778
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
779
ERR_FAIL_NULL(ae);
780
AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);
781
ERR_FAIL_NULL(other_ae);
782
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
783
_ensure_node(p_id, ae);
784
785
accesskit_node_push_detail(ae->node, (accesskit_node_id)p_related_id.get_id());
786
}
787
788
void AccessibilityDriverAccessKit::accessibility_update_add_related_described_by(const RID &p_id, const RID &p_related_id) {
789
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
790
791
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
792
ERR_FAIL_NULL(ae);
793
AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);
794
ERR_FAIL_NULL(other_ae);
795
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
796
_ensure_node(p_id, ae);
797
798
accesskit_node_push_described_by(ae->node, (accesskit_node_id)p_related_id.get_id());
799
}
800
801
void AccessibilityDriverAccessKit::accessibility_update_add_related_flow_to(const RID &p_id, const RID &p_related_id) {
802
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
803
804
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
805
ERR_FAIL_NULL(ae);
806
AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);
807
ERR_FAIL_NULL(other_ae);
808
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
809
_ensure_node(p_id, ae);
810
811
accesskit_node_push_flow_to(ae->node, (accesskit_node_id)p_related_id.get_id());
812
}
813
814
void AccessibilityDriverAccessKit::accessibility_update_add_related_labeled_by(const RID &p_id, const RID &p_related_id) {
815
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
816
817
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
818
ERR_FAIL_NULL(ae);
819
AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);
820
ERR_FAIL_NULL(other_ae);
821
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
822
_ensure_node(p_id, ae);
823
824
accesskit_node_push_labelled_by(ae->node, (accesskit_node_id)p_related_id.get_id());
825
}
826
827
void AccessibilityDriverAccessKit::accessibility_update_add_related_radio_group(const RID &p_id, const RID &p_related_id) {
828
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
829
830
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
831
ERR_FAIL_NULL(ae);
832
AccessibilityElement *other_ae = rid_owner.get_or_null(p_related_id);
833
ERR_FAIL_NULL(other_ae);
834
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
835
_ensure_node(p_id, ae);
836
837
accesskit_node_push_to_radio_group(ae->node, (accesskit_node_id)p_related_id.get_id());
838
}
839
840
void AccessibilityDriverAccessKit::accessibility_update_set_active_descendant(const RID &p_id, const RID &p_other_id) {
841
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
842
843
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
844
ERR_FAIL_NULL(ae);
845
AccessibilityElement *other_ae = rid_owner.get_or_null(p_other_id);
846
ERR_FAIL_NULL(other_ae);
847
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
848
_ensure_node(p_id, ae);
849
850
accesskit_node_set_active_descendant(ae->node, (accesskit_node_id)p_other_id.get_id());
851
}
852
853
void AccessibilityDriverAccessKit::accessibility_update_set_next_on_line(const RID &p_id, const RID &p_other_id) {
854
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
855
856
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
857
ERR_FAIL_NULL(ae);
858
AccessibilityElement *other_ae = rid_owner.get_or_null(p_other_id);
859
ERR_FAIL_NULL(other_ae);
860
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
861
_ensure_node(p_id, ae);
862
863
accesskit_node_set_next_on_line(ae->node, (accesskit_node_id)p_other_id.get_id());
864
}
865
866
void AccessibilityDriverAccessKit::accessibility_update_set_previous_on_line(const RID &p_id, const RID &p_other_id) {
867
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
868
869
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
870
ERR_FAIL_NULL(ae);
871
AccessibilityElement *other_ae = rid_owner.get_or_null(p_other_id);
872
ERR_FAIL_NULL(other_ae);
873
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
874
_ensure_node(p_id, ae);
875
876
accesskit_node_set_previous_on_line(ae->node, (accesskit_node_id)p_other_id.get_id());
877
}
878
879
void AccessibilityDriverAccessKit::accessibility_update_set_member_of(const RID &p_id, const RID &p_group_id) {
880
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
881
882
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
883
ERR_FAIL_NULL(ae);
884
AccessibilityElement *other_ae = rid_owner.get_or_null(p_group_id);
885
ERR_FAIL_NULL(other_ae);
886
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
887
_ensure_node(p_id, ae);
888
889
accesskit_node_set_member_of(ae->node, (accesskit_node_id)p_group_id.get_id());
890
}
891
892
void AccessibilityDriverAccessKit::accessibility_update_set_in_page_link_target(const RID &p_id, const RID &p_other_id) {
893
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
894
895
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
896
ERR_FAIL_NULL(ae);
897
AccessibilityElement *other_ae = rid_owner.get_or_null(p_other_id);
898
ERR_FAIL_NULL(other_ae);
899
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
900
_ensure_node(p_id, ae);
901
902
accesskit_node_set_in_page_link_target(ae->node, (accesskit_node_id)p_other_id.get_id());
903
}
904
905
void AccessibilityDriverAccessKit::accessibility_update_set_error_message(const RID &p_id, const RID &p_other_id) {
906
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
907
908
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
909
ERR_FAIL_NULL(ae);
910
AccessibilityElement *other_ae = rid_owner.get_or_null(p_other_id);
911
ERR_FAIL_NULL(other_ae);
912
ERR_FAIL_COND(other_ae->window_id != ae->window_id);
913
_ensure_node(p_id, ae);
914
915
accesskit_node_set_error_message(ae->node, (accesskit_node_id)p_other_id.get_id());
916
}
917
918
void AccessibilityDriverAccessKit::accessibility_update_set_live(const RID &p_id, DisplayServer::AccessibilityLiveMode p_live) {
919
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
920
921
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
922
ERR_FAIL_NULL(ae);
923
_ensure_node(p_id, ae);
924
925
switch (p_live) {
926
case DisplayServer::AccessibilityLiveMode::LIVE_OFF: {
927
accesskit_node_set_live(ae->node, ACCESSKIT_LIVE_OFF);
928
} break;
929
case DisplayServer::AccessibilityLiveMode::LIVE_POLITE: {
930
accesskit_node_set_live(ae->node, ACCESSKIT_LIVE_POLITE);
931
} break;
932
case DisplayServer::AccessibilityLiveMode::LIVE_ASSERTIVE: {
933
accesskit_node_set_live(ae->node, ACCESSKIT_LIVE_ASSERTIVE);
934
} break;
935
}
936
}
937
938
void AccessibilityDriverAccessKit::accessibility_update_add_action(const RID &p_id, DisplayServer::AccessibilityAction p_action, const Callable &p_callable) {
939
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
940
941
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
942
ERR_FAIL_NULL(ae);
943
_ensure_node(p_id, ae);
944
945
ae->actions[_accessibility_action(p_action)] = p_callable;
946
947
accesskit_node_add_action(ae->node, _accessibility_action(p_action));
948
}
949
950
void AccessibilityDriverAccessKit::accessibility_update_add_custom_action(const RID &p_id, int p_action_id, const String &p_action_description) {
951
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
952
953
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
954
ERR_FAIL_NULL(ae);
955
_ensure_node(p_id, ae);
956
957
if (!p_action_description.is_empty()) {
958
accesskit_custom_action ca = accesskit_custom_action_new(p_action_id, p_action_description.utf8().ptr());
959
accesskit_node_push_custom_action(ae->node, ca);
960
} else {
961
String cs_name = vformat("Custom Action %d", p_action_id);
962
accesskit_custom_action ca = accesskit_custom_action_new(p_action_id, cs_name.utf8().ptr());
963
accesskit_node_push_custom_action(ae->node, ca);
964
}
965
}
966
967
void AccessibilityDriverAccessKit::accessibility_update_set_table_row_count(const RID &p_id, int p_count) {
968
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
969
970
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
971
ERR_FAIL_NULL(ae);
972
_ensure_node(p_id, ae);
973
974
accesskit_node_set_row_count(ae->node, p_count);
975
}
976
977
void AccessibilityDriverAccessKit::accessibility_update_set_table_column_count(const RID &p_id, int p_count) {
978
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
979
980
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
981
ERR_FAIL_NULL(ae);
982
_ensure_node(p_id, ae);
983
984
accesskit_node_set_column_count(ae->node, p_count);
985
}
986
987
void AccessibilityDriverAccessKit::accessibility_update_set_table_row_index(const RID &p_id, int p_index) {
988
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
989
990
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
991
ERR_FAIL_NULL(ae);
992
_ensure_node(p_id, ae);
993
994
accesskit_node_set_row_index(ae->node, p_index);
995
}
996
997
void AccessibilityDriverAccessKit::accessibility_update_set_table_column_index(const RID &p_id, int p_index) {
998
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
999
1000
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1001
ERR_FAIL_NULL(ae);
1002
_ensure_node(p_id, ae);
1003
1004
accesskit_node_set_column_index(ae->node, p_index);
1005
}
1006
1007
void AccessibilityDriverAccessKit::accessibility_update_set_table_cell_position(const RID &p_id, int p_row_index, int p_column_index) {
1008
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1009
1010
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1011
ERR_FAIL_NULL(ae);
1012
_ensure_node(p_id, ae);
1013
1014
accesskit_node_set_row_index(ae->node, p_row_index);
1015
accesskit_node_set_column_index(ae->node, p_column_index);
1016
}
1017
1018
void AccessibilityDriverAccessKit::accessibility_update_set_table_cell_span(const RID &p_id, int p_row_span, int p_column_span) {
1019
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1020
1021
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1022
ERR_FAIL_NULL(ae);
1023
_ensure_node(p_id, ae);
1024
1025
accesskit_node_set_row_span(ae->node, p_row_span);
1026
accesskit_node_set_column_span(ae->node, p_column_span);
1027
}
1028
1029
void AccessibilityDriverAccessKit::accessibility_update_set_list_item_count(const RID &p_id, int p_size) {
1030
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1031
1032
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1033
ERR_FAIL_NULL(ae);
1034
_ensure_node(p_id, ae);
1035
1036
accesskit_node_set_size_of_set(ae->node, p_size);
1037
}
1038
1039
void AccessibilityDriverAccessKit::accessibility_update_set_list_item_index(const RID &p_id, int p_index) {
1040
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1041
1042
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1043
ERR_FAIL_NULL(ae);
1044
_ensure_node(p_id, ae);
1045
1046
accesskit_node_set_position_in_set(ae->node, p_index);
1047
}
1048
1049
void AccessibilityDriverAccessKit::accessibility_update_set_list_item_level(const RID &p_id, int p_level) {
1050
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1051
1052
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1053
ERR_FAIL_NULL(ae);
1054
_ensure_node(p_id, ae);
1055
1056
accesskit_node_set_level(ae->node, p_level);
1057
}
1058
1059
void AccessibilityDriverAccessKit::accessibility_update_set_list_item_selected(const RID &p_id, bool p_selected) {
1060
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1061
1062
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1063
ERR_FAIL_NULL(ae);
1064
_ensure_node(p_id, ae);
1065
1066
accesskit_node_set_selected(ae->node, p_selected);
1067
}
1068
1069
void AccessibilityDriverAccessKit::accessibility_update_set_list_item_expanded(const RID &p_id, bool p_expanded) {
1070
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1071
1072
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1073
ERR_FAIL_NULL(ae);
1074
_ensure_node(p_id, ae);
1075
1076
accesskit_node_set_expanded(ae->node, p_expanded);
1077
}
1078
1079
void AccessibilityDriverAccessKit::accessibility_update_set_popup_type(const RID &p_id, DisplayServer::AccessibilityPopupType p_popup) {
1080
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1081
1082
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1083
ERR_FAIL_NULL(ae);
1084
_ensure_node(p_id, ae);
1085
1086
switch (p_popup) {
1087
case DisplayServer::AccessibilityPopupType::POPUP_MENU: {
1088
accesskit_node_set_has_popup(ae->node, ACCESSKIT_HAS_POPUP_MENU);
1089
} break;
1090
case DisplayServer::AccessibilityPopupType::POPUP_LIST: {
1091
accesskit_node_set_has_popup(ae->node, ACCESSKIT_HAS_POPUP_LISTBOX);
1092
} break;
1093
case DisplayServer::AccessibilityPopupType::POPUP_TREE: {
1094
accesskit_node_set_has_popup(ae->node, ACCESSKIT_HAS_POPUP_TREE);
1095
} break;
1096
case DisplayServer::AccessibilityPopupType::POPUP_DIALOG: {
1097
accesskit_node_set_has_popup(ae->node, ACCESSKIT_HAS_POPUP_DIALOG);
1098
} break;
1099
}
1100
}
1101
1102
void AccessibilityDriverAccessKit::accessibility_update_set_checked(const RID &p_id, bool p_checekd) {
1103
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1104
1105
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1106
ERR_FAIL_NULL(ae);
1107
_ensure_node(p_id, ae);
1108
1109
if (p_checekd) {
1110
accesskit_node_set_toggled(ae->node, ACCESSKIT_TOGGLED_TRUE);
1111
} else {
1112
accesskit_node_set_toggled(ae->node, ACCESSKIT_TOGGLED_FALSE);
1113
}
1114
}
1115
1116
void AccessibilityDriverAccessKit::accessibility_update_set_num_value(const RID &p_id, double p_position) {
1117
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1118
1119
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1120
ERR_FAIL_NULL(ae);
1121
_ensure_node(p_id, ae);
1122
1123
accesskit_node_set_numeric_value(ae->node, p_position);
1124
}
1125
1126
void AccessibilityDriverAccessKit::accessibility_update_set_num_range(const RID &p_id, double p_min, double p_max) {
1127
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1128
1129
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1130
ERR_FAIL_NULL(ae);
1131
_ensure_node(p_id, ae);
1132
1133
accesskit_node_set_min_numeric_value(ae->node, p_min);
1134
accesskit_node_set_max_numeric_value(ae->node, p_max);
1135
}
1136
1137
void AccessibilityDriverAccessKit::accessibility_update_set_num_step(const RID &p_id, double p_step) {
1138
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1139
1140
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1141
ERR_FAIL_NULL(ae);
1142
_ensure_node(p_id, ae);
1143
1144
accesskit_node_set_numeric_value_step(ae->node, p_step);
1145
}
1146
1147
void AccessibilityDriverAccessKit::accessibility_update_set_num_jump(const RID &p_id, double p_jump) {
1148
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1149
1150
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1151
ERR_FAIL_NULL(ae);
1152
_ensure_node(p_id, ae);
1153
1154
accesskit_node_set_numeric_value_jump(ae->node, p_jump);
1155
}
1156
1157
void AccessibilityDriverAccessKit::accessibility_update_set_scroll_x(const RID &p_id, double p_position) {
1158
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1159
1160
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1161
ERR_FAIL_NULL(ae);
1162
_ensure_node(p_id, ae);
1163
1164
accesskit_node_set_scroll_x(ae->node, p_position);
1165
}
1166
1167
void AccessibilityDriverAccessKit::accessibility_update_set_scroll_x_range(const RID &p_id, double p_min, double p_max) {
1168
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1169
1170
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1171
ERR_FAIL_NULL(ae);
1172
_ensure_node(p_id, ae);
1173
1174
accesskit_node_set_scroll_x_min(ae->node, p_min);
1175
accesskit_node_set_scroll_x_max(ae->node, p_max);
1176
}
1177
1178
void AccessibilityDriverAccessKit::accessibility_update_set_scroll_y(const RID &p_id, double p_position) {
1179
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1180
1181
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1182
ERR_FAIL_NULL(ae);
1183
_ensure_node(p_id, ae);
1184
1185
accesskit_node_set_scroll_y(ae->node, p_position);
1186
}
1187
1188
void AccessibilityDriverAccessKit::accessibility_update_set_scroll_y_range(const RID &p_id, double p_min, double p_max) {
1189
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1190
1191
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1192
ERR_FAIL_NULL(ae);
1193
_ensure_node(p_id, ae);
1194
1195
accesskit_node_set_scroll_y_min(ae->node, p_min);
1196
accesskit_node_set_scroll_y_max(ae->node, p_max);
1197
}
1198
1199
void AccessibilityDriverAccessKit::accessibility_update_set_text_decorations(const RID &p_id, bool p_underline, bool p_strikethrough, bool p_overline) {
1200
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1201
1202
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1203
ERR_FAIL_NULL(ae);
1204
_ensure_node(p_id, ae);
1205
1206
if (p_underline) {
1207
accesskit_node_set_underline(ae->node, ACCESSKIT_TEXT_DECORATION_SOLID);
1208
} else {
1209
accesskit_node_clear_underline(ae->node);
1210
}
1211
if (p_overline) {
1212
accesskit_node_set_overline(ae->node, ACCESSKIT_TEXT_DECORATION_SOLID);
1213
} else {
1214
accesskit_node_clear_overline(ae->node);
1215
}
1216
if (p_strikethrough) {
1217
accesskit_node_set_strikethrough(ae->node, ACCESSKIT_TEXT_DECORATION_SOLID);
1218
} else {
1219
accesskit_node_clear_strikethrough(ae->node);
1220
}
1221
}
1222
1223
void AccessibilityDriverAccessKit::accessibility_update_set_text_align(const RID &p_id, HorizontalAlignment p_align) {
1224
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1225
1226
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1227
ERR_FAIL_NULL(ae);
1228
_ensure_node(p_id, ae);
1229
1230
switch (p_align) {
1231
case HORIZONTAL_ALIGNMENT_LEFT: {
1232
accesskit_node_set_text_align(ae->node, ACCESSKIT_TEXT_ALIGN_LEFT);
1233
} break;
1234
case HORIZONTAL_ALIGNMENT_CENTER: {
1235
accesskit_node_set_text_align(ae->node, ACCESSKIT_TEXT_ALIGN_RIGHT);
1236
} break;
1237
case HORIZONTAL_ALIGNMENT_RIGHT: {
1238
accesskit_node_set_text_align(ae->node, ACCESSKIT_TEXT_ALIGN_CENTER);
1239
} break;
1240
case HORIZONTAL_ALIGNMENT_FILL: {
1241
accesskit_node_set_text_align(ae->node, ACCESSKIT_TEXT_ALIGN_JUSTIFY);
1242
} break;
1243
}
1244
}
1245
1246
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) {
1247
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1248
1249
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1250
ERR_FAIL_NULL(ae);
1251
AccessibilityElement *start_ae = rid_owner.get_or_null(p_text_start_id);
1252
ERR_FAIL_NULL(start_ae);
1253
ERR_FAIL_COND(start_ae->window_id != ae->window_id);
1254
AccessibilityElement *end_ae = rid_owner.get_or_null(p_text_end_id);
1255
ERR_FAIL_NULL(end_ae);
1256
ERR_FAIL_COND(end_ae->window_id != ae->window_id);
1257
1258
int start_pos = p_start_char;
1259
int end_pos = p_end_char;
1260
RID start_rid;
1261
RID end_rid;
1262
for (const RID &rid : start_ae->children) {
1263
const AccessibilityElement *child_ae = rid_owner.get_or_null(rid);
1264
if (child_ae && child_ae->role == ACCESSKIT_ROLE_TEXT_RUN) {
1265
if (p_start_char >= child_ae->run.x && p_start_char <= child_ae->run.y) {
1266
start_rid = rid;
1267
start_pos = p_start_char - child_ae->run.x;
1268
break;
1269
}
1270
}
1271
}
1272
for (const RID &rid : end_ae->children) {
1273
const AccessibilityElement *child_ae = rid_owner.get_or_null(rid);
1274
if (child_ae && child_ae->role == ACCESSKIT_ROLE_TEXT_RUN) {
1275
if (p_end_char >= child_ae->run.x && p_end_char <= child_ae->run.y) {
1276
end_rid = rid;
1277
end_pos = p_end_char - child_ae->run.x;
1278
break;
1279
}
1280
}
1281
}
1282
ERR_FAIL_COND(start_rid.is_null() && end_rid.is_null());
1283
_ensure_node(p_id, ae);
1284
1285
accesskit_text_selection sel;
1286
sel.anchor.node = (accesskit_node_id)start_rid.get_id();
1287
sel.anchor.character_index = start_pos;
1288
sel.focus.node = (accesskit_node_id)end_rid.get_id();
1289
sel.focus.character_index = end_pos;
1290
accesskit_node_set_text_selection(ae->node, sel);
1291
}
1292
1293
void AccessibilityDriverAccessKit::accessibility_update_set_flag(const RID &p_id, DisplayServer::AccessibilityFlags p_flag, bool p_value) {
1294
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1295
1296
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1297
ERR_FAIL_NULL(ae);
1298
_ensure_node(p_id, ae);
1299
1300
switch (p_flag) {
1301
case DisplayServer::AccessibilityFlags::FLAG_HIDDEN: {
1302
if (p_value) {
1303
accesskit_node_set_hidden(ae->node);
1304
} else {
1305
accesskit_node_clear_hidden(ae->node);
1306
}
1307
} break;
1308
case DisplayServer::AccessibilityFlags::FLAG_MULTISELECTABLE: {
1309
if (p_value) {
1310
accesskit_node_set_multiselectable(ae->node);
1311
} else {
1312
accesskit_node_clear_multiselectable(ae->node);
1313
}
1314
} break;
1315
case DisplayServer::AccessibilityFlags::FLAG_REQUIRED: {
1316
if (p_value) {
1317
accesskit_node_set_required(ae->node);
1318
} else {
1319
accesskit_node_clear_required(ae->node);
1320
}
1321
} break;
1322
case DisplayServer::AccessibilityFlags::FLAG_VISITED: {
1323
if (p_value) {
1324
accesskit_node_set_visited(ae->node);
1325
} else {
1326
accesskit_node_clear_visited(ae->node);
1327
}
1328
} break;
1329
case DisplayServer::AccessibilityFlags::FLAG_BUSY: {
1330
if (p_value) {
1331
accesskit_node_set_busy(ae->node);
1332
} else {
1333
accesskit_node_clear_busy(ae->node);
1334
}
1335
} break;
1336
case DisplayServer::AccessibilityFlags::FLAG_MODAL: {
1337
if (p_value) {
1338
accesskit_node_set_modal(ae->node);
1339
} else {
1340
accesskit_node_clear_modal(ae->node);
1341
}
1342
} break;
1343
case DisplayServer::AccessibilityFlags::FLAG_TOUCH_PASSTHROUGH: {
1344
if (p_value) {
1345
accesskit_node_set_touch_transparent(ae->node);
1346
} else {
1347
accesskit_node_clear_touch_transparent(ae->node);
1348
}
1349
} break;
1350
case DisplayServer::AccessibilityFlags::FLAG_READONLY: {
1351
if (p_value) {
1352
accesskit_node_set_read_only(ae->node);
1353
} else {
1354
accesskit_node_clear_read_only(ae->node);
1355
}
1356
} break;
1357
case DisplayServer::AccessibilityFlags::FLAG_DISABLED: {
1358
if (p_value) {
1359
accesskit_node_set_disabled(ae->node);
1360
} else {
1361
accesskit_node_clear_disabled(ae->node);
1362
}
1363
} break;
1364
case DisplayServer::AccessibilityFlags::FLAG_CLIPS_CHILDREN: {
1365
if (p_value) {
1366
accesskit_node_set_clips_children(ae->node);
1367
} else {
1368
accesskit_node_clear_clips_children(ae->node);
1369
}
1370
} break;
1371
}
1372
}
1373
1374
void AccessibilityDriverAccessKit::accessibility_update_set_classname(const RID &p_id, const String &p_classname) {
1375
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1376
1377
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1378
ERR_FAIL_NULL(ae);
1379
_ensure_node(p_id, ae);
1380
1381
if (!p_classname.is_empty()) {
1382
accesskit_node_set_class_name(ae->node, p_classname.utf8().ptr());
1383
} else {
1384
accesskit_node_clear_class_name(ae->node);
1385
}
1386
}
1387
1388
void AccessibilityDriverAccessKit::accessibility_update_set_placeholder(const RID &p_id, const String &p_placeholder) {
1389
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1390
1391
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1392
ERR_FAIL_NULL(ae);
1393
_ensure_node(p_id, ae);
1394
1395
if (!p_placeholder.is_empty()) {
1396
accesskit_node_set_placeholder(ae->node, p_placeholder.utf8().ptr());
1397
} else {
1398
accesskit_node_clear_placeholder(ae->node);
1399
}
1400
}
1401
1402
void AccessibilityDriverAccessKit::accessibility_update_set_language(const RID &p_id, const String &p_language) {
1403
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1404
1405
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1406
ERR_FAIL_NULL(ae);
1407
_ensure_node(p_id, ae);
1408
1409
accesskit_node_set_language(ae->node, p_language.utf8().ptr());
1410
}
1411
1412
void AccessibilityDriverAccessKit::accessibility_update_set_text_orientation(const RID &p_id, bool p_vertical) {
1413
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1414
1415
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1416
ERR_FAIL_NULL(ae);
1417
_ensure_node(p_id, ae);
1418
1419
if (p_vertical) {
1420
accesskit_node_set_text_direction(ae->node, ACCESSKIT_TEXT_DIRECTION_TOP_TO_BOTTOM);
1421
} else {
1422
accesskit_node_set_text_direction(ae->node, ACCESSKIT_TEXT_DIRECTION_LEFT_TO_RIGHT);
1423
}
1424
}
1425
1426
void AccessibilityDriverAccessKit::accessibility_update_set_list_orientation(const RID &p_id, bool p_vertical) {
1427
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1428
1429
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1430
ERR_FAIL_NULL(ae);
1431
_ensure_node(p_id, ae);
1432
1433
if (p_vertical) {
1434
accesskit_node_set_orientation(ae->node, ACCESSKIT_ORIENTATION_VERTICAL);
1435
} else {
1436
accesskit_node_set_orientation(ae->node, ACCESSKIT_ORIENTATION_HORIZONTAL);
1437
}
1438
}
1439
1440
void AccessibilityDriverAccessKit::accessibility_update_set_shortcut(const RID &p_id, const String &p_shortcut) {
1441
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1442
1443
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1444
ERR_FAIL_NULL(ae);
1445
_ensure_node(p_id, ae);
1446
1447
if (!p_shortcut.is_empty()) {
1448
accesskit_node_set_keyboard_shortcut(ae->node, p_shortcut.utf8().ptr());
1449
} else {
1450
accesskit_node_clear_keyboard_shortcut(ae->node);
1451
}
1452
}
1453
1454
void AccessibilityDriverAccessKit::accessibility_update_set_url(const RID &p_id, const String &p_url) {
1455
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1456
1457
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1458
ERR_FAIL_NULL(ae);
1459
_ensure_node(p_id, ae);
1460
1461
if (!p_url.is_empty()) {
1462
accesskit_node_set_url(ae->node, p_url.utf8().ptr());
1463
} else {
1464
accesskit_node_clear_url(ae->node);
1465
}
1466
}
1467
1468
void AccessibilityDriverAccessKit::accessibility_update_set_role_description(const RID &p_id, const String &p_description) {
1469
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1470
1471
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1472
ERR_FAIL_NULL(ae);
1473
_ensure_node(p_id, ae);
1474
1475
if (!p_description.is_empty()) {
1476
accesskit_node_set_role_description(ae->node, p_description.utf8().ptr());
1477
} else {
1478
accesskit_node_clear_role_description(ae->node);
1479
}
1480
}
1481
1482
void AccessibilityDriverAccessKit::accessibility_update_set_state_description(const RID &p_id, const String &p_description) {
1483
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1484
1485
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1486
ERR_FAIL_NULL(ae);
1487
_ensure_node(p_id, ae);
1488
1489
if (!p_description.is_empty()) {
1490
accesskit_node_set_state_description(ae->node, p_description.utf8().ptr());
1491
} else {
1492
accesskit_node_clear_state_description(ae->node);
1493
}
1494
}
1495
1496
void AccessibilityDriverAccessKit::accessibility_update_set_color_value(const RID &p_id, const Color &p_color) {
1497
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1498
1499
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1500
ERR_FAIL_NULL(ae);
1501
_ensure_node(p_id, ae);
1502
1503
accesskit_node_set_color_value(ae->node, p_color.to_rgba32());
1504
}
1505
1506
void AccessibilityDriverAccessKit::accessibility_update_set_background_color(const RID &p_id, const Color &p_color) {
1507
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1508
1509
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1510
ERR_FAIL_NULL(ae);
1511
_ensure_node(p_id, ae);
1512
1513
accesskit_node_set_background_color(ae->node, p_color.to_rgba32());
1514
}
1515
1516
void AccessibilityDriverAccessKit::accessibility_update_set_foreground_color(const RID &p_id, const Color &p_color) {
1517
ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification.");
1518
1519
AccessibilityElement *ae = rid_owner.get_or_null(p_id);
1520
ERR_FAIL_NULL(ae);
1521
_ensure_node(p_id, ae);
1522
1523
accesskit_node_set_foreground_color(ae->node, p_color.to_rgba32());
1524
}
1525
1526
Error AccessibilityDriverAccessKit::init() {
1527
#ifdef ACCESSKIT_DYNAMIC
1528
#ifdef DEBUG_ENABLED
1529
int dylibloader_verbose = 1;
1530
#else
1531
int dylibloader_verbose = 0;
1532
#endif
1533
void *library_handle = nullptr;
1534
String path;
1535
String arch = Engine::get_singleton()->get_architecture_name();
1536
#ifdef LINUXBSD_ENABLED
1537
path = OS::get_singleton()->get_executable_path().get_base_dir().path_join("libaccesskit." + arch + ".so");
1538
if (!FileAccess::exists(path)) {
1539
path = OS::get_singleton()->get_executable_path().get_base_dir().path_join("../lib").path_join("libaccesskit." + arch + ".so");
1540
}
1541
if (!FileAccess::exists(path)) {
1542
path = OS::get_singleton()->get_executable_path().get_base_dir().path_join("libaccesskit.so");
1543
}
1544
if (!FileAccess::exists(path)) {
1545
path = OS::get_singleton()->get_executable_path().get_base_dir().path_join("../lib").path_join("libaccesskit.so");
1546
}
1547
if (!FileAccess::exists(path)) {
1548
return ERR_CANT_CREATE;
1549
}
1550
#endif
1551
#ifdef MACOS_ENABLED
1552
path = OS::get_singleton()->get_executable_path().get_base_dir().path_join("libaccesskit." + arch + ".dylib");
1553
if (!FileAccess::exists(path)) {
1554
path = OS::get_singleton()->get_executable_path().get_base_dir().path_join("../Frameworks").path_join("libaccesskit." + arch + ".dylib");
1555
}
1556
if (!FileAccess::exists(path)) {
1557
path = OS::get_singleton()->get_executable_path().get_base_dir().path_join("libaccesskit.dylib");
1558
}
1559
if (!FileAccess::exists(path)) {
1560
path = OS::get_singleton()->get_executable_path().get_base_dir().path_join("../Frameworks").path_join("libaccesskit.dylib");
1561
}
1562
if (!FileAccess::exists(path)) {
1563
return ERR_CANT_CREATE;
1564
}
1565
#endif
1566
#ifdef WINDOWS_ENABLED
1567
path = OS::get_singleton()->get_executable_path().get_base_dir().path_join("accesskit." + arch + ".dll");
1568
if (!FileAccess::exists(path)) {
1569
path = OS::get_singleton()->get_executable_path().get_base_dir().path_join("accesskit.dll");
1570
}
1571
if (!FileAccess::exists(path)) {
1572
return ERR_CANT_CREATE;
1573
}
1574
#endif
1575
1576
Error err = OS::get_singleton()->open_dynamic_library(path, library_handle);
1577
if (err == OK && initialize_libaccesskit(dylibloader_verbose, library_handle) == 0) {
1578
print_verbose("AccessKit loaded.");
1579
} else {
1580
return ERR_CANT_CREATE;
1581
}
1582
#endif
1583
#ifdef MACOS_ENABLED
1584
//accesskit_macos_add_focus_forwarder_to_window_class("GodotWindow");
1585
#endif
1586
return OK;
1587
}
1588
1589
AccessibilityDriverAccessKit::AccessibilityDriverAccessKit() {
1590
singleton = this;
1591
1592
role_map[DisplayServer::AccessibilityRole::ROLE_UNKNOWN] = ACCESSKIT_ROLE_UNKNOWN;
1593
role_map[DisplayServer::AccessibilityRole::ROLE_DEFAULT_BUTTON] = ACCESSKIT_ROLE_DEFAULT_BUTTON;
1594
role_map[DisplayServer::AccessibilityRole::ROLE_AUDIO] = ACCESSKIT_ROLE_AUDIO;
1595
role_map[DisplayServer::AccessibilityRole::ROLE_VIDEO] = ACCESSKIT_ROLE_VIDEO;
1596
role_map[DisplayServer::AccessibilityRole::ROLE_STATIC_TEXT] = ACCESSKIT_ROLE_LABEL;
1597
role_map[DisplayServer::AccessibilityRole::ROLE_CONTAINER] = ACCESSKIT_ROLE_GENERIC_CONTAINER;
1598
role_map[DisplayServer::AccessibilityRole::ROLE_PANEL] = ACCESSKIT_ROLE_PANE;
1599
role_map[DisplayServer::AccessibilityRole::ROLE_BUTTON] = ACCESSKIT_ROLE_BUTTON;
1600
role_map[DisplayServer::AccessibilityRole::ROLE_LINK] = ACCESSKIT_ROLE_LINK;
1601
role_map[DisplayServer::AccessibilityRole::ROLE_CHECK_BOX] = ACCESSKIT_ROLE_CHECK_BOX;
1602
role_map[DisplayServer::AccessibilityRole::ROLE_RADIO_BUTTON] = ACCESSKIT_ROLE_RADIO_BUTTON;
1603
role_map[DisplayServer::AccessibilityRole::ROLE_CHECK_BUTTON] = ACCESSKIT_ROLE_SWITCH;
1604
role_map[DisplayServer::AccessibilityRole::ROLE_SCROLL_BAR] = ACCESSKIT_ROLE_SCROLL_BAR;
1605
role_map[DisplayServer::AccessibilityRole::ROLE_SCROLL_VIEW] = ACCESSKIT_ROLE_SCROLL_VIEW;
1606
role_map[DisplayServer::AccessibilityRole::ROLE_SPLITTER] = ACCESSKIT_ROLE_SPLITTER;
1607
role_map[DisplayServer::AccessibilityRole::ROLE_SLIDER] = ACCESSKIT_ROLE_SLIDER;
1608
role_map[DisplayServer::AccessibilityRole::ROLE_SPIN_BUTTON] = ACCESSKIT_ROLE_SPIN_BUTTON;
1609
role_map[DisplayServer::AccessibilityRole::ROLE_PROGRESS_INDICATOR] = ACCESSKIT_ROLE_PROGRESS_INDICATOR;
1610
role_map[DisplayServer::AccessibilityRole::ROLE_TEXT_FIELD] = ACCESSKIT_ROLE_TEXT_INPUT;
1611
role_map[DisplayServer::AccessibilityRole::ROLE_MULTILINE_TEXT_FIELD] = ACCESSKIT_ROLE_MULTILINE_TEXT_INPUT;
1612
role_map[DisplayServer::AccessibilityRole::ROLE_COLOR_PICKER] = ACCESSKIT_ROLE_COLOR_WELL;
1613
role_map[DisplayServer::AccessibilityRole::ROLE_TABLE] = ACCESSKIT_ROLE_TABLE;
1614
role_map[DisplayServer::AccessibilityRole::ROLE_CELL] = ACCESSKIT_ROLE_CELL;
1615
role_map[DisplayServer::AccessibilityRole::ROLE_ROW] = ACCESSKIT_ROLE_ROW;
1616
role_map[DisplayServer::AccessibilityRole::ROLE_ROW_GROUP] = ACCESSKIT_ROLE_ROW_GROUP;
1617
role_map[DisplayServer::AccessibilityRole::ROLE_ROW_HEADER] = ACCESSKIT_ROLE_ROW_HEADER;
1618
role_map[DisplayServer::AccessibilityRole::ROLE_COLUMN_HEADER] = ACCESSKIT_ROLE_COLUMN_HEADER;
1619
role_map[DisplayServer::AccessibilityRole::ROLE_TREE] = ACCESSKIT_ROLE_TREE;
1620
role_map[DisplayServer::AccessibilityRole::ROLE_TREE_ITEM] = ACCESSKIT_ROLE_TREE_ITEM;
1621
role_map[DisplayServer::AccessibilityRole::ROLE_LIST] = ACCESSKIT_ROLE_LIST;
1622
role_map[DisplayServer::AccessibilityRole::ROLE_LIST_ITEM] = ACCESSKIT_ROLE_LIST_ITEM;
1623
role_map[DisplayServer::AccessibilityRole::ROLE_LIST_BOX] = ACCESSKIT_ROLE_LIST_BOX;
1624
role_map[DisplayServer::AccessibilityRole::ROLE_LIST_BOX_OPTION] = ACCESSKIT_ROLE_LIST_BOX_OPTION;
1625
role_map[DisplayServer::AccessibilityRole::ROLE_TAB_BAR] = ACCESSKIT_ROLE_TAB_LIST;
1626
role_map[DisplayServer::AccessibilityRole::ROLE_TAB] = ACCESSKIT_ROLE_TAB;
1627
role_map[DisplayServer::AccessibilityRole::ROLE_TAB_PANEL] = ACCESSKIT_ROLE_TAB_PANEL;
1628
role_map[DisplayServer::AccessibilityRole::ROLE_MENU_BAR] = ACCESSKIT_ROLE_MENU_BAR;
1629
role_map[DisplayServer::AccessibilityRole::ROLE_MENU] = ACCESSKIT_ROLE_MENU;
1630
role_map[DisplayServer::AccessibilityRole::ROLE_MENU_ITEM] = ACCESSKIT_ROLE_MENU_ITEM;
1631
role_map[DisplayServer::AccessibilityRole::ROLE_MENU_ITEM_CHECK_BOX] = ACCESSKIT_ROLE_MENU_ITEM_CHECK_BOX;
1632
role_map[DisplayServer::AccessibilityRole::ROLE_MENU_ITEM_RADIO] = ACCESSKIT_ROLE_MENU_ITEM_RADIO;
1633
role_map[DisplayServer::AccessibilityRole::ROLE_IMAGE] = ACCESSKIT_ROLE_IMAGE;
1634
role_map[DisplayServer::AccessibilityRole::ROLE_WINDOW] = ACCESSKIT_ROLE_WINDOW;
1635
role_map[DisplayServer::AccessibilityRole::ROLE_TITLE_BAR] = ACCESSKIT_ROLE_TITLE_BAR;
1636
role_map[DisplayServer::AccessibilityRole::ROLE_DIALOG] = ACCESSKIT_ROLE_DIALOG;
1637
role_map[DisplayServer::AccessibilityRole::ROLE_TOOLTIP] = ACCESSKIT_ROLE_TOOLTIP;
1638
1639
action_map[DisplayServer::AccessibilityAction::ACTION_CLICK] = ACCESSKIT_ACTION_CLICK;
1640
action_map[DisplayServer::AccessibilityAction::ACTION_FOCUS] = ACCESSKIT_ACTION_FOCUS;
1641
action_map[DisplayServer::AccessibilityAction::ACTION_BLUR] = ACCESSKIT_ACTION_BLUR;
1642
action_map[DisplayServer::AccessibilityAction::ACTION_COLLAPSE] = ACCESSKIT_ACTION_COLLAPSE;
1643
action_map[DisplayServer::AccessibilityAction::ACTION_EXPAND] = ACCESSKIT_ACTION_EXPAND;
1644
action_map[DisplayServer::AccessibilityAction::ACTION_DECREMENT] = ACCESSKIT_ACTION_DECREMENT;
1645
action_map[DisplayServer::AccessibilityAction::ACTION_INCREMENT] = ACCESSKIT_ACTION_INCREMENT;
1646
action_map[DisplayServer::AccessibilityAction::ACTION_HIDE_TOOLTIP] = ACCESSKIT_ACTION_HIDE_TOOLTIP;
1647
action_map[DisplayServer::AccessibilityAction::ACTION_SHOW_TOOLTIP] = ACCESSKIT_ACTION_SHOW_TOOLTIP;
1648
//action_map[DisplayServer::AccessibilityAction::ACTION_INVALIDATE_TREE] = ACCESSKIT_ACTION_INVALIDATE_TREE;
1649
//action_map[DisplayServer::AccessibilityAction::ACTION_LOAD_INLINE_TEXT_BOXES] = ACCESSKIT_ACTION_LOAD_INLINE_TEXT_BOXES;
1650
action_map[DisplayServer::AccessibilityAction::ACTION_SET_TEXT_SELECTION] = ACCESSKIT_ACTION_SET_TEXT_SELECTION;
1651
action_map[DisplayServer::AccessibilityAction::ACTION_REPLACE_SELECTED_TEXT] = ACCESSKIT_ACTION_REPLACE_SELECTED_TEXT;
1652
action_map[DisplayServer::AccessibilityAction::ACTION_SCROLL_BACKWARD] = ACCESSKIT_ACTION_SCROLL_UP;
1653
action_map[DisplayServer::AccessibilityAction::ACTION_SCROLL_DOWN] = ACCESSKIT_ACTION_SCROLL_DOWN;
1654
action_map[DisplayServer::AccessibilityAction::ACTION_SCROLL_FORWARD] = ACCESSKIT_ACTION_SCROLL_DOWN;
1655
action_map[DisplayServer::AccessibilityAction::ACTION_SCROLL_LEFT] = ACCESSKIT_ACTION_SCROLL_LEFT;
1656
action_map[DisplayServer::AccessibilityAction::ACTION_SCROLL_RIGHT] = ACCESSKIT_ACTION_SCROLL_RIGHT;
1657
action_map[DisplayServer::AccessibilityAction::ACTION_SCROLL_UP] = ACCESSKIT_ACTION_SCROLL_UP;
1658
action_map[DisplayServer::AccessibilityAction::ACTION_SCROLL_INTO_VIEW] = ACCESSKIT_ACTION_SCROLL_INTO_VIEW;
1659
action_map[DisplayServer::AccessibilityAction::ACTION_SCROLL_TO_POINT] = ACCESSKIT_ACTION_SCROLL_TO_POINT;
1660
action_map[DisplayServer::AccessibilityAction::ACTION_SET_SCROLL_OFFSET] = ACCESSKIT_ACTION_SET_SCROLL_OFFSET;
1661
//action_map[DisplayServer::AccessibilityAction::ACTION_SET_SEQUENTIAL_FOCUS_NAVIGATION_STARTING_POINT] = ACCESSKIT_ACTION_SET_SEQUENTIAL_FOCUS_NAVIGATION_STARTING_POINT;
1662
action_map[DisplayServer::AccessibilityAction::ACTION_SET_VALUE] = ACCESSKIT_ACTION_SET_VALUE;
1663
action_map[DisplayServer::AccessibilityAction::ACTION_SHOW_CONTEXT_MENU] = ACCESSKIT_ACTION_SHOW_CONTEXT_MENU;
1664
action_map[DisplayServer::AccessibilityAction::ACTION_CUSTOM] = ACCESSKIT_ACTION_CUSTOM_ACTION;
1665
}
1666
1667
AccessibilityDriverAccessKit::~AccessibilityDriverAccessKit() {
1668
singleton = nullptr;
1669
}
1670
1671
#endif // ACCESSKIT_ENABLED
1672
1673