[Accessibility] Handle adapter activation/deactivation.
(cherry picked from commit 876dcc8a5d2b1ca0cffcc84ea8cfd06d69fadde4)
This commit is contained in:
committed by
Thaddeus Crews
parent
4caac57d2a
commit
effdbbfafd
@@ -73,6 +73,7 @@ bool AccessibilityDriverAccessKit::window_create(DisplayServer::WindowID p_windo
|
||||
#ifdef LINUXBSD_ENABLED
|
||||
wd.adapter = accesskit_unix_adapter_new(&_accessibility_initial_tree_update_callback, (void *)(size_t)p_window_id, &_accessibility_action_callback, (void *)(size_t)p_window_id, &_accessibility_deactivation_callback, (void *)(size_t)p_window_id);
|
||||
#endif
|
||||
print_verbose(vformat("Accessibility: window %d adapter created.", p_window_id));
|
||||
|
||||
if (wd.adapter == nullptr) {
|
||||
memdelete(ae);
|
||||
@@ -89,6 +90,8 @@ void AccessibilityDriverAccessKit::window_destroy(DisplayServer::WindowID p_wind
|
||||
WindowData *wd = windows.getptr(p_window_id);
|
||||
ERR_FAIL_NULL(wd);
|
||||
|
||||
print_verbose(vformat("Accessibility: window %d adapter destroyed.", p_window_id));
|
||||
|
||||
#ifdef WINDOWS_ENABLED
|
||||
accesskit_windows_subclassing_adapter_free(wd->adapter);
|
||||
#endif
|
||||
@@ -104,7 +107,22 @@ void AccessibilityDriverAccessKit::window_destroy(DisplayServer::WindowID p_wind
|
||||
}
|
||||
|
||||
void AccessibilityDriverAccessKit::_accessibility_deactivation_callback(void *p_user_data) {
|
||||
// NOP
|
||||
DisplayServer::WindowID window_id = (DisplayServer::WindowID)(size_t)p_user_data;
|
||||
WindowData *wd = singleton->windows.getptr(window_id);
|
||||
ERR_FAIL_NULL(wd);
|
||||
|
||||
print_verbose(vformat("Accessibility: window %d adapter deactivated.", window_id));
|
||||
|
||||
if (singleton->focus.is_valid()) {
|
||||
AccessibilityElement *ae = singleton->rid_owner.get_or_null(singleton->focus);
|
||||
if (ae && ae->window_id == window_id) {
|
||||
singleton->focus = RID();
|
||||
}
|
||||
}
|
||||
if (wd->deactivate.is_valid()) {
|
||||
wd->deactivate.call_deferred(); // Should be called on main thread only.
|
||||
}
|
||||
wd->update.clear();
|
||||
}
|
||||
|
||||
void AccessibilityDriverAccessKit::_accessibility_action_callback(struct accesskit_action_request *p_request, void *p_user_data) {
|
||||
@@ -215,9 +233,58 @@ accesskit_tree_update *AccessibilityDriverAccessKit::_accessibility_initial_tree
|
||||
accesskit_tree_update_set_tree(tree_update, accesskit_tree_new(win_id));
|
||||
accesskit_tree_update_push_node(tree_update, win_id, win_node);
|
||||
|
||||
print_verbose(vformat("Accessibility: window %d adapter activated.", window_id));
|
||||
|
||||
if (wd->activate.is_valid()) {
|
||||
wd->activate.call_deferred(); // Should be called on main thread only.
|
||||
}
|
||||
|
||||
return tree_update;
|
||||
}
|
||||
|
||||
void AccessibilityDriverAccessKit::accessibility_set_window_callbacks(DisplayServer::WindowID p_window_id, const Callable &p_activate_callable, const Callable &p_deativate_callable) {
|
||||
WindowData *wd = singleton->windows.getptr(p_window_id);
|
||||
ERR_FAIL_NULL(wd);
|
||||
|
||||
wd->activate = p_activate_callable;
|
||||
wd->deactivate = p_deativate_callable;
|
||||
}
|
||||
|
||||
void AccessibilityDriverAccessKit::accessibility_window_activation_completed(DisplayServer::WindowID p_window_id) {
|
||||
WindowData *wd = singleton->windows.getptr(p_window_id);
|
||||
if (!wd) {
|
||||
return;
|
||||
}
|
||||
|
||||
print_verbose(vformat("Accessibility: window %d adapter initial update completed.", p_window_id));
|
||||
|
||||
wd->initial_update_completed = true;
|
||||
}
|
||||
|
||||
void AccessibilityDriverAccessKit::accessibility_window_deactivation_completed(DisplayServer::WindowID p_window_id) {
|
||||
WindowData *wd = singleton->windows.getptr(p_window_id);
|
||||
if (!wd) {
|
||||
return;
|
||||
}
|
||||
|
||||
print_verbose(vformat("Accessibility: window %d adapter deactivation completed.", p_window_id));
|
||||
|
||||
#ifdef DEV_ENABLED
|
||||
LocalVector<RID> to_delete;
|
||||
for (const RID &rid : rid_owner.get_owned_list()) {
|
||||
AccessibilityElement *ae = rid_owner.get_or_null(rid);
|
||||
if (rid != wd->root_id && ae && ae->window_id == p_window_id) {
|
||||
ERR_PRINT(vformat("Accessibility/BUG: Accessibility element %d was not deleted on window %d adapter deactivation.", rid.get_id(), p_window_id));
|
||||
to_delete.push_back(rid);
|
||||
}
|
||||
}
|
||||
for (const RID &rid : to_delete) {
|
||||
_free_recursive(wd, rid);
|
||||
}
|
||||
#endif
|
||||
wd->initial_update_completed = false;
|
||||
}
|
||||
|
||||
RID AccessibilityDriverAccessKit::accessibility_create_element(DisplayServer::WindowID p_window_id, DisplayServer::AccessibilityRole p_role) {
|
||||
AccessibilityElement *ae = memnew(AccessibilityElement);
|
||||
ae->role = _accessibility_role(p_role);
|
||||
|
||||
@@ -81,7 +81,10 @@ class AccessibilityDriverAccessKit : public AccessibilityDriver {
|
||||
#endif
|
||||
|
||||
RID root_id;
|
||||
bool initial_update_completed = false;
|
||||
HashSet<RID> update;
|
||||
Callable activate;
|
||||
Callable deactivate;
|
||||
};
|
||||
|
||||
RID focus;
|
||||
@@ -127,6 +130,9 @@ public:
|
||||
|
||||
void accessibility_set_window_rect(DisplayServer::WindowID p_window_id, const Rect2 &p_rect_out, const Rect2 &p_rect_in) override;
|
||||
void accessibility_set_window_focused(DisplayServer::WindowID p_window_id, bool p_focused) override;
|
||||
void accessibility_set_window_callbacks(DisplayServer::WindowID p_window_id, const Callable &p_activate_callable, const Callable &p_deativate_callable) override;
|
||||
void accessibility_window_activation_completed(DisplayServer::WindowID p_window_id) override;
|
||||
void accessibility_window_deactivation_completed(DisplayServer::WindowID p_window_id) override;
|
||||
|
||||
void accessibility_update_set_role(const RID &p_id, DisplayServer::AccessibilityRole p_role) override;
|
||||
void accessibility_update_set_name(const RID &p_id, const String &p_name) override;
|
||||
|
||||
@@ -63,8 +63,22 @@
|
||||
width[1] = 0;
|
||||
height[1] = 0;
|
||||
|
||||
#ifdef APPLE_EMBEDDED_ENABLED
|
||||
[p_device lockForConfiguration:&error];
|
||||
|
||||
[p_device setFocusMode:AVCaptureFocusModeLocked];
|
||||
[p_device setExposureMode:AVCaptureExposureModeLocked];
|
||||
[p_device setWhiteBalanceMode:AVCaptureWhiteBalanceModeLocked];
|
||||
|
||||
[p_device unlockForConfiguration];
|
||||
#endif // APPLE_EMBEDDED_ENABLED
|
||||
|
||||
[self beginConfiguration];
|
||||
|
||||
#ifdef APPLE_EMBEDDED_ENABLED
|
||||
self.sessionPreset = AVCaptureSessionPreset1280x720;
|
||||
#endif // APPLE_EMBEDDED_ENABLED
|
||||
|
||||
input = [AVCaptureDeviceInput deviceInputWithDevice:p_device error:&error];
|
||||
if (!input) {
|
||||
print_line("Couldn't get input device for camera");
|
||||
|
||||
+24
-2
@@ -672,6 +672,7 @@ void Window::_make_window() {
|
||||
DisplayServer::get_singleton()->window_set_mouse_passthrough(mpath, window_id);
|
||||
DisplayServer::get_singleton()->window_set_title(displayed_title, window_id);
|
||||
DisplayServer::get_singleton()->window_attach_instance_id(get_instance_id(), window_id);
|
||||
DisplayServer::get_singleton()->accessibility_set_window_callbacks(window_id, callable_mp(this, &Window::_accessibility_activate), callable_mp(this, &Window::_accessibility_deactivate));
|
||||
|
||||
_update_window_size();
|
||||
|
||||
@@ -895,6 +896,16 @@ void Window::hide() {
|
||||
set_visible(false);
|
||||
}
|
||||
|
||||
void Window::_accessibility_activate() {
|
||||
_accessibility_notify_enter(this);
|
||||
DisplayServer::get_singleton()->accessibility_window_activation_completed(get_window_id());
|
||||
}
|
||||
|
||||
void Window::_accessibility_deactivate() {
|
||||
_accessibility_notify_exit(this);
|
||||
DisplayServer::get_singleton()->accessibility_window_deactivation_completed(get_window_id());
|
||||
}
|
||||
|
||||
void Window::_accessibility_notify_enter(Node *p_node) {
|
||||
p_node->queue_accessibility_update();
|
||||
|
||||
@@ -977,10 +988,12 @@ void Window::set_visible(bool p_visible) {
|
||||
if (get_tree() && get_tree()->is_accessibility_supported()) {
|
||||
get_tree()->_accessibility_force_update();
|
||||
_accessibility_notify_enter(this);
|
||||
DisplayServer::get_singleton()->accessibility_window_activation_completed(get_window_id());
|
||||
}
|
||||
} else {
|
||||
if (get_tree() && get_tree()->is_accessibility_supported()) {
|
||||
_accessibility_notify_exit(this);
|
||||
DisplayServer::get_singleton()->accessibility_window_deactivation_completed(get_window_id());
|
||||
}
|
||||
focused = false;
|
||||
if (focused_window == this) {
|
||||
@@ -1424,8 +1437,14 @@ void Window::_notification(int p_what) {
|
||||
ERR_MAIN_THREAD_GUARD;
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ACCESSIBILITY_INVALIDATE: {
|
||||
accessibility_title_element = RID();
|
||||
accessibility_announcement_element = RID();
|
||||
if (accessibility_title_element.is_valid()) {
|
||||
DisplayServer::get_singleton()->accessibility_free_element(accessibility_title_element);
|
||||
accessibility_title_element = RID();
|
||||
}
|
||||
if (accessibility_announcement_element.is_valid()) {
|
||||
DisplayServer::get_singleton()->accessibility_free_element(accessibility_announcement_element);
|
||||
accessibility_announcement_element = RID();
|
||||
}
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_ACCESSIBILITY_UPDATE: {
|
||||
@@ -1545,6 +1564,7 @@ void Window::_notification(int p_what) {
|
||||
window_id = DisplayServer::MAIN_WINDOW_ID;
|
||||
focused_window = this;
|
||||
DisplayServer::get_singleton()->window_attach_instance_id(get_instance_id(), window_id);
|
||||
DisplayServer::get_singleton()->accessibility_set_window_callbacks(window_id, callable_mp(this, &Window::_accessibility_activate), callable_mp(this, &Window::_accessibility_deactivate));
|
||||
_update_from_window();
|
||||
// Since this window already exists (created on start), we must update pos and size from it.
|
||||
{
|
||||
@@ -1578,6 +1598,7 @@ void Window::_notification(int p_what) {
|
||||
if (window_id != DisplayServer::MAIN_WINDOW_ID && get_tree() && get_tree()->is_accessibility_supported()) {
|
||||
get_tree()->_accessibility_force_update();
|
||||
_accessibility_notify_enter(this);
|
||||
DisplayServer::get_singleton()->accessibility_window_activation_completed(get_window_id());
|
||||
}
|
||||
notification(NOTIFICATION_VISIBILITY_CHANGED);
|
||||
emit_signal(SceneStringName(visibility_changed));
|
||||
@@ -1632,6 +1653,7 @@ void Window::_notification(int p_what) {
|
||||
if (visible && window_id != DisplayServer::MAIN_WINDOW_ID) {
|
||||
if (get_tree() && get_tree()->is_accessibility_supported()) {
|
||||
_accessibility_notify_exit(this);
|
||||
DisplayServer::get_singleton()->accessibility_window_deactivation_completed(get_window_id());
|
||||
if (get_parent()) {
|
||||
get_parent()->queue_accessibility_update();
|
||||
}
|
||||
|
||||
@@ -167,6 +167,9 @@ private:
|
||||
void _accessibility_notify_enter(Node *p_node);
|
||||
void _accessibility_notify_exit(Node *p_node);
|
||||
|
||||
void _accessibility_activate();
|
||||
void _accessibility_deactivate();
|
||||
|
||||
bool _try_parent_dialog(Node *p_from_node);
|
||||
|
||||
Size2i max_size_used;
|
||||
|
||||
@@ -716,6 +716,24 @@ void DisplayServer::accessibility_set_window_focused(DisplayServer::WindowID p_w
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayServer::accessibility_set_window_callbacks(DisplayServer::WindowID p_window_id, const Callable &p_activate_callable, const Callable &p_deativate_callable) {
|
||||
if (accessibility_driver) {
|
||||
accessibility_driver->accessibility_set_window_callbacks(p_window_id, p_activate_callable, p_deativate_callable);
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayServer::accessibility_window_activation_completed(DisplayServer::WindowID p_window_id) {
|
||||
if (accessibility_driver) {
|
||||
accessibility_driver->accessibility_window_activation_completed(p_window_id);
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayServer::accessibility_window_deactivation_completed(DisplayServer::WindowID p_window_id) {
|
||||
if (accessibility_driver) {
|
||||
accessibility_driver->accessibility_window_deactivation_completed(p_window_id);
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayServer::accessibility_update_set_role(const RID &p_id, DisplayServer::AccessibilityRole p_role) {
|
||||
if (accessibility_driver) {
|
||||
accessibility_driver->accessibility_update_set_role(p_id, p_role);
|
||||
|
||||
@@ -446,7 +446,7 @@ public:
|
||||
|
||||
virtual WindowID get_window_at_screen_position(const Point2i &p_position) const = 0;
|
||||
|
||||
virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) = 0;
|
||||
virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) = 0; // Note: internal method used by Window, do not expose.
|
||||
virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const = 0;
|
||||
|
||||
virtual void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) = 0;
|
||||
@@ -698,6 +698,9 @@ public:
|
||||
|
||||
virtual void accessibility_set_window_rect(DisplayServer::WindowID p_window_id, const Rect2 &p_rect_out, const Rect2 &p_rect_in);
|
||||
virtual void accessibility_set_window_focused(DisplayServer::WindowID p_window_id, bool p_focused);
|
||||
virtual void accessibility_set_window_callbacks(DisplayServer::WindowID p_window_id, const Callable &p_activate_callable, const Callable &p_deativate_callable); // Note: internal method used by Window, do not expose.
|
||||
virtual void accessibility_window_activation_completed(DisplayServer::WindowID p_window_id); // Note: internal method used by Window, do not expose.
|
||||
virtual void accessibility_window_deactivation_completed(DisplayServer::WindowID p_window_id); // Note: internal method used by Window, do not expose.
|
||||
|
||||
virtual void accessibility_update_set_role(const RID &p_id, DisplayServer::AccessibilityRole p_role);
|
||||
virtual void accessibility_update_set_name(const RID &p_id, const String &p_name);
|
||||
@@ -930,6 +933,9 @@ public:
|
||||
|
||||
virtual void accessibility_set_window_rect(DisplayServer::WindowID p_window_id, const Rect2 &p_rect_out, const Rect2 &p_rect_in) = 0;
|
||||
virtual void accessibility_set_window_focused(DisplayServer::WindowID p_window_id, bool p_focused) = 0;
|
||||
virtual void accessibility_set_window_callbacks(DisplayServer::WindowID p_window_id, const Callable &p_activate_callable, const Callable &p_deativate_callable) = 0;
|
||||
virtual void accessibility_window_activation_completed(DisplayServer::WindowID p_window_id) = 0;
|
||||
virtual void accessibility_window_deactivation_completed(DisplayServer::WindowID p_window_id) = 0;
|
||||
|
||||
virtual void accessibility_update_set_role(const RID &p_id, DisplayServer::AccessibilityRole p_role) = 0;
|
||||
virtual void accessibility_update_set_name(const RID &p_id, const String &p_name) = 0;
|
||||
|
||||
Reference in New Issue
Block a user