[*] Harden against bad Windows emulators

Change-Id: Ic09b4cb807e7eba1eeaf12fe7642e9a3213b8f3b
This commit is contained in:
Reece Wilson 2024-03-23 18:46:14 +00:00
parent d4827ef266
commit 04403770e6
3 changed files with 47 additions and 15 deletions

View File

@ -72,6 +72,10 @@ public:
QPlatformIntegration *QWindowsIntegrationPlugin::create(const QString& system, const QStringList& paramList, int &, char **) 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) if (system.compare(system, "windows"_L1, Qt::CaseInsensitive) == 0)
return new QWindowsGdiIntegration(paramList); return new QWindowsGdiIntegration(paramList);
return nullptr; return nullptr;

View File

@ -498,7 +498,7 @@ QtWindows::DpiAwareness QWindowsContext::processDpiAwareness()
static auto pGetDPIAwareness = reinterpret_cast<GetProcessDpiAwareness_f>(GetProcAddress(LoadLibraryW(L"USER32.dll"), "GetProcessDpiAwareness")); static auto pGetDPIAwareness = reinterpret_cast<GetProcessDpiAwareness_f>(GetProcAddress(LoadLibraryW(L"USER32.dll"), "GetProcessDpiAwareness"));
if (!pGetDPIAwareness) { if (!pGetDPIAwareness) {
return (QtWindows::DpiAwareness)0; return QtWindows::DpiAwareness::System;
} }
static auto pGetThreadDpiAwarenessContext = reinterpret_cast<GetThreadDpiAwarenessContext_f>(GetProcAddress(LoadLibraryW(L"USER32.dll"), "GetThreadDpiAwarenessContext")); static auto pGetThreadDpiAwarenessContext = reinterpret_cast<GetThreadDpiAwarenessContext_f>(GetProcAddress(LoadLibraryW(L"USER32.dll"), "GetThreadDpiAwarenessContext"));
@ -1014,6 +1014,12 @@ bool QWindowsContext::shouldHaveNonClientDpiScaling(const QWindow *window)
if (QWindowsContextPrivate::m_v2DpiAware) if (QWindowsContextPrivate::m_v2DpiAware)
return true; return true;
static auto pSystemParametersInfoForDpi = reinterpret_cast<SystemParametersInfoForDpi_f>(
GetProcAddress(LoadLibraryW(L"USER32.dll"), "SystemParametersInfoForDpi"));
if (!pSystemParametersInfoForDpi) {
return true;
}
return window->isTopLevel() return window->isTopLevel()
&& !window->property(QWindowsWindow::embeddedNativeParentHandleProperty).isValid() && !window->property(QWindowsWindow::embeddedNativeParentHandleProperty).isValid()
#if QT_CONFIG(opengl) // /QTBUG-62901, EnableNonClientDpiScaling has problems with GL #if QT_CONFIG(opengl) // /QTBUG-62901, EnableNonClientDpiScaling has problems with GL

View File

@ -69,26 +69,48 @@ int GetSystemMetricsForDpi2(int a, UINT dpi)
return pGetSystemMetricsForDpi ? pGetSystemMetricsForDpi(a, dpi) : GetSystemMetrics(a); 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<GetDpiForMonitor_f>(GetProcAddress( auto pGetDpiForMonitor = reinterpret_cast<GetDpiForMonitor_f>(GetProcAddress(
LoadLibraryW(L"USER32.dll"), "GetDpiForMonitor")); LoadLibraryW(L"USER32.dll"), "GetDpiForMonitor"));
if (pGetDpiForMonitor) { if (pGetDpiForMonitor) {
return pGetDpiForMonitor(hmonitor, dpiType, pDpiX, pDpiY); return pGetDpiForMonitor(hMonitor, dpiType, pDpiX, pDpiY);
} }
auto hwnd = GetActiveWindow(); if (GetMonitorInfo(hMonitor, &mi))
if (HDC hDC = GetDC(hwnd)) { {
auto dpiX = GetDeviceCaps(hDC, LOGPIXELSX); // Note: Windows 7 is effectively stuck in System-level of awareness
auto dpiY = GetDeviceCaps(hDC, LOGPIXELSY); // If these values return anything other than identical values, we're under a really shite Windows emulator providing broken DPI scaling under legacy systems.
ReleaseDC(hwnd, hDC); // We should only be dependent on system upscaling/downscaling based on the primary monitors DPI at time of session startup
*pDpiX = dpiX; if (auto hDC = CreateDC(NULL, mi.szDevice, NULL, NULL))
*pDpiY = dpiY; {
return S_OK; auto dpiX = GetDeviceCaps(hDC, LOGPIXELSX);
} else { auto dpiY = GetDeviceCaps(hDC, LOGPIXELSY);
*pDpiX = 96; *pDpiX = dpiX;
*pDpiY = 96; *pDpiY = dpiY;
return S_OK; 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;
}
} }
} }