diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index 622860e777e..ae74936a208 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -81,6 +81,10 @@ void MenuButton::show_popup() { emit_signal(SNAME("about_to_popup")); Rect2 rect = get_screen_rect(); rect.position.y += rect.size.height; + if (get_viewport()->is_embedding_subwindows() && popup->get_force_native()) { + Transform2D xform = get_viewport()->get_popup_base_transform_native(); + rect = xform.xform(rect); + } rect.size.height = 0; popup->set_size(rect.size); if (is_layout_rtl()) { diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index d1a1d21a416..2823ba9c792 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -541,6 +541,10 @@ void OptionButton::show_popup() { Rect2 rect = get_screen_rect(); rect.position.y += rect.size.height; + if (get_viewport()->is_embedding_subwindows() && popup->get_force_native()) { + Transform2D xform = get_viewport()->get_popup_base_transform_native(); + rect = xform.xform(rect); + } rect.size.height = 0; popup->popup(rect); } diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 52295343938..facd4aa4386 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -3216,7 +3216,7 @@ void PopupMenu::popup(const Rect2i &p_bounds) { } void PopupMenu::_pre_popup() { - Size2 scale = get_parent_viewport()->get_popup_base_transform().get_scale(); + Size2 scale = get_force_native() ? get_parent_viewport()->get_popup_base_transform_native().get_scale() : get_parent_viewport()->get_popup_base_transform().get_scale(); CanvasItem *c = Object::cast_to(get_parent()); if (c) { scale *= c->get_global_transform_with_canvas().get_scale(); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 03cc39ee92c..0ed3864b08e 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -730,6 +730,7 @@ public: Transform2D get_screen_transform() const; virtual Transform2D get_screen_transform_internal(bool p_absolute_position = false) const; + virtual Transform2D get_popup_base_transform_native() const { return Transform2D(); } virtual Transform2D get_popup_base_transform() const { return Transform2D(); } virtual Viewport *get_section_root_viewport() const { return nullptr; } virtual bool is_attached_in_viewport() const { return false; } diff --git a/scene/main/window.cpp b/scene/main/window.cpp index e3eb4bfa6f0..49811492498 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -3028,6 +3028,20 @@ Transform2D Window::get_screen_transform_internal(bool p_absolute_position) cons return embedder_transform * get_final_transform(); } +Transform2D Window::get_popup_base_transform_native() const { + ERR_READ_THREAD_GUARD_V(Transform2D()); + if (!DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_SUBWINDOWS)) { + return Transform2D(); + } + Transform2D popup_base_transform; + popup_base_transform.set_origin(get_position()); + popup_base_transform *= get_final_transform(); + if (get_embedder()) { + return get_embedder()->get_popup_base_transform_native() * popup_base_transform; + } + return popup_base_transform; +} + Transform2D Window::get_popup_base_transform() const { ERR_READ_THREAD_GUARD_V(Transform2D()); if (is_embedding_subwindows()) { diff --git a/scene/main/window.h b/scene/main/window.h index b53a3808558..cd023de18e9 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -509,6 +509,7 @@ public: virtual Transform2D get_final_transform() const override; virtual Transform2D get_screen_transform_internal(bool p_absolute_position = false) const override; virtual Transform2D get_popup_base_transform() const override; + virtual Transform2D get_popup_base_transform_native() const override; virtual Viewport *get_section_root_viewport() const override; virtual bool is_attached_in_viewport() const override;