From 4b8cfc3040b9a07a6fe506f2b8bfc52a53ac8d60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Sun, 26 Jan 2025 23:15:18 +0200 Subject: [PATCH] Fix native popup menus position in embedded windows. --- platform/macos/native_menu_macos.mm | 2 +- scene/gui/popup_menu.cpp | 19 +++++++++++++++++-- scene/gui/popup_menu.h | 1 + 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/platform/macos/native_menu_macos.mm b/platform/macos/native_menu_macos.mm index 802d58dc269..8ec013bbdae 100644 --- a/platform/macos/native_menu_macos.mm +++ b/platform/macos/native_menu_macos.mm @@ -293,7 +293,7 @@ void NativeMenuMacOS::popup(const RID &p_rid, const Vector2i &p_position) { position += ds->_get_screens_origin(); position /= ds->screen_get_max_scale(); - [md->menu popUpMenuPositioningItem:nil atLocation:NSMakePoint(position.x, position.y) inView:nil]; + [md->menu popUpMenuPositioningItem:nil atLocation:NSMakePoint(position.x, position.y - 5) inView:nil]; // Menu vertical position doesn't include rounded corners, add `5` display pixels to better align it with Godot buttons. } } diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 5b9dd8655cd..092a12bd148 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -2958,6 +2958,21 @@ void PopupMenu::_bind_methods() { PropertyListHelper::register_base_helper(&base_property_helper); } +void PopupMenu::_native_popup(const Rect2i &p_rect) { + Point2i popup_pos = p_rect.position; + if (is_embedded()) { + popup_pos = get_embedder()->get_screen_transform().xform(popup_pos); // Note: for embedded windows "screen transform" is transform relative to embedder not the actual screen. + DisplayServer::WindowID wid = get_window_id(); + if (wid == DisplayServer::INVALID_WINDOW_ID) { + wid = DisplayServer::MAIN_WINDOW_ID; + } + popup_pos += DisplayServer::get_singleton()->window_get_position(wid); + } + float win_scale = get_parent_visible_window()->get_content_scale_factor(); + NativeMenu::get_singleton()->set_minimum_width(global_menu, p_rect.size.x * win_scale); + NativeMenu::get_singleton()->popup(global_menu, popup_pos); +} + void PopupMenu::popup(const Rect2i &p_bounds) { bool native = global_menu.is_valid(); #ifdef TOOLS_ENABLED @@ -2967,7 +2982,7 @@ void PopupMenu::popup(const Rect2i &p_bounds) { #endif if (native) { - NativeMenu::get_singleton()->popup(global_menu, (p_bounds != Rect2i()) ? p_bounds.position : get_position()); + _native_popup(p_bounds != Rect2i() ? p_bounds : Rect2i(get_position(), Size2i())); } else { set_flag(FLAG_NO_FOCUS, !is_embedded()); @@ -2995,7 +3010,7 @@ void PopupMenu::set_visible(bool p_visible) { if (native) { if (p_visible) { - NativeMenu::get_singleton()->popup(global_menu, get_position()); + _native_popup(Rect2i(get_position(), get_size())); } } else { set_flag(FLAG_NO_FOCUS, !is_embedded()); diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index bed158ba17c..bf84d5effc6 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -215,6 +215,7 @@ class PopupMenu : public Popup { bool _set_item_accelerator(int p_index, const Ref &p_ie); void _set_item_checkable_type(int p_index, int p_checkable_type); int _get_item_checkable_type(int p_index) const; + void _native_popup(const Rect2i &p_rect); protected: virtual Rect2i _popup_adjust_rect() const override;