diff options
| author | crueter <crueter@eden-emu.dev> | 2025-09-15 17:21:18 +0200 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2025-09-15 17:21:18 +0200 |
| commit | f4386423e88ae2c01b4f7afb1ac46deb50d39332 (patch) | |
| tree | 8a3b3fc11c9f8fe1f28c3a6fde06eff98f69fa05 /src/qt_common/qt_common.cpp | |
| parent | 4c5d03f5defedd6decf2dfbbaca93a518e6d0adc (diff) | |
[qt] refactor: qt_common lib (#94)
This is part of a series of PRs made in preparation for the QML rewrite. this PR specifically moves a bunch of utility functions from main.cpp into qt_common, with the biggest benefit being that QML can reuse the exact same code through ctx passthrough.
Also, QtCommon::Frontend is an abstraction layer over several previously Widgets-specific stuff like QMessageBox that gets used everywhere. The idea is that once QML is implemented, these functions can have a Quick version implemented for systems that don't work well with Widgets (sun) or for those on Plasma 6+ (reduces memory usage w/o Widgets linkage) although Quick from C++ is actually anal, but whatever.
Other than that this should also just kinda reduce the size of main.cpp which is a 6000-line behemoth rn, and clangd straight up gives up with it for me (likely caused by the massive amount of headers, which this DOES reduce).
In the future, I probably want to create a common strings lookup table that both Qt and QML can reference--though I'm not sure how much linguist likes that--which should give us a way to keep language consistent (use frozen-map).
TODO: Docs for Qt stuff
Co-authored-by: MaranBr <maranbr@outlook.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/94
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Diffstat (limited to 'src/qt_common/qt_common.cpp')
| -rw-r--r-- | src/qt_common/qt_common.cpp | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/src/qt_common/qt_common.cpp b/src/qt_common/qt_common.cpp new file mode 100644 index 0000000000..6be241c740 --- /dev/null +++ b/src/qt_common/qt_common.cpp @@ -0,0 +1,122 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "qt_common.h" +#include "common/fs/fs.h" + +#include <QGuiApplication> +#include <QStringLiteral> +#include "common/logging/log.h" +#include "core/frontend/emu_window.h" + +#include <QFile> + +#include <QMessageBox> + +#include <JlCompress.h> + +#if !defined(WIN32) && !defined(__APPLE__) +#include <qpa/qplatformnativeinterface.h> +#elif defined(__APPLE__) +#include <objc/message.h> +#endif + +namespace QtCommon { + +#ifdef YUZU_QT_WIDGETS +QWidget* rootObject = nullptr; +#else +QObject* rootObject = nullptr; +#endif + +std::unique_ptr<Core::System> system = nullptr; +std::shared_ptr<FileSys::RealVfsFilesystem> vfs = nullptr; +std::unique_ptr<FileSys::ManualContentProvider> provider = nullptr; + +Core::Frontend::WindowSystemType GetWindowSystemType() +{ + // Determine WSI type based on Qt platform. + QString platform_name = QGuiApplication::platformName(); + if (platform_name == QStringLiteral("windows")) + return Core::Frontend::WindowSystemType::Windows; + else if (platform_name == QStringLiteral("xcb")) + return Core::Frontend::WindowSystemType::X11; + else if (platform_name == QStringLiteral("wayland")) + return Core::Frontend::WindowSystemType::Wayland; + else if (platform_name == QStringLiteral("wayland-egl")) + return Core::Frontend::WindowSystemType::Wayland; + else if (platform_name == QStringLiteral("cocoa")) + return Core::Frontend::WindowSystemType::Cocoa; + else if (platform_name == QStringLiteral("android")) + return Core::Frontend::WindowSystemType::Android; + + LOG_CRITICAL(Frontend, "Unknown Qt platform {}!", platform_name.toStdString()); + return Core::Frontend::WindowSystemType::Windows; +} // namespace Core::Frontend::WindowSystemType + +Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window) +{ + Core::Frontend::EmuWindow::WindowSystemInfo wsi; + wsi.type = GetWindowSystemType(); + +#if defined(WIN32) + // Our Win32 Qt external doesn't have the private API. + wsi.render_surface = reinterpret_cast<void*>(window->winId()); +#elif defined(__APPLE__) + wsi.render_surface = reinterpret_cast<void* (*) (id, SEL)>( + objc_msgSend)(reinterpret_cast<id>(window->winId()), sel_registerName("layer")); +#else + QPlatformNativeInterface* pni = QGuiApplication::platformNativeInterface(); + wsi.display_connection = pni->nativeResourceForWindow("display", window); + if (wsi.type == Core::Frontend::WindowSystemType::Wayland) + wsi.render_surface = window ? pni->nativeResourceForWindow("surface", window) : nullptr; + else + wsi.render_surface = window ? reinterpret_cast<void*>(window->winId()) : nullptr; +#endif + wsi.render_surface_scale = window ? static_cast<float>(window->devicePixelRatio()) : 1.0f; + + return wsi; +} + +const QString tr(const char* str) +{ + return QGuiApplication::tr(str); +} + +const QString tr(const std::string& str) +{ + return QGuiApplication::tr(str.c_str()); +} + +#ifdef YUZU_QT_WIDGETS +void Init(QWidget* root) +#else +void Init(QObject* root) +#endif +{ + system = std::make_unique<Core::System>(); + rootObject = root; + vfs = std::make_unique<FileSys::RealVfsFilesystem>(); + provider = std::make_unique<FileSys::ManualContentProvider>(); +} + +std::filesystem::path GetEdenCommand() { + std::filesystem::path command; + + QString appimage = QString::fromLocal8Bit(getenv("APPIMAGE")); + if (!appimage.isEmpty()) { + command = std::filesystem::path{appimage.toStdString()}; + } else { + const QStringList args = QGuiApplication::arguments(); + command = args[0].toStdString(); + } + + // If relative path, make it an absolute path + if (command.c_str()[0] == '.') { + command = Common::FS::GetCurrentDir() / command; + } + + return command; +} + +} // namespace QtCommon |
