From 2ae19ad133e7d88fe3e3fa8cb433ec5c1af52b59 Mon Sep 17 00:00:00 2001 From: Collecting Date: Mon, 5 Jan 2026 06:34:20 +0000 Subject: [PATCH] fix(gamescope): Increase Font & Fix question Signed-off-by: Collecting --- src/citron/main.cpp | 105 +++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 49 deletions(-) diff --git a/src/citron/main.cpp b/src/citron/main.cpp index 3c8c77d99..6588df0a9 100644 --- a/src/citron/main.cpp +++ b/src/citron/main.cpp @@ -95,6 +95,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual #include #include #include +#include #include #include #include @@ -496,6 +497,12 @@ GMainWindow::GMainWindow(std::unique_ptr config_, bool has_broken_vulk // Create a non-modal QMessageBox instance with a nullptr parent to make it a top-level window. // This prevents it from blocking the main application window. auto* confirmation_dialog = new QMessageBox(nullptr); + const bool is_gamescope = !qgetenv("GAMESCOPE_WIDTH").isEmpty() || qgetenv("XDG_CURRENT_DESKTOP") == "gamescope"; + if (is_gamescope) { + confirmation_dialog->setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowStaysOnTopHint); + confirmation_dialog->resize(650, 300); + confirmation_dialog->setStyleSheet(QStringLiteral("font-size: 11pt;")); + } confirmation_dialog->setAttribute(Qt::WA_DeleteOnClose); // This ensures it is deleted automatically on close. confirmation_dialog->setWindowModality(Qt::NonModal); // Explicitly set modality. confirmation_dialog->setWindowTitle(tr("First-Time Setup")); @@ -855,15 +862,13 @@ void GMainWindow::SoftwareKeyboardShowNormal() { } const auto& layout = render_window->GetFramebufferLayout(); - const auto x = layout.screen.left; const auto y = layout.screen.top; const auto w = layout.screen.GetWidth(); const auto h = layout.screen.GetHeight(); - const auto scale_ratio = devicePixelRatioF(); - software_keyboard->ShowNormalKeyboard(render_window->mapToGlobal(QPoint(x, y) / scale_ratio), - QSize(w, h) / scale_ratio); + software_keyboard->ShowNormalKeyboard(render_window->mapToGlobal(QPoint(x, y)), + QSize(w, h)); } void GMainWindow::SoftwareKeyboardShowTextCheck( @@ -896,11 +901,10 @@ void GMainWindow::SoftwareKeyboardShowInline( (1.0f - appear_parameters.key_top_scale_y)))); const auto w = static_cast(layout.screen.GetWidth() * appear_parameters.key_top_scale_x); const auto h = static_cast(layout.screen.GetHeight() * appear_parameters.key_top_scale_y); - const auto scale_ratio = devicePixelRatioF(); software_keyboard->ShowInlineKeyboard(std::move(appear_parameters), - render_window->mapToGlobal(QPoint(x, y) / scale_ratio), - QSize(w, h) / scale_ratio); + render_window->mapToGlobal(QPoint(x, y)), + QSize(w, h)); } void GMainWindow::SoftwareKeyboardHideInline() { @@ -980,13 +984,11 @@ void GMainWindow::WebBrowserOpenWebPage(const std::string& main_url, } const auto& layout = render_window->GetFramebufferLayout(); - const auto scale_ratio = devicePixelRatioF(); - web_applet->resize(layout.screen.GetWidth() / scale_ratio, - layout.screen.GetHeight() / scale_ratio); - web_applet->move(layout.screen.left / scale_ratio, - (layout.screen.top / scale_ratio) + menuBar()->height()); - web_applet->setZoomFactor(static_cast(layout.screen.GetWidth() / scale_ratio) / - static_cast(Layout::ScreenUndocked::Width)); + web_applet->resize(layout.screen.GetWidth(), layout.screen.GetHeight()); + web_applet->move(layout.screen.left, + (layout.screen.top) + menuBar()->height()); + web_applet->setZoomFactor(static_cast(layout.screen.GetWidth()) / + static_cast(Layout::ScreenUndocked::Width)); web_applet->setFocus(); web_applet->show(); @@ -4493,7 +4495,12 @@ bool GMainWindow::question(QWidget* parent, const QString& title, const QString& const bool is_gamescope = !qgetenv("GAMESCOPE_WIDTH").isEmpty() || qgetenv("XDG_CURRENT_DESKTOP") == "gamescope"; if (is_gamescope) { - box_dialog->setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint); + box_dialog->setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowStaysOnTopHint); + box_dialog->setWindowModality(Qt::NonModal); + + box_dialog->resize(650, 300); + + box_dialog->setStyleSheet(QStringLiteral("font-size: 11pt;")); } box_dialog->setWindowTitle(title); @@ -6089,7 +6096,9 @@ void VolumeButton::ResetMultiplier() { #endif static void SetHighDPIAttributes() { - const bool is_gamescope = !qgetenv("GAMESCOPE_WIDTH").isEmpty() || qgetenv("XDG_CURRENT_DESKTOP") == "gamescope"; + [[maybe_unused]] const bool is_gamescope = !qgetenv("GAMESCOPE_WIDTH").isEmpty() || + qgetenv("XDG_CURRENT_DESKTOP") == "gamescope" || + !qgetenv("STEAM_DECK").isEmpty(); #ifdef _WIN32 // Windows logic: Set policy globally. @@ -6111,15 +6120,11 @@ static void SetHighDPIAttributes() { FreeLibrary(shcore); } #else - if (is_gamescope) { - // Force 1:1 pixel mapping for Steam Deck to prevent bloated windows. - QGuiApplication::setHighDpiScaleFactorRoundingPolicy( - Qt::HighDpiScaleFactorRoundingPolicy::Floor); - } else { - // Standard Linux desktops handle fractional scaling better via PassThrough - QGuiApplication::setHighDpiScaleFactorRoundingPolicy( - Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); - } +if (is_gamescope) { + // PassThrough prevents Qt6 from recursively expanding layouts to fit rounded DPIs + QGuiApplication::setHighDpiScaleFactorRoundingPolicy( + Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); +} #endif } @@ -6130,19 +6135,20 @@ int main(int argc, char* argv[]) { !qgetenv("STEAM_DECK").isEmpty(); if (is_gamescope) { - // Kill the SteamOS scaling requests before they can bloat the UI - QGuiApplication::setDesktopSettingsAware(false); - - // Force 1:1 pixel ratio + // 1. Kill the scaling system entirely qputenv("QT_ENABLE_HIGHDPI_SCALING", "0"); qputenv("QT_SCALE_FACTOR", "1"); - qputenv("QT_SCREEN_SCALE_FACTORS", "1"); qputenv("QT_AUTO_SCREEN_SCALE_FACTOR", "0"); - // Steam Deck has a high physical DPI. Hard-coding 96 DPI prevents text - // from being oversized in dialogs like "About" or "Updater". + // 2. Force font DPI to standard qputenv("QT_FONT_DPI", "96"); + // 3. Stop Qt from querying physical hardware DPI for text/widgets + qputenv("QT_USE_PHYSICAL_DPI", "0"); + + // 4. Force the legacy coordinate system for X11/XCB + qputenv("QT_SCREEN_SCALE_FACTORS", "1"); + // FORCE X11 backend: Qt 6 scaling overrides are reliably respected under XCB in Gamescope. // Wayland mode in Gamescope often ignores scaling overrides for child windows. qputenv("QT_QPA_PLATFORM", "xcb"); @@ -6216,6 +6222,24 @@ int main(int argc, char* argv[]) { QCoreApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity); QApplication app(argc, argv); + +#ifdef _WIN32 + OverrideWindowsFont(); +#endif + + if (is_gamescope) { + app.setStyleSheet(app.styleSheet().append(QStringLiteral( + "QDialog { " + " font-size: 11pt; " + " margin: 0px; " + " padding: 0px; " + "}" + "QLabel { font-size: 10pt; }" + ))); + + app.setStyle(QStyleFactory::create(QStringLiteral("Fusion"))); + } + #ifdef __linux__ if (QGuiApplication::platformName().startsWith(QStringLiteral("wayland"))) { Settings::values.is_wayland_platform.SetValue(true); @@ -6223,7 +6247,6 @@ int main(int argc, char* argv[]) { #endif #ifdef CITRON_USE_AUTO_UPDATER - // Check for and apply staged updates before starting the main application std::filesystem::path app_dir = std::filesystem::path(QCoreApplication::applicationDirPath().toStdString()); #ifdef _WIN32 @@ -6235,7 +6258,6 @@ int main(int argc, char* argv[]) { } catch (...) {} } #else - // On Linux, apply staged updates at startup if (Updater::UpdaterService::HasStagedUpdate(app_dir)) { if (Updater::UpdaterService::ApplyStagedUpdate(app_dir)) { QMessageBox::information(nullptr, QObject::tr("Update Applied"), @@ -6245,19 +6267,6 @@ int main(int argc, char* argv[]) { #endif #endif -#ifdef _WIN32 - OverrideWindowsFont(); -#endif - - - // Workaround for QTBUG-85409 -#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 - setlocale(LC_ALL, "C"); GMainWindow main_window{std::move(config), has_broken_vulkan}; @@ -6268,11 +6277,9 @@ int main(int argc, char* argv[]) { if (is_gamescope) { QTimer::singleShot(200, &main_window, [&main_window]() { main_window.showMaximized(); - if (main_window.layout()) { main_window.layout()->activate(); } - main_window.update(); main_window.raise(); main_window.activateWindow();