From 86909fb4ed13cb47e716473e55836f1ea2668e09 Mon Sep 17 00:00:00 2001 From: Caio Oliveira Date: Thu, 18 Sep 2025 23:31:56 -0300 Subject: [PATCH] [meta] Add option to FORCE X11 as Graphics Backend * save the option on a external file because settings are loaded AFTER Qt window is created and then the graphics backend is already applied Signed-off-by: Caio Oliveira --- src/common/settings.h | 4 ++ src/qt_common/CMakeLists.txt | 4 ++ src/qt_common/gui_settings.cpp | 25 +++++++++++ src/qt_common/gui_settings.h | 14 ++++++ src/qt_common/shared_translation.cpp | 4 ++ src/yuzu/main.cpp | 64 ++++++++++++++++++++++++++++ src/yuzu/main.h | 3 ++ 7 files changed, 118 insertions(+) create mode 100644 src/qt_common/gui_settings.cpp create mode 100644 src/qt_common/gui_settings.h diff --git a/src/common/settings.h b/src/common/settings.h index 8605445837..6279088909 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -643,6 +643,10 @@ struct Values { // Linux SwitchableSetting enable_gamemode{linkage, true, "enable_gamemode", Category::Linux}; +#ifdef __unix__ + SwitchableSetting gui_force_x11{linkage, false, "gui_force_x11", Category::Linux}; + Setting gui_hide_backend_warning{linkage, false, "gui_hide_backend_warning", Category::Linux}; +#endif // Controls InputSetting> players; diff --git a/src/qt_common/CMakeLists.txt b/src/qt_common/CMakeLists.txt index eb36de4cf2..21f3f7dd50 100644 --- a/src/qt_common/CMakeLists.txt +++ b/src/qt_common/CMakeLists.txt @@ -30,6 +30,10 @@ add_library(qt_common STATIC ) +if (UNIX) + target_sources(qt_common PRIVATE gui_settings.cpp gui_settings.h) +endif() + create_target_directory_groups(qt_common) # TODO(crueter) diff --git a/src/qt_common/gui_settings.cpp b/src/qt_common/gui_settings.cpp new file mode 100644 index 0000000000..982d28bbcb --- /dev/null +++ b/src/qt_common/gui_settings.cpp @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "gui_settings.h" +#include "common/fs/fs.h" +#include "common/fs/path_util.h" + +namespace FS = Common::FS; + +namespace GraphicsBackend { + +QString GuiConfigPath() { + return QString::fromStdString(FS::PathToUTF8String(FS::GetEdenPath(FS::EdenPath::ConfigDir) / "gui_config.ini")); +} + +void SetForceX11(bool state) { + (void)FS::CreateParentDir(GuiConfigPath().toStdString()); + QSettings(GuiConfigPath(), QSettings::IniFormat).setValue("gui_force_x11", state); +} + +bool GetForceX11() { + return QSettings(GuiConfigPath(), QSettings::IniFormat).value("gui_force_x11", false).toBool(); +} + +} // namespace GraphicsBackend diff --git a/src/qt_common/gui_settings.h b/src/qt_common/gui_settings.h new file mode 100644 index 0000000000..f37572bb71 --- /dev/null +++ b/src/qt_common/gui_settings.h @@ -0,0 +1,14 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include +#include + +namespace GraphicsBackend { + +void SetForceX11(bool state); +bool GetForceX11(); + +} // namespace GraphicsBackend diff --git a/src/qt_common/shared_translation.cpp b/src/qt_common/shared_translation.cpp index 98a55e1fcf..d450681e79 100644 --- a/src/qt_common/shared_translation.cpp +++ b/src/qt_common/shared_translation.cpp @@ -446,6 +446,10 @@ std::unique_ptr InitializeTranslations(QObject* parent) // Linux INSERT(Settings, enable_gamemode, tr("Enable Gamemode"), QString()); +#ifdef __unix__ + INSERT(Settings, gui_force_x11, tr("Force X11 as Graphics Backend"), QString()); + INSERT(Settings, gui_hide_backend_warning, QString(), QString()); +#endif // Ui Debugging diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index d2c12c9d40..948ed0601d 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -21,6 +21,7 @@ #ifdef __unix__ #include #include +#include "qt_common/gui_settings.h" #endif #ifdef __linux__ #include "common/linux/gamemode.h" @@ -544,6 +545,10 @@ GMainWindow::GMainWindow(bool has_broken_vulkan) // Gen keys if necessary OnCheckFirmwareDecryption(); +#ifdef __unix__ + OnCheckGraphicsBackend(); +#endif + game_list->LoadCompatibilityList(); // force reload on first load to ensure add-ons get updated game_list->PopulateAsync(UISettings::values.game_dirs); @@ -3420,6 +3425,9 @@ void GMainWindow::OnConfigure() { #ifdef __linux__ const bool old_gamemode = Settings::values.enable_gamemode.GetValue(); #endif +#ifdef __unix__ + const bool old_force_x11 = Settings::values.gui_force_x11.GetValue(); +#endif Settings::SetConfiguringGlobal(true); ConfigureDialog configure_dialog(this, hotkey_registry, input_subsystem.get(), @@ -3484,6 +3492,11 @@ void GMainWindow::OnConfigure() { SetGamemodeEnabled(Settings::values.enable_gamemode.GetValue()); } #endif +#ifdef __unix__ + if (Settings::values.gui_force_x11.GetValue() != old_force_x11) { + GraphicsBackend::SetForceX11(Settings::values.gui_force_x11.GetValue()); + } +#endif if (!multiplayer_state->IsHostingPublicRoom()) { multiplayer_state->UpdateCredentials(); @@ -4448,6 +4461,54 @@ void GMainWindow::OnCheckFirmwareDecryption() { UpdateMenuState(); } +#ifdef __unix__ +void GMainWindow::OnCheckGraphicsBackend() { + const QString platformName = QGuiApplication::platformName(); + const QByteArray qtPlatform = qgetenv("QT_QPA_PLATFORM"); + + if (platformName == QStringLiteral("xcb") || qtPlatform == "xcb") + return; + + const bool isWayland = platformName.startsWith(QStringLiteral("wayland"), Qt::CaseInsensitive) || qtPlatform.startsWith("wayland"); + if (!isWayland) + return; + + const bool currently_hidden = Settings::values.gui_hide_backend_warning.GetValue(); + if (currently_hidden) + return; + + QMessageBox msgbox(this); + msgbox.setWindowTitle(tr("Wayland Detected!")); + msgbox.setText(tr("You are running Eden under Wayland Graphics Backend.\n\n" + "It's recommended to use X11 for the best compatibility.\n\n" + "There's no plan to support Wayland at moment\nExpect crashes!")); + msgbox.setIcon(QMessageBox::Warning); + + QPushButton* okButton = msgbox.addButton(tr("Use X11"), QMessageBox::AcceptRole); + QPushButton* cancelButton = msgbox.addButton(tr("Continue with Wayland"), QMessageBox::RejectRole); + msgbox.setDefaultButton(okButton); + + QCheckBox* cb = new QCheckBox(tr("Don't show again"), &msgbox); + cb->setChecked(currently_hidden); + msgbox.setCheckBox(cb); + + msgbox.exec(); + + const bool hide = cb->isChecked(); + if (hide != currently_hidden) { + Settings::values.gui_hide_backend_warning.SetValue(hide); + } + + if (msgbox.clickedButton() == okButton) { + Settings::values.gui_force_x11.SetValue(true); + GraphicsBackend::SetForceX11(true); + QMessageBox::information(this, + tr("Restart Required"), + tr("Restart Eden to apply the X11 backend.")); + } +} +#endif + bool GMainWindow::CheckFirmwarePresence() { return FirmwareManager::CheckFirmwarePresence(*QtCommon::system.get()); } @@ -4937,6 +4998,9 @@ int main(int argc, char* argv[]) { qputenv("DISPLAY", ":0"); } + if (GraphicsBackend::GetForceX11()) + qputenv("QT_QPA_PLATFORM", "xcb"); + // Fix the Wayland appId. This needs to match the name of the .desktop file without the .desktop // suffix. QGuiApplication::setDesktopFileName(QStringLiteral("dev.eden_emu.eden")); diff --git a/src/yuzu/main.h b/src/yuzu/main.h index e3922759b0..3515238280 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -411,6 +411,9 @@ private slots: void OnCreateHomeMenuApplicationMenuShortcut(); void OnCaptureScreenshot(); void OnCheckFirmwareDecryption(); +#ifdef __unix__ + void OnCheckGraphicsBackend(); +#endif void OnLanguageChanged(const QString& locale); void OnMouseActivity(); bool OnShutdownBegin();