@@ -570,6 +570,10 @@ bool Window::get_flag(Flags p_flag) const {
570570 return flags[p_flag];
571571}
572572
573+ bool Window::is_popup() const {
574+ return get_flag(Window::FLAG_POPUP) || get_flag(Window::FLAG_NO_FOCUS);
575+ }
576+
573577bool Window::is_maximize_allowed() const {
574578 ERR_READ_THREAD_GUARD_V(false);
575579 if (window_id != DisplayServer::INVALID_WINDOW_ID) {
@@ -680,11 +684,6 @@ void Window::_make_window() {
680684 }
681685 }
682686
683- if (get_tree() && get_tree()->is_accessibility_supported()) {
684- get_tree()->_accessibility_force_update();
685- _accessibility_notify_enter(this);
686- }
687-
688687 _update_window_callbacks();
689688
690689 RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_WHEN_VISIBLE);
@@ -716,10 +715,6 @@ void Window::_clear_window() {
716715
717716 _update_from_window();
718717
719- if (get_tree() && get_tree()->is_accessibility_supported()) {
720- _accessibility_notify_exit(this);
721- }
722-
723718 DisplayServer::get_singleton()->delete_sub_window(window_id);
724719 window_id = DisplayServer::INVALID_WINDOW_ID;
725720
@@ -886,7 +881,7 @@ void Window::_accessibility_notify_enter(Node *p_node) {
886881
887882 if (p_node != this) {
888883 const Window *window = Object::cast_to<Window>(p_node);
889- if (window && !window->is_embedded() ) {
884+ if (window) {
890885 return;
891886 }
892887 }
@@ -901,7 +896,7 @@ void Window::_accessibility_notify_exit(Node *p_node) {
901896
902897 if (p_node != this) {
903898 const Window *window = Object::cast_to<Window>(p_node);
904- if (window && !window->is_embedded() ) {
899+ if (window) {
905900 return;
906901 }
907902 }
@@ -950,23 +945,35 @@ void Window::set_visible(bool p_visible) {
950945 }
951946 }
952947 embedder->_sub_window_register(this);
953- embedder->queue_accessibility_update();
954948 RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE);
955949 } else {
956950 embedder->_sub_window_remove(this);
957- embedder->queue_accessibility_update();
958951 embedder = nullptr;
959952 RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED);
960953 }
961954 _update_window_size();
962955 }
963956
964- if (!visible) {
957+ if (visible) {
958+ if (get_tree() && get_tree()->is_accessibility_supported()) {
959+ get_tree()->_accessibility_force_update();
960+ _accessibility_notify_enter(this);
961+ }
962+ } else {
963+ if (get_tree() && get_tree()->is_accessibility_supported()) {
964+ _accessibility_notify_exit(this);
965+ }
965966 focused = false;
966967 if (focused_window == this) {
967968 focused_window = nullptr;
968969 }
969970 }
971+ if (get_parent()) {
972+ get_parent()->queue_accessibility_update();
973+ }
974+ if (embedder) {
975+ embedder->queue_accessibility_update();
976+ }
970977
971978 notification(NOTIFICATION_VISIBILITY_CHANGED);
972979 emit_signal(SceneStringName(visibility_changed));
@@ -1371,10 +1378,10 @@ Viewport *Window::get_embedder() const {
13711378}
13721379
13731380RID Window::get_accessibility_element() const {
1374- if (is_part_of_edited_scene()) {
1381+ if (!visible || is_part_of_edited_scene()) {
13751382 return RID();
13761383 }
1377- if (get_embedder()) {
1384+ if (get_embedder() || is_popup() ) {
13781385 return Node::get_accessibility_element();
13791386 } else if (window_id != DisplayServer::INVALID_WINDOW_ID) {
13801387 return DisplayServer::get_singleton()->accessibility_get_window_root(window_id);
@@ -1415,11 +1422,18 @@ void Window::_notification(int p_what) {
14151422 DisplayServer::get_singleton()->accessibility_update_add_action(ae, DisplayServer::AccessibilityAction::ACTION_FOCUS, callable_mp(this, &Window::_accessibility_action_grab_focus));
14161423 DisplayServer::get_singleton()->accessibility_update_set_flag(ae, DisplayServer::AccessibilityFlags::FLAG_HIDDEN, !visible);
14171424
1418- if (get_embedder()) {
1425+ if (get_embedder() || is_popup() ) {
14191426 Control *parent_ctrl = Object::cast_to<Control>(get_parent());
14201427 Transform2D parent_tr = parent_ctrl ? parent_ctrl->get_global_transform() : Transform2D();
14211428 Transform2D tr;
1422- tr.set_origin(position);
1429+ if (window_id == DisplayServer::INVALID_WINDOW_ID) {
1430+ tr.set_origin(position);
1431+ } else {
1432+ Window *np = get_non_popup_window();
1433+ if (np) {
1434+ tr.set_origin(get_position() - np->get_position());
1435+ }
1436+ }
14231437 DisplayServer::get_singleton()->accessibility_update_set_transform(ae, parent_tr.affine_inverse() * tr);
14241438 DisplayServer::get_singleton()->accessibility_update_set_bounds(ae, Rect2(Point2(), size));
14251439
@@ -1540,9 +1554,19 @@ void Window::_notification(int p_what) {
15401554 _make_transient();
15411555 }
15421556 if (visible) {
1557+ if (window_id != DisplayServer::MAIN_WINDOW_ID && get_tree() && get_tree()->is_accessibility_supported()) {
1558+ get_tree()->_accessibility_force_update();
1559+ _accessibility_notify_enter(this);
1560+ }
15431561 notification(NOTIFICATION_VISIBILITY_CHANGED);
15441562 emit_signal(SceneStringName(visibility_changed));
15451563 RS::get_singleton()->viewport_set_active(get_viewport_rid(), true);
1564+ if (get_parent()) {
1565+ get_parent()->queue_accessibility_update();
1566+ }
1567+ if (embedder) {
1568+ embedder->queue_accessibility_update();
1569+ }
15461570 }
15471571
15481572 // Emits NOTIFICATION_THEME_CHANGED internally.
@@ -1584,6 +1608,18 @@ void Window::_notification(int p_what) {
15841608
15851609 set_theme_context(nullptr, false);
15861610
1611+ if (visible && window_id != DisplayServer::MAIN_WINDOW_ID) {
1612+ if (get_tree() && get_tree()->is_accessibility_supported()) {
1613+ _accessibility_notify_exit(this);
1614+ if (get_parent()) {
1615+ get_parent()->queue_accessibility_update();
1616+ }
1617+ if (embedder) {
1618+ embedder->queue_accessibility_update();
1619+ }
1620+ }
1621+ }
1622+
15871623 accessibility_title_element = RID();
15881624 accessibility_announcement_element = RID();
15891625
@@ -1816,6 +1852,14 @@ Viewport *Window::get_parent_viewport() const {
18161852 }
18171853}
18181854
1855+ Window *Window::get_non_popup_window() const {
1856+ Window *w = const_cast<Window *>(this);
1857+ while (w && w->is_popup()) {
1858+ w = w->get_parent_visible_window();
1859+ }
1860+ return w;
1861+ }
1862+
18191863Window *Window::get_parent_visible_window() const {
18201864 ERR_READ_THREAD_GUARD_V(nullptr);
18211865 Viewport *vp = get_parent_viewport();
0 commit comments