mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-11-03 04:18:39 +00:00
[desktop] Prefer X11, but allow Wayland (with a warning) (#4579)
Use `xcb;wayland` as the default value for `QT_QPA_PLATFORM` which will always try X11 first, then only fallback to Wayland if, for some reason, X11 is unavailable or unable to initialize. This also prints a warning to the log if the backend is wayland. Might be promoted to a warning dialog if this becomes a consistent-enough issue to warrant a more obvious warning. Requires removing the wayland hook from the AppImage Signed-off-by: crueter <crueter@eden-emu.dev> - [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions). - [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md). - [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability. ------------------- Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4579 Reviewed-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
@@ -42,10 +42,6 @@ add_library(qt_common STATIC
|
||||
render/context.h
|
||||
render/emu_thread.h render/emu_thread.cpp)
|
||||
|
||||
if (UNIX)
|
||||
target_sources(qt_common PRIVATE gui_settings.cpp gui_settings.h)
|
||||
endif()
|
||||
|
||||
create_target_directory_groups(qt_common)
|
||||
|
||||
if (USE_DISCORD_PRESENCE)
|
||||
|
||||
@@ -345,10 +345,6 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent) {
|
||||
|
||||
// Linux
|
||||
INSERT(UISettings, enable_gamemode, tr("Enable Gamemode"), QString());
|
||||
#ifdef __unix__
|
||||
INSERT(UISettings, gui_force_x11, tr("Force X11 as Graphics Backend"), QString());
|
||||
INSERT(UISettings, gui_hide_backend_warning, QString(), QString());
|
||||
#endif
|
||||
|
||||
// Ui Debugging
|
||||
|
||||
|
||||
@@ -148,11 +148,6 @@ struct Values {
|
||||
false,
|
||||
#endif
|
||||
"enable_gamemode", Category::UiGeneral};
|
||||
#ifdef __unix__
|
||||
SwitchableSetting<bool> gui_force_x11{linkage, false, "gui_force_x11", Category::UiGeneral};
|
||||
Setting<bool> gui_hide_backend_warning{linkage, false, "gui_hide_backend_warning",
|
||||
Category::UiGeneral};
|
||||
#endif
|
||||
|
||||
// Discord RPC
|
||||
Setting<bool> enable_discord_presence{linkage, false, "enable_discord_presence", Category::Ui};
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/path_util.h"
|
||||
#include "gui_settings.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
|
||||
@@ -1,15 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QSettings>
|
||||
#include <QString>
|
||||
|
||||
namespace GraphicsBackend {
|
||||
|
||||
QString GuiConfigPath();
|
||||
void SetForceX11(bool state);
|
||||
bool GetForceX11();
|
||||
|
||||
} // namespace GraphicsBackend
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <thread>
|
||||
#include <JlCompress.h>
|
||||
#include <QPainter>
|
||||
|
||||
#if !defined(WIN32) && !defined(__APPLE__)
|
||||
@@ -37,7 +36,6 @@
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <QApplication>
|
||||
#include <QSettings>
|
||||
#include <windows.h>
|
||||
#include "common/windows/timer_resolution.h"
|
||||
@@ -277,6 +275,14 @@ void Init(QWidget* root) {
|
||||
|
||||
// Remove cached contents generated during the previous session
|
||||
RemoveCachedContents();
|
||||
|
||||
// Platform checks
|
||||
const auto qpa = QGuiApplication::platformName();
|
||||
LOG_INFO(Frontend, "Qt Platform Backend: {}", qpa.toStdString());
|
||||
if (qpa == QStringLiteral("wayland"))
|
||||
LOG_WARNING(
|
||||
Frontend,
|
||||
"Platform backend is set to Wayland, which may cause performance/stability issues");
|
||||
}
|
||||
|
||||
std::filesystem::path GetEdenCommand() {
|
||||
@@ -325,4 +331,47 @@ QPixmap CreateCirclePixmapFromColor(const QColor& color) {
|
||||
return circle_pixmap;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// TODO(crueter): Does this affect Qt 6 at all?
|
||||
static void OverrideWindowsFont() {
|
||||
// Qt5 chooses these fonts on Windows and they have fairly ugly alphanumeric/cyrillic characters
|
||||
// Asking to use "MS Shell Dlg 2" gives better other chars while leaving the Chinese Characters.
|
||||
const QString startup_font = QGuiApplication::font().family();
|
||||
const QStringList ugly_fonts = {QStringLiteral("SimSun"), QStringLiteral("PMingLiU")};
|
||||
if (ugly_fonts.contains(startup_font)) {
|
||||
QGuiApplication::setFont(QFont(QStringLiteral("MS Shell Dlg 2"), 9, QFont::Normal));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void SetupApplication() {
|
||||
// Init settings params
|
||||
QCoreApplication::setOrganizationName(QStringLiteral("eden"));
|
||||
QCoreApplication::setApplicationName(QStringLiteral("eden"));
|
||||
|
||||
#ifdef __unix__
|
||||
// Set the DISPLAY variable in order to open web browsers
|
||||
// TODO (lat9nq): Find a better solution for AppImages to start external applications
|
||||
if (QString::fromLocal8Bit(qgetenv("DISPLAY")).isEmpty()) {
|
||||
qputenv("DISPLAY", ":0");
|
||||
}
|
||||
|
||||
// Always prefer X11 but allow Wayland if the user is missing X11 for some reason.
|
||||
if (qEnvironmentVariableIsEmpty("QT_QPA_PLATFORM"))
|
||||
qputenv("QT_QPA_PLATFORM", "xcb;wayland");
|
||||
|
||||
// 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"));
|
||||
#endif
|
||||
|
||||
// Enables the core to make the qt created contexts current on std::threads
|
||||
QCoreApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity);
|
||||
|
||||
// Make the app look a little better.
|
||||
#ifdef _WIN32
|
||||
OverrideWindowsFont();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace QtCommon
|
||||
|
||||
@@ -42,6 +42,9 @@ void Init(QWidget* root);
|
||||
void SetupContentProviders();
|
||||
void SetupHID();
|
||||
|
||||
// setup env vars, scaling, and app attributes
|
||||
void SetupApplication();
|
||||
|
||||
const QString tr(const char* str);
|
||||
const QString tr(const std::string& str);
|
||||
|
||||
|
||||
+5
-59
@@ -8,12 +8,11 @@
|
||||
#include <cstring>
|
||||
#include "dedicated_room/yuzu_room.h"
|
||||
#endif
|
||||
#ifdef __unix__
|
||||
#include "qt_common/gui_settings.h"
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/resource.h>
|
||||
#else
|
||||
#include <QScreen>
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
@@ -24,20 +23,7 @@
|
||||
|
||||
#include "main_window.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <QScreen>
|
||||
|
||||
static void OverrideWindowsFont() {
|
||||
// Qt5 chooses these fonts on Windows and they have fairly ugly alphanumeric/cyrillic characters
|
||||
// Asking to use "MS Shell Dlg 2" gives better other chars while leaving the Chinese Characters.
|
||||
const QString startup_font = QApplication::font().family();
|
||||
const QStringList ugly_fonts = {QStringLiteral("SimSun"), QStringLiteral("PMingLiU")};
|
||||
if (ugly_fonts.contains(startup_font)) {
|
||||
QApplication::setFont(QFont(QStringLiteral("MS Shell Dlg 2"), 9, QFont::Normal));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO(crueter): This is very annoying, see if there are any other solutions.
|
||||
static Qt::HighDpiScaleFactorRoundingPolicy GetHighDpiRoundingPolicy() {
|
||||
#ifdef _WIN32
|
||||
// For Windows, we want to avoid scaling artifacts on fractional scaling ratios.
|
||||
@@ -107,10 +93,6 @@ int main(int argc, char* argv[]) {
|
||||
Breakpad::InstallCrashHandler();
|
||||
#endif
|
||||
|
||||
// Init settings params
|
||||
QCoreApplication::setOrganizationName(QStringLiteral("eden"));
|
||||
QCoreApplication::setApplicationName(QStringLiteral("eden"));
|
||||
|
||||
// Increases the maximum open file limit.
|
||||
// TODO: This should be common to all frontends.
|
||||
#ifdef _WIN32
|
||||
@@ -149,31 +131,10 @@ int main(int argc, char* argv[]) {
|
||||
chdir(Common::FS::PathToUTF8String(bin_path).c_str());
|
||||
#endif
|
||||
|
||||
#ifdef __unix__
|
||||
// Set the DISPLAY variable in order to open web browsers
|
||||
// TODO (lat9nq): Find a better solution for AppImages to start external applications
|
||||
if (QString::fromLocal8Bit(qgetenv("DISPLAY")).isEmpty()) {
|
||||
qputenv("DISPLAY", ":0");
|
||||
}
|
||||
|
||||
if (GraphicsBackend::GetForceX11() && qEnvironmentVariableIsEmpty("QT_QPA_PLATFORM"))
|
||||
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"));
|
||||
#endif
|
||||
QtCommon::SetupApplication();
|
||||
|
||||
auto rounding_policy = GetHighDpiRoundingPolicy();
|
||||
QApplication::setHighDpiScaleFactorRoundingPolicy(rounding_policy);
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
// Disables the "?" button on all dialogs. Disabled by default on Qt6.
|
||||
QCoreApplication::setAttribute(Qt::AA_DisableWindowContextHelpButton);
|
||||
#endif
|
||||
|
||||
// Enables the core to make the qt created contexts current on std::threads
|
||||
QCoreApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity);
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(rounding_policy);
|
||||
|
||||
#ifdef _WIN32
|
||||
QApplication::setStyle(QStringLiteral("windowsvista"));
|
||||
@@ -181,21 +142,6 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
QApplication app(argc, argv);
|
||||
|
||||
#ifdef _WIN32
|
||||
OverrideWindowsFont();
|
||||
#endif
|
||||
|
||||
// Workaround for QTBUG-85409, for Suzhou numerals the number 1 is actually \u3021
|
||||
// so we can see if we get \u3008 instead
|
||||
// TL;DR all other number formats are consecutive in unicode code points
|
||||
// This bug is fixed in Qt6, specifically 6.0.0-alpha1
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
const QLocale locale = QLocale::system();
|
||||
if (QStringLiteral("\u3008") == locale.toString(1)) {
|
||||
QLocale::setDefault(QLocale::system().name());
|
||||
}
|
||||
#endif
|
||||
|
||||
// Qt changes the locale and causes issues in float conversion using std::to_string() when
|
||||
// generating shaders
|
||||
setlocale(LC_ALL, "C");
|
||||
|
||||
@@ -184,7 +184,6 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
|
||||
#include <csignal>
|
||||
#include <QSocketNotifier>
|
||||
#include <sys/socket.h>
|
||||
#include "qt_common/gui_settings.h"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -452,10 +451,6 @@ MainWindow::MainWindow(bool has_broken_vulkan)
|
||||
// Gen keys if necessary
|
||||
OnCheckFirmwareDecryption();
|
||||
|
||||
#ifdef __unix__
|
||||
OnCheckGraphicsBackend();
|
||||
#endif
|
||||
|
||||
// Check for orphaned profiles and reset profile data if necessary
|
||||
QtCommon::Content::FixProfiles();
|
||||
|
||||
@@ -3475,9 +3470,6 @@ void MainWindow::OnConfigure() {
|
||||
const bool old_discord_presence = UISettings::values.enable_discord_presence.GetValue();
|
||||
const auto old_language_index = Settings::values.language_index.GetValue();
|
||||
const bool old_gamemode = UISettings::values.enable_gamemode.GetValue();
|
||||
#ifdef __unix__
|
||||
const bool old_force_x11 = UISettings::values.gui_force_x11.GetValue();
|
||||
#endif
|
||||
|
||||
Settings::SetConfiguringGlobal(true);
|
||||
ConfigureDialog configure_dialog(this, hotkey_registry, input_subsystem.get(),
|
||||
@@ -3542,11 +3534,6 @@ void MainWindow::OnConfigure() {
|
||||
if (UISettings::values.enable_gamemode.GetValue() != old_gamemode) {
|
||||
SetGamemodeEnabled(UISettings::values.enable_gamemode.GetValue());
|
||||
}
|
||||
#ifdef __unix__
|
||||
if (UISettings::values.gui_force_x11.GetValue() != old_force_x11) {
|
||||
GraphicsBackend::SetForceX11(UISettings::values.gui_force_x11.GetValue());
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!multiplayer_state->IsHostingPublicRoom()) {
|
||||
multiplayer_state->UpdateCredentials();
|
||||
@@ -4430,56 +4417,6 @@ void MainWindow::OnCheckFirmwareDecryption() {
|
||||
UpdateMenuState();
|
||||
}
|
||||
|
||||
#ifdef __unix__
|
||||
void MainWindow::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 = UISettings::values.gui_hide_backend_warning.GetValue();
|
||||
if (currently_hidden)
|
||||
return;
|
||||
|
||||
QMessageBox msgbox(this);
|
||||
msgbox.setWindowTitle(tr("Wayland Detected!"));
|
||||
msgbox.setText(
|
||||
tr("Wayland is known to have significant performance issues and mysterious bugs.\n"
|
||||
"It's recommended to use X11 instead.\n\n"
|
||||
"Would you like to force it for future launches?"));
|
||||
msgbox.setIcon(QMessageBox::Warning);
|
||||
|
||||
QPushButton* okButton = msgbox.addButton(tr("Use X11"), QMessageBox::AcceptRole);
|
||||
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) {
|
||||
UISettings::values.gui_hide_backend_warning.SetValue(hide);
|
||||
}
|
||||
|
||||
if (msgbox.clickedButton() == okButton) {
|
||||
UISettings::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 MainWindow::CheckFirmwarePresence() {
|
||||
return FirmwareManager::CheckFirmwarePresence(*QtCommon::system.get());
|
||||
}
|
||||
|
||||
@@ -427,9 +427,6 @@ private slots:
|
||||
void OnCreateHomeMenuApplicationMenuShortcut();
|
||||
void OnCaptureScreenshot();
|
||||
void OnCheckFirmwareDecryption();
|
||||
#ifdef __unix__
|
||||
void OnCheckGraphicsBackend();
|
||||
#endif
|
||||
void OnLanguageChanged(const QString& locale);
|
||||
void OnMouseActivity();
|
||||
bool OnShutdownBegin();
|
||||
|
||||
Reference in New Issue
Block a user