Bladeren bron

Fix native popup menus position in embedded windows.

Pāvels Nadtočajevs 7 maanden geleden
bovenliggende
commit
4b8cfc3040
3 gewijzigde bestanden met toevoegingen van 19 en 3 verwijderingen
  1. 1 1
      platform/macos/native_menu_macos.mm
  2. 17 2
      scene/gui/popup_menu.cpp
  3. 1 0
      scene/gui/popup_menu.h

+ 1 - 1
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.
 	}
 }
 

+ 17 - 2
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());

+ 1 - 0
scene/gui/popup_menu.h

@@ -215,6 +215,7 @@ class PopupMenu : public Popup {
 	bool _set_item_accelerator(int p_index, const Ref<InputEventKey> &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;