From d3110b9521d3b67daf41b45b6a520907ff11773a Mon Sep 17 00:00:00 2001 From: TellowKrinkle Date: Sat, 10 Jun 2023 02:11:14 -0500 Subject: [PATCH 1/2] VideoCommon: Update imgui scale when dpi changes --- Source/Core/VideoCommon/OnScreenUI.cpp | 5 ++++- Source/Core/VideoCommon/Present.cpp | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Source/Core/VideoCommon/OnScreenUI.cpp b/Source/Core/VideoCommon/OnScreenUI.cpp index e2fa2593a7..d5949e356f 100644 --- a/Source/Core/VideoCommon/OnScreenUI.cpp +++ b/Source/Core/VideoCommon/OnScreenUI.cpp @@ -55,7 +55,6 @@ bool OnScreenUI::Initialize(u32 width, u32 height, float scale) // Don't create an ini file. TODO: Do we want this in the future? ImGui::GetIO().IniFilename = nullptr; SetScale(scale); - ImGui::GetStyle().WindowRounding = 7.0f; PortableVertexDeclaration vdecl = {}; vdecl.position = {ComponentFormat::Float, 2, offsetof(ImDrawVert, pos), true, false}; @@ -343,6 +342,10 @@ void OnScreenUI::SetScale(float backbuffer_scale) ImGui::GetIO().DisplayFramebufferScale.x = backbuffer_scale; ImGui::GetIO().DisplayFramebufferScale.y = backbuffer_scale; ImGui::GetIO().FontGlobalScale = backbuffer_scale; + // ScaleAllSizes scales in-place, so calling it twice will double-apply the scale + // Reset the style first so that the scale is applied to the base style, not an already-scaled one + ImGui::GetStyle() = {}; + ImGui::GetStyle().WindowRounding = 7.0f; ImGui::GetStyle().ScaleAllSizes(backbuffer_scale); m_backbuffer_scale = backbuffer_scale; diff --git a/Source/Core/VideoCommon/Present.cpp b/Source/Core/VideoCommon/Present.cpp index 3ac4d516df..7de3fd9d84 100644 --- a/Source/Core/VideoCommon/Present.cpp +++ b/Source/Core/VideoCommon/Present.cpp @@ -176,6 +176,8 @@ void Presenter::SetBackbuffer(SurfaceInfo info) m_backbuffer_height = info.height; m_backbuffer_scale = info.scale; m_backbuffer_format = info.format; + if (m_onscreen_ui) + m_onscreen_ui->SetScale(info.scale); UpdateDrawRectangle(); } From fc53dca7bdc30473b6e26228b97c5e0de378b3d3 Mon Sep 17 00:00:00 2001 From: TellowKrinkle Date: Sat, 10 Jun 2023 02:12:17 -0500 Subject: [PATCH 2/2] Qt: Send SizeChanged on DPI changes --- Source/Core/DolphinQt/RenderWidget.cpp | 17 +++++++++++++++-- Source/Core/DolphinQt/RenderWidget.h | 3 +++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Source/Core/DolphinQt/RenderWidget.cpp b/Source/Core/DolphinQt/RenderWidget.cpp index 8393434530..129fad9858 100644 --- a/Source/Core/DolphinQt/RenderWidget.cpp +++ b/Source/Core/DolphinQt/RenderWidget.cpp @@ -437,6 +437,10 @@ bool RenderWidget::event(QEvent* event) case QEvent::Move: SetCursorLocked(m_cursor_locked); break; + + // According to https://bugreports.qt.io/browse/QTBUG-95925 the recommended practice for + // handling DPI change is responding to paint events + case QEvent::Paint: case QEvent::Resize: { SetCursorLocked(m_cursor_locked); @@ -446,9 +450,18 @@ bool RenderWidget::event(QEvent* event) QScreen* screen = window()->windowHandle()->screen(); - const auto dpr = screen->devicePixelRatio(); + const float dpr = screen->devicePixelRatio(); + const int width = new_size.width() * dpr; + const int height = new_size.height() * dpr; - emit SizeChanged(new_size.width() * dpr, new_size.height() * dpr); + if (m_last_window_width != width || m_last_window_height != height || + m_last_window_scale != dpr) + { + m_last_window_width = width; + m_last_window_height = height; + m_last_window_scale = dpr; + emit SizeChanged(width, height); + } break; } // Happens when we add/remove the widget from the main window instead of the dedicated one diff --git a/Source/Core/DolphinQt/RenderWidget.h b/Source/Core/DolphinQt/RenderWidget.h index 87235a3986..c214ead7d0 100644 --- a/Source/Core/DolphinQt/RenderWidget.h +++ b/Source/Core/DolphinQt/RenderWidget.h @@ -47,6 +47,9 @@ private: static constexpr int MOUSE_HIDE_DELAY = 3000; QTimer* m_mouse_timer; QPoint m_last_mouse{}; + int m_last_window_width = 0; + int m_last_window_height = 0; + float m_last_window_scale = 0; bool m_cursor_locked = false; bool m_lock_cursor_on_next_activation = false; bool m_dont_lock_cursor_on_show = false;