From d7c2509d36669614de3cf45d336df62b51eca2dc Mon Sep 17 00:00:00 2001 From: Collecting Date: Sun, 4 Jan 2026 18:41:18 +0000 Subject: [PATCH] fix(overhaul): UI and resolution bugs for Steam Deck (Gamescope) Signed-off-by: Collecting --- src/citron/util/performance_overlay.cpp | 68 ++++++++++++++----------- 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/src/citron/util/performance_overlay.cpp b/src/citron/util/performance_overlay.cpp index 5b786e584..bb30c3ab8 100644 --- a/src/citron/util/performance_overlay.cpp +++ b/src/citron/util/performance_overlay.cpp @@ -41,18 +41,18 @@ namespace { bool IsGamescope() { - static bool gamescope = qgetenv("XDG_CURRENT_DESKTOP") == "gamescope" || - !qgetenv("GAMESCOPE_WIDTH").isEmpty(); + static bool gamescope = qgetenv("XDG_CURRENT_DESKTOP") == "gamescope"; return gamescope; } } -PerformanceOverlay::PerformanceOverlay(QWidget* parent) : QWidget(parent) { - // Cast the parent (which is now 'this' from main.cpp) to get our data source - main_window = qobject_cast(parent); +PerformanceOverlay::PerformanceOverlay(QWidget* parent) : QWidget(IsGamescope() ? nullptr : parent) { + if (parent) { + main_window = qobject_cast(parent); + } if (IsGamescope()) { - setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); + setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::WindowDoesNotAcceptFocus); setAttribute(Qt::WA_ShowWithoutActivating); } else { setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); @@ -60,13 +60,14 @@ PerformanceOverlay::PerformanceOverlay(QWidget* parent) : QWidget(parent) { setAttribute(Qt::WA_TranslucentBackground, true); setAttribute(Qt::WA_NoSystemBackground); + setAttribute(Qt::WA_WState_ExplicitShowHide); if (IsGamescope()) { title_font = QFont(QString::fromUtf8("Segoe UI"), 8, QFont::Bold); value_font = QFont(QString::fromUtf8("Segoe UI"), 9, QFont::Bold); small_font = QFont(QString::fromUtf8("Segoe UI"), 7, QFont::Normal); setMinimumSize(150, 110); - resize(170, 130); + resize(170, 140); // Taller for 2-line stats } else { title_font = QFont(QString::fromUtf8("Segoe UI"), 9, QFont::Medium); value_font = QFont(QString::fromUtf8("Segoe UI"), 11, QFont::Bold); @@ -99,14 +100,15 @@ PerformanceOverlay::PerformanceOverlay(QWidget* parent) : QWidget(parent) { PerformanceOverlay::~PerformanceOverlay() = default; void PerformanceOverlay::SetVisible(bool visible) { - if (is_visible == visible) return; - is_visible = visible; + is_enabled = visible; + is_visible = visible; // Update the state so the check works next time + if (visible) { show(); update_timer.start(500); } else { + update_timer.stop(); // Stop the timer first hide(); - update_timer.stop(); } } @@ -172,26 +174,37 @@ void PerformanceOverlay::mouseReleaseEvent(QMouseEvent* event) { } void PerformanceOverlay::UpdatePerformanceStats() { - if (!main_window) return; + if (!main_window || !is_enabled) return; - // Gamescope Catch-all: Hide if ANY other Citron window (Updater, Lobby, etc.) is visible. if (IsGamescope()) { - bool sub_window_visible = false; - for (QWidget* w : QApplication::topLevelWidgets()) { - if (w->isWindow() && w->isVisible() && w != main_window && w != this && - !w->inherits("GRenderWindow") && !w->inherits("VramOverlay") && !w->inherits("ControllerOverlay")) { - sub_window_visible = true; + bool ui_active = (QApplication::activePopupWidget() != nullptr); + + if (!ui_active) { + for (QWidget* w : QApplication::topLevelWidgets()) { + if (w->isVisible() && w != main_window && w != this && + !w->inherits("GRenderWindow") && + !w->inherits("VramOverlay") && + !w->inherits("ControllerOverlay") && + !w->inherits("PerformanceOverlay")) { + ui_active = true; break; + } } } - if (sub_window_visible) { + + if (ui_active) { if (!this->isHidden()) this->hide(); return; } - } - if (is_visible && this->isHidden()) { - this->show(); + if (this->isHidden()) { + this->show(); + } + } else { + // Desktop: Only force a show if the user actually has it enabled in the menu + if (is_enabled && this->isHidden()) { + this->show(); + } } shaders_building = main_window->GetShadersBuilding(); @@ -439,15 +452,12 @@ void PerformanceOverlay::DrawFrameGraph(QPainter& painter) { painter.setFont(small_font); painter.setPen(text_color); - const QString min_text = QString::fromUtf8("Min: %1ms").arg(FormatFrameTime(min_frame_time)); - const QString avg_text = QString::fromUtf8("Avg: %1ms").arg(FormatFrameTime(avg_frame_time)); - const QString max_text = QString::fromUtf8("Max: %1ms").arg(FormatFrameTime(max_frame_time)); + // FIXED: Split Min/Avg/Max into multiple lines to prevent squishing at 800p + const QString min_avg_text = QString::fromUtf8("Min:%1ms Avg:%2ms").arg(FormatFrameTime(min_frame_time)).arg(FormatFrameTime(avg_frame_time)); + const QString max_text = QString::fromUtf8("Max:%1ms").arg(FormatFrameTime(max_frame_time)); - painter.drawText(graph_rect.left(), graph_y - 5, min_text); - painter.drawText(graph_rect.center().x() - (painter.fontMetrics().horizontalAdvance(avg_text) / 2), - graph_y - 5, avg_text); - painter.drawText(graph_rect.right() - painter.fontMetrics().horizontalAdvance(max_text), - graph_y - 5, max_text); + painter.drawText(graph_rect.left(), graph_y - 18, min_avg_text); + painter.drawText(graph_rect.left(), graph_y - 4, max_text); } void PerformanceOverlay::AddFrameTime(double frame_time_ms) {