From a12627765fb8941c0c90dd40616c13677a8f9a1c Mon Sep 17 00:00:00 2001 From: Markus Sauermann <6299227+Sauermann@users.noreply.github.com> Date: Tue, 20 Jun 2023 15:50:44 +0200 Subject: [PATCH] Embedded Popups store their safe_rect in their embedder Storing it in the DisplayServer didn't make sense in this case, because the embedded window is unknown to the DisplayServer. --- scene/gui/popup_menu.cpp | 9 +++++++-- scene/main/viewport.cpp | 17 ++++++++++++++++- scene/main/viewport.h | 5 ++++- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index adeaf9a49f4..72f1ee72170 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -244,7 +244,12 @@ void PopupMenu::_activate_submenu(int p_over, bool p_by_keyboard) { Rect2 safe_area = this_rect; safe_area.position.y += items[p_over]._ofs_cache + scroll_offset + theme_cache.panel_style->get_offset().height - theme_cache.v_separation / 2; safe_area.size.y = items[p_over]._height_cache + theme_cache.v_separation; - DisplayServer::get_singleton()->window_set_popup_safe_rect(submenu_popup->get_window_id(), safe_area); + Viewport *vp = submenu_popup->get_embedder(); + if (vp) { + vp->subwindow_set_popup_safe_rect(submenu_popup, safe_area); + } else { + DisplayServer::get_singleton()->window_set_popup_safe_rect(submenu_popup->get_window_id(), safe_area); + } // Make the position of the parent popup relative to submenu popup. this_rect.position = this_rect.position - submenu_pum->get_position(); @@ -273,7 +278,7 @@ void PopupMenu::_parent_focused() { window_parent = Object::cast_to(window_parent->get_parent()->get_viewport()); } - Rect2 safe_area = DisplayServer::get_singleton()->window_get_popup_safe_rect(get_window_id()); + Rect2 safe_area = get_embedder()->subwindow_get_popup_safe_rect(this); Point2 pos = DisplayServer::get_singleton()->mouse_get_position() - mouse_pos_adjusted; if (safe_area == Rect2i() || !safe_area.has_point(pos)) { Popup::_parent_focused(); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index b395c908439..a20e62515aa 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -462,7 +462,7 @@ void Viewport::_sub_window_remove(Window *p_window) { RenderingServer::get_singleton()->viewport_set_parent_viewport(p_window->viewport, p_window->parent ? p_window->parent->viewport : RID()); } -int Viewport::_sub_window_find(Window *p_window) { +int Viewport::_sub_window_find(Window *p_window) const { for (int i = 0; i < gui.sub_windows.size(); i++) { if (gui.sub_windows[i].window == p_window) { return i; @@ -3482,6 +3482,21 @@ bool Viewport::is_embedding_subwindows() const { return gui.embed_subwindows_hint; } +void Viewport::subwindow_set_popup_safe_rect(Window *p_window, const Rect2i &p_rect) { + int index = _sub_window_find(p_window); + ERR_FAIL_COND(index == -1); + + SubWindow sw = gui.sub_windows[index]; + sw.parent_safe_rect = p_rect; +} + +Rect2i Viewport::subwindow_get_popup_safe_rect(Window *p_window) const { + int index = _sub_window_find(p_window); + ERR_FAIL_COND_V(index == -1, Rect2i()); + + return gui.sub_windows[index].parent_safe_rect; +} + void Viewport::pass_mouse_focus_to(Viewport *p_viewport, Control *p_control) { ERR_MAIN_THREAD_GUARD; ERR_FAIL_NULL(p_viewport); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index af2907ca6f1..e56d69a8684 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -338,6 +338,7 @@ private: struct SubWindow { Window *window = nullptr; RID canvas_item; + Rect2i parent_safe_rect; }; // VRS @@ -461,7 +462,7 @@ private: void _sub_window_update(Window *p_window); void _sub_window_grab_focus(Window *p_window); void _sub_window_remove(Window *p_window); - int _sub_window_find(Window *p_window); + int _sub_window_find(Window *p_window) const; bool _sub_windows_forward_input(const Ref &p_event); SubWindowResize _sub_window_get_resize_margin(Window *p_subwindow, const Point2 &p_point); @@ -644,6 +645,8 @@ public: void set_embedding_subwindows(bool p_embed); bool is_embedding_subwindows() const; + void subwindow_set_popup_safe_rect(Window *p_window, const Rect2i &p_rect); + Rect2i subwindow_get_popup_safe_rect(Window *p_window) const; Viewport *get_parent_viewport() const; Window *get_base_window() const;