[*] 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 **)
{
if (!GetProcAddress(LoadLibraryW(L"USER32.dll"), "GetProcessDpiAwareness"))) {
SetProcessDPIAware();
}
if (system.compare(system, "windows"_L1, Qt::CaseInsensitive) == 0)
return new QWindowsGdiIntegration(paramList);
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"));
if (!pGetDPIAwareness) {
return (QtWindows::DpiAwareness)0;
return QtWindows::DpiAwareness::System;
}
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)
return true;
static auto pSystemParametersInfoForDpi = reinterpret_cast<SystemParametersInfoForDpi_f>(
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

View File

@ -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<GetDpiForMonitor_f>(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;
}
}
}