1
0
mirror of https://gitlab.com/kelteseth/ScreenPlay.git synced 2024-09-14 22:42:34 +02:00

Fix mixed scaling issues (again)

Now we no longer trust Qt and use the data
we get from the Windows api directly.

Move monitor query function into util to be used
later in the main app, because we also must
user the correct values there.
This commit is contained in:
Elias Steurer 2021-11-13 14:12:19 +01:00
parent 80283f58f5
commit b52c89c933
4 changed files with 52 additions and 44 deletions

View File

@ -26,3 +26,8 @@ target_include_directories(
PRIVATE src/)
target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core)
if(WIN32)
# Used for query windows monitor data
target_link_libraries(${PROJECT_NAME} PUBLIC shcore.lib)
endif()

View File

@ -33,6 +33,17 @@
****************************************************************************/
#pragma once
#include <QtGlobal>
#if defined(Q_OS_WIN)
// Must be first!
#include <qt_windows.h>
#include "WinUser.h"
#include <ShellScalingApi.h>
#endif
#include "ScreenPlayUtil/contenttypes.h"
#include <QJsonArray>
#include <QJsonObject>
@ -41,6 +52,37 @@
#include <optional>
namespace ScreenPlayUtil {
#if defined(Q_OS_WIN)
struct WinMonitorStats {
std::vector<int> iMonitors;
std::vector<HMONITOR> hMonitors;
std::vector<HDC> hdcMonitors;
std::vector<RECT> rcMonitors;
std::vector<DEVICE_SCALE_FACTOR> scaleFactor;
std::vector<std::pair<UINT, UINT>> sizes;
static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor,
LPARAM pData)
{
WinMonitorStats* pThis = reinterpret_cast<WinMonitorStats*>(pData);
auto scaleFactor = DEVICE_SCALE_FACTOR::DEVICE_SCALE_FACTOR_INVALID;
GetScaleFactorForMonitor(hMon, &scaleFactor);
UINT x = 0;
UINT y = 0;
GetDpiForMonitor(hMon, MONITOR_DPI_TYPE::MDT_RAW_DPI, &x, &y);
pThis->sizes.push_back({ x, y });
pThis->scaleFactor.push_back(scaleFactor);
pThis->hMonitors.push_back(hMon);
pThis->hdcMonitors.push_back(hdc);
pThis->rcMonitors.push_back(*lprcMonitor);
pThis->iMonitors.push_back(pThis->hdcMonitors.size());
return TRUE;
}
WinMonitorStats() { EnumDisplayMonitors(0, 0, MonitorEnum, (LPARAM)this); }
};
#endif
QJsonArray fillArray(const QVector<QString>& items);
ScreenPlay::SearchType::SearchType getSearchTypeFromInstalledType(const ScreenPlay::InstalledType::InstalledType type);
std::optional<ScreenPlay::InstalledType::InstalledType> getInstalledTypeFromString(const QString& type);

View File

@ -83,6 +83,5 @@ if(WIN32)
# Disable console window on Windows
# https://stackoverflow.com/questions/8249028/how-do-i-keep-my-qt-c-program-from-opening-a-console-in-windows
set_property(TARGET ${PROJECT_NAME} PROPERTY WIN32_EXECUTABLE true)
target_link_libraries(${PROJECT_NAME} PRIVATE shcore.lib)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/index.html ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/index.html COPYONLY)
endif()

View File

@ -1,41 +1,8 @@
#include "winwindow.h"
#include "WinUser.h"
#include "qqml.h"
#include <ShellScalingApi.h>
#include <algorithm>
#include <iostream>
#include <vector>
#include <windows.h>
struct WinMonitorStats {
std::vector<int> iMonitors;
std::vector<HMONITOR> hMonitors;
std::vector<HDC> hdcMonitors;
std::vector<RECT> rcMonitors;
std::vector<DEVICE_SCALE_FACTOR> scaleFactor;
std::vector<std::pair<UINT, UINT>> sizes;
static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor,
LPARAM pData)
{
WinMonitorStats* pThis = reinterpret_cast<WinMonitorStats*>(pData);
auto scaleFactor = DEVICE_SCALE_FACTOR::DEVICE_SCALE_FACTOR_INVALID;
GetScaleFactorForMonitor(hMon, &scaleFactor);
UINT x = 0;
UINT y = 0;
GetDpiForMonitor(hMon, MONITOR_DPI_TYPE::MDT_RAW_DPI, &x, &y);
pThis->sizes.push_back({ x, y });
pThis->scaleFactor.push_back(scaleFactor);
pThis->hMonitors.push_back(hMon);
pThis->hdcMonitors.push_back(hdc);
pThis->rcMonitors.push_back(*lprcMonitor);
pThis->iMonitors.push_back(pThis->hdcMonitors.size());
return TRUE;
}
WinMonitorStats() { EnumDisplayMonitors(0, 0, MonitorEnum, (LPARAM)this); }
};
/*!
\brief Searches for the worker window for our window to parent to.
@ -225,11 +192,6 @@ WinWindow::WinWindow(
configureWindowGeometry();
if (hasWindowScaling()) {
qInfo() << "Monitor with scaling detected!";
configureWindowGeometry();
}
// We do not support autopause for multi monitor wallpaper
if (this->activeScreensList().length() == 1) {
if (checkWallpaperVisible) {
@ -294,13 +256,13 @@ void WinWindow::setupWallpaperForOneScreen(int activeScreen)
const QRect screenRect = QApplication::screens().at(activeScreen)->geometry();
const int boderWidth = 2;
const float scaling = getScaling(activeScreen);
const auto width = screenRect.width() * scaling + boderWidth;
const auto height = screenRect.height() * scaling + boderWidth;
const int borderOffset = -1;
const int x = screenRect.x() + m_zeroPoint.x() + borderOffset;
const int y = screenRect.y() + m_zeroPoint.y() + borderOffset;
ScreenPlayUtil::WinMonitorStats Monitors;
const int width = std::abs(Monitors.rcMonitors[activeScreen].right - Monitors.rcMonitors[activeScreen].left);
const int height = std::abs(Monitors.rcMonitors[activeScreen].top - Monitors.rcMonitors[activeScreen].bottom);
const int x = Monitors.rcMonitors[activeScreen].left + m_zeroPoint.x() + borderOffset;
const int y = Monitors.rcMonitors[activeScreen].top + m_zeroPoint.y() + borderOffset;
qInfo() << QString("Setup window activeScreen: %1 scaling: %2 x: %3 y: %4 width: %5 height: %6").arg(activeScreen).arg(scaling).arg(x).arg(y).arg(width).arg(height);
{