Skip to content

Commit 92ebcd2

Browse files
committed
Merge pull request godotengine#102079 from bruvzg/emb_nmenu
Fix native popup menus position in embedded windows.
2 parents d5eacef + 4b8cfc3 commit 92ebcd2

File tree

3 files changed

+19
-3
lines changed

3 files changed

+19
-3
lines changed

platform/macos/native_menu_macos.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@
293293
position += ds->_get_screens_origin();
294294
position /= ds->screen_get_max_scale();
295295

296-
[md->menu popUpMenuPositioningItem:nil atLocation:NSMakePoint(position.x, position.y) inView:nil];
296+
[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.
297297
}
298298
}
299299

scene/gui/popup_menu.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2958,6 +2958,21 @@ void PopupMenu::_bind_methods() {
29582958
PropertyListHelper::register_base_helper(&base_property_helper);
29592959
}
29602960

2961+
void PopupMenu::_native_popup(const Rect2i &p_rect) {
2962+
Point2i popup_pos = p_rect.position;
2963+
if (is_embedded()) {
2964+
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.
2965+
DisplayServer::WindowID wid = get_window_id();
2966+
if (wid == DisplayServer::INVALID_WINDOW_ID) {
2967+
wid = DisplayServer::MAIN_WINDOW_ID;
2968+
}
2969+
popup_pos += DisplayServer::get_singleton()->window_get_position(wid);
2970+
}
2971+
float win_scale = get_parent_visible_window()->get_content_scale_factor();
2972+
NativeMenu::get_singleton()->set_minimum_width(global_menu, p_rect.size.x * win_scale);
2973+
NativeMenu::get_singleton()->popup(global_menu, popup_pos);
2974+
}
2975+
29612976
void PopupMenu::popup(const Rect2i &p_bounds) {
29622977
bool native = global_menu.is_valid();
29632978
#ifdef TOOLS_ENABLED
@@ -2967,7 +2982,7 @@ void PopupMenu::popup(const Rect2i &p_bounds) {
29672982
#endif
29682983

29692984
if (native) {
2970-
NativeMenu::get_singleton()->popup(global_menu, (p_bounds != Rect2i()) ? p_bounds.position : get_position());
2985+
_native_popup(p_bounds != Rect2i() ? p_bounds : Rect2i(get_position(), Size2i()));
29712986
} else {
29722987
set_flag(FLAG_NO_FOCUS, !is_embedded());
29732988

@@ -2995,7 +3010,7 @@ void PopupMenu::set_visible(bool p_visible) {
29953010

29963011
if (native) {
29973012
if (p_visible) {
2998-
NativeMenu::get_singleton()->popup(global_menu, get_position());
3013+
_native_popup(Rect2i(get_position(), get_size()));
29993014
}
30003015
} else {
30013016
set_flag(FLAG_NO_FOCUS, !is_embedded());

scene/gui/popup_menu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ class PopupMenu : public Popup {
215215
bool _set_item_accelerator(int p_index, const Ref<InputEventKey> &p_ie);
216216
void _set_item_checkable_type(int p_index, int p_checkable_type);
217217
int _get_item_checkable_type(int p_index) const;
218+
void _native_popup(const Rect2i &p_rect);
218219

219220
protected:
220221
virtual Rect2i _popup_adjust_rect() const override;

0 commit comments

Comments
 (0)