Просмотр исходного кода

Merge pull request #4949 from Morph1984/hidpi-temp-fix

main: Enable High DPI fixes for Qt >= 5.14
liamwhite 3 лет назад
Родитель
Сommit
1f3e8d633a
3 измененных файлов с 65 добавлено и 8 удалено
  1. 1 1
      src/yuzu/applets/qt_software_keyboard.cpp
  2. 63 6
      src/yuzu/main.cpp
  3. 1 1
      src/yuzu/util/overlay_dialog.cpp

+ 1 - 1
src/yuzu/applets/qt_software_keyboard.cpp

@@ -575,7 +575,7 @@ void QtSoftwareKeyboardDialog::MoveAndResizeWindow(QPoint pos, QSize size) {
     QDialog::resize(size);
     QDialog::resize(size);
 
 
     // High DPI
     // High DPI
-    const float dpi_scale = qApp->screenAt(pos)->logicalDotsPerInch() / 96.0f;
+    const float dpi_scale = screen()->logicalDotsPerInch() / 96.0f;
 
 
     RescaleKeyboardElements(size.width(), size.height(), dpi_scale);
     RescaleKeyboardElements(size.width(), size.height(), dpi_scale);
 }
 }

+ 63 - 6
src/yuzu/main.cpp

@@ -680,8 +680,10 @@ void GMainWindow::SoftwareKeyboardShowNormal() {
     const auto y = layout.screen.top;
     const auto y = layout.screen.top;
     const auto w = layout.screen.GetWidth();
     const auto w = layout.screen.GetWidth();
     const auto h = layout.screen.GetHeight();
     const auto h = layout.screen.GetHeight();
+    const auto scale_ratio = devicePixelRatioF();
 
 
-    software_keyboard->ShowNormalKeyboard(render_window->mapToGlobal(QPoint(x, y)), QSize(w, h));
+    software_keyboard->ShowNormalKeyboard(render_window->mapToGlobal(QPoint(x, y) / scale_ratio),
+                                          QSize(w, h) / scale_ratio);
 }
 }
 
 
 void GMainWindow::SoftwareKeyboardShowTextCheck(
 void GMainWindow::SoftwareKeyboardShowTextCheck(
@@ -714,9 +716,11 @@ void GMainWindow::SoftwareKeyboardShowInline(
                                                (1.0f - appear_parameters.key_top_scale_y))));
                                                (1.0f - appear_parameters.key_top_scale_y))));
     const auto w = static_cast<int>(layout.screen.GetWidth() * appear_parameters.key_top_scale_x);
     const auto w = static_cast<int>(layout.screen.GetWidth() * appear_parameters.key_top_scale_x);
     const auto h = static_cast<int>(layout.screen.GetHeight() * appear_parameters.key_top_scale_y);
     const auto h = static_cast<int>(layout.screen.GetHeight() * appear_parameters.key_top_scale_y);
+    const auto scale_ratio = devicePixelRatioF();
 
 
     software_keyboard->ShowInlineKeyboard(std::move(appear_parameters),
     software_keyboard->ShowInlineKeyboard(std::move(appear_parameters),
-                                          render_window->mapToGlobal(QPoint(x, y)), QSize(w, h));
+                                          render_window->mapToGlobal(QPoint(x, y) / scale_ratio),
+                                          QSize(w, h) / scale_ratio);
 }
 }
 
 
 void GMainWindow::SoftwareKeyboardHideInline() {
 void GMainWindow::SoftwareKeyboardHideInline() {
@@ -796,10 +800,11 @@ void GMainWindow::WebBrowserOpenWebPage(const std::string& main_url,
         }
         }
 
 
         const auto& layout = render_window->GetFramebufferLayout();
         const auto& layout = render_window->GetFramebufferLayout();
-        web_browser_view.resize(layout.screen.GetWidth(), layout.screen.GetHeight());
-        web_browser_view.move(layout.screen.left, layout.screen.top + menuBar()->height());
-        web_browser_view.setZoomFactor(static_cast<qreal>(layout.screen.GetWidth()) /
-                                       static_cast<qreal>(Layout::ScreenUndocked::Width));
+        const auto scale_ratio = devicePixelRatioF();
+        web_browser_view.resize(layout.screen.GetWidth() / scale_ratio,
+                                layout.screen.GetHeight() / scale_ratio);
+        web_browser_view.move(layout.screen.left / scale_ratio,
+                              (layout.screen.top / scale_ratio) + menuBar()->height());
 
 
         web_browser_view.setFocus();
         web_browser_view.setFocus();
         web_browser_view.show();
         web_browser_view.show();
@@ -4448,6 +4453,55 @@ void GMainWindow::changeEvent(QEvent* event) {
 #undef main
 #undef main
 #endif
 #endif
 
 
+static void SetHighDPIAttributes() {
+#ifdef _WIN32
+    // For Windows, we want to avoid scaling artifacts on fractional scaling ratios.
+    // This is done by setting the optimal scaling policy for the primary screen.
+
+    // Create a temporary QApplication.
+    int temp_argc = 0;
+    char** temp_argv = nullptr;
+    QApplication temp{temp_argc, temp_argv};
+
+    // Get the current screen geometry.
+    const QScreen* primary_screen = QGuiApplication::primaryScreen();
+    if (primary_screen == nullptr) {
+        return;
+    }
+
+    const QRect screen_rect = primary_screen->geometry();
+    const int real_width = screen_rect.width();
+    const int real_height = screen_rect.height();
+    const float real_ratio = primary_screen->logicalDotsPerInch() / 96.0f;
+
+    // Recommended minimum width and height for proper window fit.
+    // Any screen with a lower resolution than this will still have a scale of 1.
+    constexpr float minimum_width = 1350.0f;
+    constexpr float minimum_height = 900.0f;
+
+    const float width_ratio = std::max(1.0f, real_width / minimum_width);
+    const float height_ratio = std::max(1.0f, real_height / minimum_height);
+
+    // Get the lower of the 2 ratios and truncate, this is the maximum integer scale.
+    const float max_ratio = std::trunc(std::min(width_ratio, height_ratio));
+
+    if (max_ratio > real_ratio) {
+        QApplication::setHighDpiScaleFactorRoundingPolicy(
+            Qt::HighDpiScaleFactorRoundingPolicy::Round);
+    } else {
+        QApplication::setHighDpiScaleFactorRoundingPolicy(
+            Qt::HighDpiScaleFactorRoundingPolicy::Floor);
+    }
+#else
+    // Other OSes should be better than Windows at fractional scaling.
+    QApplication::setHighDpiScaleFactorRoundingPolicy(
+        Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
+#endif
+
+    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+    QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
+}
+
 int main(int argc, char* argv[]) {
 int main(int argc, char* argv[]) {
     std::unique_ptr<Config> config = std::make_unique<Config>();
     std::unique_ptr<Config> config = std::make_unique<Config>();
     bool has_broken_vulkan = false;
     bool has_broken_vulkan = false;
@@ -4503,6 +4557,8 @@ int main(int argc, char* argv[]) {
     }
     }
 #endif
 #endif
 
 
+    SetHighDPIAttributes();
+
 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
     // Disables the "?" button on all dialogs. Disabled by default on Qt6.
     // Disables the "?" button on all dialogs. Disabled by default on Qt6.
     QCoreApplication::setAttribute(Qt::AA_DisableWindowContextHelpButton);
     QCoreApplication::setAttribute(Qt::AA_DisableWindowContextHelpButton);
@@ -4510,6 +4566,7 @@ int main(int argc, char* argv[]) {
 
 
     // Enables the core to make the qt created contexts current on std::threads
     // Enables the core to make the qt created contexts current on std::threads
     QCoreApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity);
     QCoreApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity);
+
     QApplication app(argc, argv);
     QApplication app(argc, argv);
 
 
 #ifdef _WIN32
 #ifdef _WIN32

+ 1 - 1
src/yuzu/util/overlay_dialog.cpp

@@ -163,7 +163,7 @@ void OverlayDialog::MoveAndResizeWindow() {
     const auto height = static_cast<float>(parentWidget()->height());
     const auto height = static_cast<float>(parentWidget()->height());
 
 
     // High DPI
     // High DPI
-    const float dpi_scale = parentWidget()->windowHandle()->screen()->logicalDotsPerInch() / 96.0f;
+    const float dpi_scale = screen()->logicalDotsPerInch() / 96.0f;
 
 
     const auto title_text_font_size = BASE_TITLE_FONT_SIZE * (height / BASE_HEIGHT) / dpi_scale;
     const auto title_text_font_size = BASE_TITLE_FONT_SIZE * (height / BASE_HEIGHT) / dpi_scale;
     const auto body_text_font_size =
     const auto body_text_font_size =