diff --git a/src/qt_common/qt_common.cpp b/src/qt_common/qt_common.cpp index f2091df866..af4e4ffa61 100644 --- a/src/qt_common/qt_common.cpp +++ b/src/qt_common/qt_common.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later #include "qt_common.h" @@ -22,6 +22,7 @@ #include #elif defined(__APPLE__) #include +#include #endif namespace QtCommon { @@ -68,8 +69,32 @@ Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window) // Our Win32 Qt external doesn't have the private API. wsi.render_surface = reinterpret_cast(window->winId()); #elif defined(__APPLE__) - wsi.render_surface = reinterpret_cast( + id layer = reinterpret_cast( objc_msgSend)(reinterpret_cast(window->winId()), sel_registerName("layer")); + + // In Qt 6, the layer of the NSView might be a QContainerLayer. + // MoltenVK needs a CAMetalLayer. We search for it in sublayers. + Class metal_layer_class = objc_getClass("CAMetalLayer"); + id metal_layer = nullptr; + + if (layer) { + if (reinterpret_cast(objc_msgSend)(layer, sel_registerName("isKindOfClass:"), metal_layer_class)) { + metal_layer = layer; + } else { + id sublayers = reinterpret_cast(objc_msgSend)(layer, sel_registerName("sublayers")); + if (sublayers) { + unsigned long count = reinterpret_cast(objc_msgSend)(sublayers, sel_registerName("count")); + for (unsigned long i = 0; i < count; ++i) { + id sublayer = reinterpret_cast(objc_msgSend)(sublayers, sel_registerName("objectAtIndex:"), i); + if (reinterpret_cast(objc_msgSend)(sublayer, sel_registerName("isKindOfClass:"), metal_layer_class)) { + metal_layer = sublayer; + break; + } + } + } + } + } + wsi.render_surface = reinterpret_cast(metal_layer ? metal_layer : layer); #else QPlatformNativeInterface* pni = QGuiApplication::platformNativeInterface(); wsi.display_connection = pni->nativeResourceForWindow("display", window);