summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorMorten Johan Sørvig <morten.sorvig@qt.io>2020-12-01 15:24:23 +0100
committerMorten Johan Sørvig <morten.sorvig@qt.io>2021-02-08 08:13:56 +0100
commitc35643dba3efabaf3fa036895f152bf5b8725f5e (patch)
treeeb3ab567e951cc9f9f0089562694d7db71cd5044 /src/plugins
parentd9a7d1a89caa754b4b6b61c1d0712f978d7f2114 (diff)
Windows: Add support for PerMonitorV2 DPI awareness
Add support for opting in to PerMonitorV2 DPI awareness on the command line: -platform windows:dpiawareness=3 This mode is supported on Windows 10 and up. Setting it requires using the new SetProcessDpiAwarenessContext API, which can be resolved from user32.dll. Task-number: QTBUG-68712 Change-Id: I37821e27a67e08c2e9fef25e494cfd7abed13314 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/windows/qtwindowsglobal.h11
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp21
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h5
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp19
4 files changed, 50 insertions, 6 deletions
diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h
index 985f13bdc5..573a8d07c8 100644
--- a/src/plugins/platforms/windows/qtwindowsglobal.h
+++ b/src/plugins/platforms/windows/qtwindowsglobal.h
@@ -76,6 +76,14 @@
# define WM_POINTERHWHEEL 0x024F
#endif // WM_POINTERUPDATE
+#if !defined(_DPI_AWARENESS_CONTEXTS_)
+# define DPI_AWARENESS_CONTEXT_UNAWARE ((HANDLE)-1)
+# define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE ((HANDLE)-2)
+# define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ((HANDLE)-3)
+# define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((HANDLE)-4)
+# define DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED ((HANDLE)-5)
+#endif
+
QT_BEGIN_NAMESPACE
namespace QtWindows
@@ -167,7 +175,8 @@ enum ProcessDpiAwareness
{
ProcessDpiUnaware,
ProcessSystemDpiAware,
- ProcessPerMonitorDpiAware
+ ProcessPerMonitorDpiAware,
+ ProcessPerMonitorV2DpiAware // Qt extension (not in Process_DPI_Awareness)
};
} // namespace QtWindows
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 67d38a95ce..475dca4020 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -192,6 +192,7 @@ void QWindowsUser32DLL::init()
{
QSystemLibrary library(QStringLiteral("user32"));
setProcessDPIAware = (SetProcessDPIAware)library.resolve("SetProcessDPIAware");
+ setProcessDpiAwarenessContext = (SetProcessDpiAwarenessContext)library.resolve("SetProcessDpiAwarenessContext");
addClipboardFormatListener = (AddClipboardFormatListener)library.resolve("AddClipboardFormatListener");
removeClipboardFormatListener = (RemoveClipboardFormatListener)library.resolve("RemoveClipboardFormatListener");
@@ -278,9 +279,11 @@ struct QWindowsContextPrivate {
HPOWERNOTIFY m_powerNotification = nullptr;
HWND m_powerDummyWindow = nullptr;
static bool m_darkMode;
+ static bool m_v2DpiAware;
};
bool QWindowsContextPrivate::m_darkMode = false;
+bool QWindowsContextPrivate::m_v2DpiAware = false;
QWindowsContextPrivate::QWindowsContextPrivate()
: m_oleInitializeResult(OleInitialize(nullptr))
@@ -505,6 +508,23 @@ void QWindowsContext::setProcessDpiAwareness(QtWindows::ProcessDpiAwareness dpiA
}
}
+void QWindowsContext::setProcessDpiV2Awareness()
+{
+ qCDebug(lcQpaWindows) << __FUNCTION__;
+ const BOOL ok = QWindowsContext::user32dll.setProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
+ if (ok) {
+ QWindowsContextPrivate::m_v2DpiAware = true;
+ } else {
+ const HRESULT errorCode = GetLastError();
+ // E_ACCESSDENIED means set externally (MSVC manifest or external app loading Qt plugin).
+ // Silence warning in that case unless debug is enabled.
+ if (errorCode != E_ACCESSDENIED || lcQpaWindows().isDebugEnabled()) {
+ qWarning().noquote().nospace() << "setProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) failed: "
+ << QWindowsContext::comErrorString(errorCode);
+ }
+ }
+}
+
bool QWindowsContext::isDarkMode()
{
return QWindowsContextPrivate::m_darkMode;
@@ -1098,6 +1118,7 @@ static inline bool resizeOnDpiChanged(const QWindow *w)
bool QWindowsContext::shouldHaveNonClientDpiScaling(const QWindow *window)
{
return QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10
+ && !QWindowsContextPrivate::m_v2DpiAware // V2 implies NonClientDpiScaling; no need to enable
&& 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/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index aacdafebb6..99b4bb6c77 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -98,6 +98,7 @@ struct QWindowsUser32DLL
typedef BOOL (WINAPI *GetPointerPenInfoHistory)(UINT32, UINT32 *, PVOID);
typedef BOOL (WINAPI *SkipPointerFrameMessages)(UINT32);
typedef BOOL (WINAPI *SetProcessDPIAware)();
+ typedef BOOL (WINAPI *SetProcessDpiAwarenessContext)(HANDLE);
typedef BOOL (WINAPI *AddClipboardFormatListener)(HWND);
typedef BOOL (WINAPI *RemoveClipboardFormatListener)(HWND);
typedef BOOL (WINAPI *GetDisplayAutoRotationPreferences)(DWORD *);
@@ -123,6 +124,9 @@ struct QWindowsUser32DLL
// Windows Vista onwards
SetProcessDPIAware setProcessDPIAware = nullptr;
+ // Windows 10 version 1703 onwards
+ SetProcessDpiAwarenessContext setProcessDpiAwarenessContext = nullptr;
+
// Clipboard listeners are present on Windows Vista onwards
// but missing in MinGW 4.9 stub libs. Can be removed in MinGW 5.
AddClipboardFormatListener addClipboardFormatListener = nullptr;
@@ -227,6 +231,7 @@ public:
static void setTabletAbsoluteRange(int a);
void setProcessDpiAwareness(QtWindows::ProcessDpiAwareness dpiAwareness);
static int processDpiAwareness();
+ void setProcessDpiV2Awareness();
static bool isDarkMode();
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 74e6985980..ed401bac30 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -219,7 +219,7 @@ static inline unsigned parseOptions(const QStringList &paramList,
options |= QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch;
} else if (parseIntOption(param, QLatin1String("verbose"), 0, INT_MAX, &QWindowsContext::verbose)
|| parseIntOption(param, QLatin1String("tabletabsoluterange"), 0, INT_MAX, tabletAbsoluteRange)
- || parseIntOption(param, QLatin1String("dpiawareness"), QtWindows::ProcessDpiUnaware, QtWindows::ProcessPerMonitorDpiAware, dpiAwareness)) {
+ || parseIntOption(param, QLatin1String("dpiawareness"), QtWindows::ProcessDpiUnaware, QtWindows::ProcessPerMonitorV2DpiAware, dpiAwareness)) {
} else if (param == u"menus=native") {
options |= QWindowsIntegration::AlwaysUseNativeMenus;
} else if (param == u"menus=none") {
@@ -263,10 +263,19 @@ void QWindowsIntegrationPrivate::parseOptions(QWindowsIntegration *q, const QStr
if (!dpiAwarenessSet) { // Set only once in case of repeated instantiations of QGuiApplication.
if (!QCoreApplication::testAttribute(Qt::AA_PluginApplication)) {
- m_context.setProcessDpiAwareness(dpiAwareness);
- qCDebug(lcQpaWindows)
- << __FUNCTION__ << "DpiAwareness=" << dpiAwareness
- << "effective process DPI awareness=" << QWindowsContext::processDpiAwareness();
+
+ // DpiAwareV2 requires using new API
+ bool hasDpiAwarenessContext = QWindowsContext::user32dll.setProcessDpiAwarenessContext != nullptr;
+ if (dpiAwareness == QtWindows::ProcessPerMonitorV2DpiAware && hasDpiAwarenessContext) {
+ m_context.setProcessDpiV2Awareness();
+ qCDebug(lcQpaWindows)
+ << __FUNCTION__ << "DpiAwareness: DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2";
+ } else {
+ m_context.setProcessDpiAwareness(dpiAwareness);
+ qCDebug(lcQpaWindows)
+ << __FUNCTION__ << "DpiAwareness=" << dpiAwareness
+ << "effective process DPI awareness=" << QWindowsContext::processDpiAwareness();
+ }
}
dpiAwarenessSet = true;
}