From 04403770e645173cb4012af1de3c1ac9fc668ef4 Mon Sep 17 00:00:00 2001 From: Jamie Reece Wilson Date: Sat, 23 Mar 2024 18:46:14 +0000 Subject: [PATCH] [*] Harden against bad Windows emulators Change-Id: Ic09b4cb807e7eba1eeaf12fe7642e9a3213b8f3b --- src/plugins/platforms/windows/main.cpp | 4 ++ .../platforms/windows/qwindowscontext.cpp | 8 ++- .../platforms/windows/qwindowswindow.cpp | 50 +++++++++++++------ 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/src/plugins/platforms/windows/main.cpp b/src/plugins/platforms/windows/main.cpp index 51c1fb4a45..cee7c1a016 100644 --- a/src/plugins/platforms/windows/main.cpp +++ b/src/plugins/platforms/windows/main.cpp @@ -72,6 +72,10 @@ public: QPlatformIntegration *QWindowsIntegrationPlugin::create(const QString& system, const QStringList& paramList, int &, char **) { + if (!GetProcAddress(LoadLibraryW(L"USER32.dll"), "GetProcessDpiAwareness"))) { + SetProcessDPIAware(); + } + if (system.compare(system, "windows"_L1, Qt::CaseInsensitive) == 0) return new QWindowsGdiIntegration(paramList); return nullptr; diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 319d828d16..394134c4e9 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -498,7 +498,7 @@ QtWindows::DpiAwareness QWindowsContext::processDpiAwareness() static auto pGetDPIAwareness = reinterpret_cast(GetProcAddress(LoadLibraryW(L"USER32.dll"), "GetProcessDpiAwareness")); if (!pGetDPIAwareness) { - return (QtWindows::DpiAwareness)0; + return QtWindows::DpiAwareness::System; } static auto pGetThreadDpiAwarenessContext = reinterpret_cast(GetProcAddress(LoadLibraryW(L"USER32.dll"), "GetThreadDpiAwarenessContext")); @@ -1014,6 +1014,12 @@ bool QWindowsContext::shouldHaveNonClientDpiScaling(const QWindow *window) if (QWindowsContextPrivate::m_v2DpiAware) return true; + static auto pSystemParametersInfoForDpi = reinterpret_cast( + GetProcAddress(LoadLibraryW(L"USER32.dll"), "SystemParametersInfoForDpi")); + if (!pSystemParametersInfoForDpi) { + return true; + } + return window->isTopLevel() && !window->property(QWindowsWindow::embeddedNativeParentHandleProperty).isValid() #if QT_CONFIG(opengl) // /QTBUG-62901, EnableNonClientDpiScaling has problems with GL diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 0b1d3e3a18..3f12e51647 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -69,26 +69,48 @@ int GetSystemMetricsForDpi2(int a, UINT dpi) return pGetSystemMetricsForDpi ? pGetSystemMetricsForDpi(a, dpi) : GetSystemMetrics(a); } -HRESULT GetDpiForMonitor2(HMONITOR hmonitor, MONITOR_DPI_TYPE dpiType, UINT *pDpiX, UINT *pDpiY) +HRESULT GetDpiForMonitor2(HMONITOR hMonitor, MONITOR_DPI_TYPE dpiType, UINT *pDpiX, UINT *pDpiY) { + MONITORINFOEX mi { }; + mi.cbSize = sizeof(mi); + auto pGetDpiForMonitor = reinterpret_cast(GetProcAddress( LoadLibraryW(L"USER32.dll"), "GetDpiForMonitor")); + if (pGetDpiForMonitor) { - return pGetDpiForMonitor(hmonitor, dpiType, pDpiX, pDpiY); + return pGetDpiForMonitor(hMonitor, dpiType, pDpiX, pDpiY); } - auto hwnd = GetActiveWindow(); - if (HDC hDC = GetDC(hwnd)) { - auto dpiX = GetDeviceCaps(hDC, LOGPIXELSX); - auto dpiY = GetDeviceCaps(hDC, LOGPIXELSY); - ReleaseDC(hwnd, hDC); - *pDpiX = dpiX; - *pDpiY = dpiY; - return S_OK; - } else { - *pDpiX = 96; - *pDpiY = 96; - return S_OK; + if (GetMonitorInfo(hMonitor, &mi)) + { + // Note: Windows 7 is effectively stuck in System-level of awareness + // If these values return anything other than identical values, we're under a really shite Windows emulator providing broken DPI scaling under legacy systems. + // We should only be dependent on system upscaling/downscaling based on the primary monitors DPI at time of session startup + if (auto hDC = CreateDC(NULL, mi.szDevice, NULL, NULL)) + { + auto dpiX = GetDeviceCaps(hDC, LOGPIXELSX); + auto dpiY = GetDeviceCaps(hDC, LOGPIXELSY); + *pDpiX = dpiX; + *pDpiY = dpiY; + ReleaseDC(NULL, hDC); + return S_OK; + } + } + + { + auto hwnd = GetActiveWindow(); + if (HDC hDC = GetDC(hwnd)) { + auto dpiX = GetDeviceCaps(hDC, LOGPIXELSX); + auto dpiY = GetDeviceCaps(hDC, LOGPIXELSY); + ReleaseDC(hwnd, hDC); + *pDpiX = dpiX; + *pDpiY = dpiY; + return S_OK; + } else { + *pDpiX = 96; + *pDpiY = 96; + return S_OK; + } } }