forked from github_mirror/framelesshelper
win: add more dpi hacks & fix some bugs
Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
parent
b88ac1591d
commit
8c35eb9b70
|
@ -35,6 +35,8 @@
|
||||||
#include "winverhelper_p.h"
|
#include "winverhelper_p.h"
|
||||||
#include "framelesshelper_windows.h"
|
#include "framelesshelper_windows.h"
|
||||||
|
|
||||||
|
EXTERN_C BOOL WINAPI EnableChildWindowDpiMessage2(const HWND hWnd, const BOOL fEnable);
|
||||||
|
|
||||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||||
|
|
||||||
Q_LOGGING_CATEGORY(lcFramelessHelperWin, "wangwenx190.framelesshelper.core.impl.win")
|
Q_LOGGING_CATEGORY(lcFramelessHelperWin, "wangwenx190.framelesshelper.core.impl.win")
|
||||||
|
@ -73,6 +75,7 @@ FRAMELESSHELPER_STRING_CONSTANT(TrackMouseEvent)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(FindWindowW)
|
FRAMELESSHELPER_STRING_CONSTANT(FindWindowW)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(UnregisterClassW)
|
FRAMELESSHELPER_STRING_CONSTANT(UnregisterClassW)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(DestroyWindow)
|
FRAMELESSHELPER_STRING_CONSTANT(DestroyWindow)
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(EnableChildWindowDpiMessage)
|
||||||
[[maybe_unused]] static constexpr const char kFallbackTitleBarErrorMessage[] =
|
[[maybe_unused]] static constexpr const char kFallbackTitleBarErrorMessage[] =
|
||||||
"FramelessHelper is unable to create the fallback title bar window, and thus the snap layout feature will be disabled"
|
"FramelessHelper is unable to create the fallback title bar window, and thus the snap layout feature will be disabled"
|
||||||
" unconditionally. You can ignore this error and continue running your application, nothing else will be affected, "
|
" unconditionally. You can ignore this error and continue running your application, nothing else will be affected, "
|
||||||
|
@ -97,6 +100,17 @@ struct Win32Helper
|
||||||
|
|
||||||
Q_GLOBAL_STATIC(Win32Helper, g_win32Helper)
|
Q_GLOBAL_STATIC(Win32Helper, g_win32Helper)
|
||||||
|
|
||||||
|
[[nodiscard]] static inline QString hwnd2str(const WId windowId)
|
||||||
|
{
|
||||||
|
return FRAMELESSHELPER_STRING_LITERAL("0x")
|
||||||
|
+ QString::number(windowId, 16).toUpper();
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] static inline QString hwnd2str(const HWND hwnd)
|
||||||
|
{
|
||||||
|
return hwnd2str(reinterpret_cast<WId>(hwnd));
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] static inline LRESULT CALLBACK FallbackTitleBarWindowProc
|
[[nodiscard]] static inline LRESULT CALLBACK FallbackTitleBarWindowProc
|
||||||
(const HWND hWnd, const UINT uMsg, const WPARAM wParam, const LPARAM lParam)
|
(const HWND hWnd, const UINT uMsg, const WPARAM wParam, const LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
@ -508,6 +522,9 @@ void FramelessHelperWin::addWindow(const SystemParameters ¶ms)
|
||||||
qApp->installNativeEventFilter(g_win32Helper()->nativeEventFilter.data());
|
qApp->installNativeEventFilter(g_win32Helper()->nativeEventFilter.data());
|
||||||
}
|
}
|
||||||
g_win32Helper()->mutex.unlock();
|
g_win32Helper()->mutex.unlock();
|
||||||
|
DEBUG.noquote() << "The DPI of window" << hwnd2str(windowId) << "is: QDpi("
|
||||||
|
<< Utils::getWindowDpi(windowId, true) << ','
|
||||||
|
<< Utils::getWindowDpi(windowId, false) << ").";
|
||||||
// Some Qt internals have to be corrected.
|
// Some Qt internals have to be corrected.
|
||||||
Utils::maybeFixupQtInternals(windowId);
|
Utils::maybeFixupQtInternals(windowId);
|
||||||
// Qt maintains a frame margin internally, we need to update it accordingly
|
// Qt maintains a frame margin internally, we need to update it accordingly
|
||||||
|
@ -519,6 +536,18 @@ void FramelessHelperWin::addWindow(const SystemParameters ¶ms)
|
||||||
Utils::updateWindowFrameMargins(windowId, false);
|
Utils::updateWindowFrameMargins(windowId, false);
|
||||||
// Tell DWM we don't use the window icon/caption/sysmenu, don't draw them.
|
// Tell DWM we don't use the window icon/caption/sysmenu, don't draw them.
|
||||||
Utils::hideOriginalTitleBarElements(windowId);
|
Utils::hideOriginalTitleBarElements(windowId);
|
||||||
|
// We don't need this hack on Win10 1607 and newer, the PMv2 DPI awareness
|
||||||
|
// mode will take care of it for us by default.
|
||||||
|
if (WindowsVersionHelper::isWin10OrGreater()
|
||||||
|
&& !WindowsVersionHelper::isWin10RS1OrGreater()) {
|
||||||
|
// Without this hack, child windows can't get DPI change messages,
|
||||||
|
// which means only top level windows can scale to the correct size.
|
||||||
|
if (EnableChildWindowDpiMessage2(reinterpret_cast<HWND>(windowId), TRUE) == FALSE) {
|
||||||
|
if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) {
|
||||||
|
WARNING << Utils::getSystemErrorMessage(kEnableChildWindowDpiMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (WindowsVersionHelper::isWin10RS1OrGreater()) {
|
if (WindowsVersionHelper::isWin10RS1OrGreater()) {
|
||||||
// Tell DWM we may need dark theme non-client area (title bar & frame border).
|
// Tell DWM we may need dark theme non-client area (title bar & frame border).
|
||||||
FramelessHelper::Core::setApplicationOSThemeAware();
|
FramelessHelper::Core::setApplicationOSThemeAware();
|
||||||
|
@ -1096,6 +1125,10 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
} break;
|
} break;
|
||||||
#endif
|
#endif
|
||||||
case WM_DPICHANGED: {
|
case WM_DPICHANGED: {
|
||||||
|
const UINT dpiX = LOWORD(wParam);
|
||||||
|
const UINT dpiY = HIWORD(wParam);
|
||||||
|
DEBUG.noquote() << "New DPI for window" << hwnd2str(hWnd)
|
||||||
|
<< ": QDpi(" << dpiX << ',' << dpiY << ").";
|
||||||
// Sync the internal window frame margins with the latest DPI.
|
// Sync the internal window frame margins with the latest DPI.
|
||||||
Utils::updateInternalWindowFrameMargins(data.params.getWindowHandle(), true);
|
Utils::updateInternalWindowFrameMargins(data.params.getWindowHandle(), true);
|
||||||
// For some unknown reason, Qt sometimes won't re-paint the window contents after
|
// For some unknown reason, Qt sometimes won't re-paint the window contents after
|
||||||
|
|
|
@ -87,6 +87,11 @@ _GetSystemMetricsForDpi(
|
||||||
_In_ UINT dpi
|
_In_ UINT dpi
|
||||||
);
|
);
|
||||||
|
|
||||||
|
UINT WINAPI
|
||||||
|
_GetWindowDPI(
|
||||||
|
_In_ HWND hWnd
|
||||||
|
);
|
||||||
|
|
||||||
UINT WINAPI
|
UINT WINAPI
|
||||||
_GetDpiForWindow(
|
_GetDpiForWindow(
|
||||||
_In_ HWND hWnd
|
_In_ HWND hWnd
|
||||||
|
@ -149,6 +154,32 @@ _AreDpiAwarenessContextsEqual(
|
||||||
_In_ _DPI_AWARENESS_CONTEXT dpiContextB
|
_In_ _DPI_AWARENESS_CONTEXT dpiContextB
|
||||||
);
|
);
|
||||||
|
|
||||||
|
BOOL WINAPI
|
||||||
|
_EnableChildWindowDpiMessage(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ BOOL fEnable
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOL WINAPI
|
||||||
|
_EnablePerMonitorDialogScaling(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
int WINAPI
|
||||||
|
_GetDpiMetrics(
|
||||||
|
_In_ int nIndex,
|
||||||
|
_In_ UINT dpi
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOL WINAPI
|
||||||
|
_AdjustWindowRectExForDpi(
|
||||||
|
_Inout_ LPRECT lpRect,
|
||||||
|
_In_ DWORD dwStyle,
|
||||||
|
_In_ BOOL bMenu,
|
||||||
|
_In_ DWORD dwExStyle,
|
||||||
|
_In_ UINT dpi
|
||||||
|
);
|
||||||
|
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
|
||||||
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API BOOL WINAPI
|
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API BOOL WINAPI
|
||||||
|
@ -395,6 +426,150 @@ IsDarkModeAllowedForApp(VOID)
|
||||||
return pIsDarkModeAllowedForApp();
|
return pIsDarkModeAllowedForApp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API BOOL WINAPI
|
||||||
|
EnableChildWindowDpiMessage2(const HWND hWnd, const BOOL fEnable)
|
||||||
|
{
|
||||||
|
using EnableChildWindowDpiMessagePtr = decltype(&::_EnableChildWindowDpiMessage);
|
||||||
|
static const auto pEnableChildWindowDpiMessage = []() -> EnableChildWindowDpiMessagePtr {
|
||||||
|
FRAMELESSHELPER_USE_NAMESPACE
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(user32)
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(EnableChildWindowDpiMessage)
|
||||||
|
// EnableChildWindowDpiMessage() was once a public API, so we can load it by name,
|
||||||
|
// but it got removed in some later SDK versions, so we can't link to it directly.
|
||||||
|
// I haven't check the accurate time point of its removal.
|
||||||
|
if (const auto pFunc = reinterpret_cast<EnableChildWindowDpiMessagePtr>(
|
||||||
|
SysApiLoader::resolve(kuser32, kEnableChildWindowDpiMessage))) {
|
||||||
|
return pFunc;
|
||||||
|
}
|
||||||
|
// EnableChildWindowDpiMessage() was a private API when first introduced.
|
||||||
|
if (const auto pFunc = reinterpret_cast<EnableChildWindowDpiMessagePtr>(
|
||||||
|
SysApiLoader::resolve(kuser32, MAKEINTRESOURCEA(2704)))) {
|
||||||
|
return pFunc;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}();
|
||||||
|
if (!pEnableChildWindowDpiMessage) {
|
||||||
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return pEnableChildWindowDpiMessage(hWnd, fEnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API BOOL WINAPI
|
||||||
|
EnablePerMonitorDialogScaling2(VOID)
|
||||||
|
{
|
||||||
|
using EnablePerMonitorDialogScalingPtr = decltype(&::_EnablePerMonitorDialogScaling);
|
||||||
|
static const auto pEnablePerMonitorDialogScaling = []() -> EnablePerMonitorDialogScalingPtr {
|
||||||
|
FRAMELESSHELPER_USE_NAMESPACE
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(user32)
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(EnablePerMonitorDialogScaling)
|
||||||
|
// EnablePerMonitorDialogScaling() was once a public API, so we can load it by name,
|
||||||
|
// but it got removed in some later SDK versions, so we can't link to it directly.
|
||||||
|
// I haven't check the accurate time point of its removal.
|
||||||
|
if (const auto pFunc = reinterpret_cast<EnablePerMonitorDialogScalingPtr>(
|
||||||
|
SysApiLoader::resolve(kuser32, kEnablePerMonitorDialogScaling))) {
|
||||||
|
return pFunc;
|
||||||
|
}
|
||||||
|
// EnablePerMonitorDialogScaling() was a private API when first introduced.
|
||||||
|
if (const auto pFunc = reinterpret_cast<EnablePerMonitorDialogScalingPtr>(
|
||||||
|
SysApiLoader::resolve(kuser32, MAKEINTRESOURCEA(2577)))) {
|
||||||
|
return pFunc;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}();
|
||||||
|
if (!pEnablePerMonitorDialogScaling) {
|
||||||
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return pEnablePerMonitorDialogScaling();
|
||||||
|
}
|
||||||
|
|
||||||
|
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API UINT WINAPI
|
||||||
|
GetDpiForWindow2(const HWND hWnd)
|
||||||
|
{
|
||||||
|
using GetDpiForWindowPtr = decltype(&::_GetDpiForWindow);
|
||||||
|
static const auto pGetDpiForWindow = []() -> GetDpiForWindowPtr {
|
||||||
|
FRAMELESSHELPER_USE_NAMESPACE
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(user32)
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(GetDpiForWindow)
|
||||||
|
if (const auto pFunc = reinterpret_cast<GetDpiForWindowPtr>(
|
||||||
|
SysApiLoader::resolve(kuser32, kGetDpiForWindow))) {
|
||||||
|
return pFunc;
|
||||||
|
}
|
||||||
|
// GetDpiForWindow() was named "GetWindowDPI" before made public.
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(GetWindowDPI)
|
||||||
|
if (const auto pFunc = reinterpret_cast<GetDpiForWindowPtr>(
|
||||||
|
SysApiLoader::resolve(kuser32, kGetWindowDPI))) {
|
||||||
|
return pFunc;
|
||||||
|
}
|
||||||
|
// GetDpiForWindow() was a private API when first introduced.
|
||||||
|
if (const auto pFunc = reinterpret_cast<GetDpiForWindowPtr>(
|
||||||
|
SysApiLoader::resolve(kuser32, MAKEINTRESOURCEA(2707)))) {
|
||||||
|
return pFunc;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}();
|
||||||
|
if (!pGetDpiForWindow) {
|
||||||
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return pGetDpiForWindow(hWnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API int WINAPI
|
||||||
|
GetSystemMetricsForDpi2(const int nIndex, const UINT dpi)
|
||||||
|
{
|
||||||
|
using GetSystemMetricsForDpiPtr = decltype(&::_GetSystemMetricsForDpi);
|
||||||
|
static const auto pGetSystemMetricsForDpi = []() -> GetSystemMetricsForDpiPtr {
|
||||||
|
FRAMELESSHELPER_USE_NAMESPACE
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(user32)
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(GetSystemMetricsForDpi)
|
||||||
|
if (const auto pFunc = reinterpret_cast<GetSystemMetricsForDpiPtr>(
|
||||||
|
SysApiLoader::resolve(kuser32, kGetSystemMetricsForDpi))) {
|
||||||
|
return pFunc;
|
||||||
|
}
|
||||||
|
// GetSystemMetricsForDpi() was named "GetDpiMetrics" before made public.
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(GetDpiMetrics)
|
||||||
|
if (const auto pFunc = reinterpret_cast<GetSystemMetricsForDpiPtr>(
|
||||||
|
SysApiLoader::resolve(kuser32, kGetDpiMetrics))) {
|
||||||
|
return pFunc;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}();
|
||||||
|
if (!pGetSystemMetricsForDpi) {
|
||||||
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return pGetSystemMetricsForDpi(nIndex, dpi);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API BOOL WINAPI
|
||||||
|
AdjustWindowRectExForDpi2(LPRECT lpRect, const DWORD dwStyle,
|
||||||
|
const BOOL bMenu, const DWORD dwExStyle, const UINT dpi)
|
||||||
|
{
|
||||||
|
using AdjustWindowRectExForDpiPtr = decltype(&::_AdjustWindowRectExForDpi);
|
||||||
|
static const auto pAdjustWindowRectExForDpi = []() -> AdjustWindowRectExForDpiPtr {
|
||||||
|
FRAMELESSHELPER_USE_NAMESPACE
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(user32)
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(AdjustWindowRectExForDpi)
|
||||||
|
if (const auto pFunc = reinterpret_cast<AdjustWindowRectExForDpiPtr>(
|
||||||
|
SysApiLoader::resolve(kuser32, kAdjustWindowRectExForDpi))) {
|
||||||
|
return pFunc;
|
||||||
|
}
|
||||||
|
// AdjustWindowRectExForDpi() was a private API when first introduced.
|
||||||
|
if (const auto pFunc = reinterpret_cast<AdjustWindowRectExForDpiPtr>(
|
||||||
|
SysApiLoader::resolve(kuser32, MAKEINTRESOURCEA(2580)))) {
|
||||||
|
return pFunc;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}();
|
||||||
|
if (!pAdjustWindowRectExForDpi) {
|
||||||
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return pAdjustWindowRectExForDpi(lpRect, dwStyle, bMenu, dwExStyle, dpi);
|
||||||
|
}
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(QMargins)
|
Q_DECLARE_METATYPE(QMargins)
|
||||||
|
|
||||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||||
|
@ -510,6 +685,11 @@ FRAMELESSHELPER_STRING_CONSTANT(GetCurrentProcess)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(GetProcessDpiAwareness)
|
FRAMELESSHELPER_STRING_CONSTANT(GetProcessDpiAwareness)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(IsProcessDPIAware)
|
FRAMELESSHELPER_STRING_CONSTANT(IsProcessDPIAware)
|
||||||
FRAMELESSHELPER_STRING_CONSTANT(AreDpiAwarenessContextsEqual)
|
FRAMELESSHELPER_STRING_CONSTANT(AreDpiAwarenessContextsEqual)
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(GetWindowDPI)
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(AdjustWindowRectExForDpi)
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(GetDpiMetrics)
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(EnablePerMonitorDialogScaling)
|
||||||
|
FRAMELESSHELPER_STRING_CONSTANT(EnableChildWindowDpiMessage)
|
||||||
|
|
||||||
struct Win32UtilsHelperData
|
struct Win32UtilsHelperData
|
||||||
{
|
{
|
||||||
|
@ -661,13 +841,16 @@ struct SYSTEM_METRIC
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
const UINT realDpi = Utils::getWindowDpi(windowId, horizontal);
|
const UINT realDpi = Utils::getWindowDpi(windowId, horizontal);
|
||||||
if (API_USER_AVAILABLE(GetSystemMetricsForDpi)) {
|
{
|
||||||
const UINT dpi = (scaled ? realDpi : USER_DEFAULT_SCREEN_DPI);
|
const UINT dpi = (scaled ? realDpi : USER_DEFAULT_SCREEN_DPI);
|
||||||
return API_CALL_FUNCTION4(GetSystemMetricsForDpi, index, dpi);
|
if (const int result = GetSystemMetricsForDpi2(index, dpi)) {
|
||||||
} else {
|
return result;
|
||||||
const qreal dpr = (scaled ? qreal(1) : (qreal(realDpi) / qreal(USER_DEFAULT_SCREEN_DPI)));
|
}
|
||||||
return qRound(qreal(GetSystemMetrics(index)) / dpr);
|
|
||||||
}
|
}
|
||||||
|
// GetSystemMetrics() will always return a scaled value, so if we want to get an unscaled
|
||||||
|
// one, we have to calculate it ourself.
|
||||||
|
const qreal dpr = (scaled ? qreal(1) : (qreal(realDpi) / qreal(USER_DEFAULT_SCREEN_DPI)));
|
||||||
|
return qRound(qreal(GetSystemMetrics(index)) / dpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[maybe_unused]] [[nodiscard]] static inline
|
[[maybe_unused]] [[nodiscard]] static inline
|
||||||
|
@ -1301,11 +1484,13 @@ quint32 Utils::getWindowDpi(const WId windowId, const bool horizontal)
|
||||||
return USER_DEFAULT_SCREEN_DPI;
|
return USER_DEFAULT_SCREEN_DPI;
|
||||||
}
|
}
|
||||||
const auto hwnd = reinterpret_cast<HWND>(windowId);
|
const auto hwnd = reinterpret_cast<HWND>(windowId);
|
||||||
if (API_USER_AVAILABLE(GetDpiForWindow)) {
|
{
|
||||||
const UINT dpi = API_CALL_FUNCTION4(GetDpiForWindow, hwnd);
|
if (const UINT dpi = GetDpiForWindow2(hwnd)) {
|
||||||
if (dpi > 0) {
|
|
||||||
return dpi;
|
return dpi;
|
||||||
} else {
|
}
|
||||||
|
// ERROR_CALL_NOT_IMPLEMENTED: the function is not available on
|
||||||
|
// current platform, not an error.
|
||||||
|
if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) {
|
||||||
WARNING << getSystemErrorMessage(kGetDpiForWindow);
|
WARNING << getSystemErrorMessage(kGetDpiForWindow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1542,6 +1727,9 @@ bool Utils::isWindowFrameBorderVisible()
|
||||||
{
|
{
|
||||||
static const bool result = []() -> bool {
|
static const bool result = []() -> bool {
|
||||||
const FramelessConfig * const config = FramelessConfig::instance();
|
const FramelessConfig * const config = FramelessConfig::instance();
|
||||||
|
if (config->isSet(Option::UseCrossPlatformQtImplementation)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (config->isSet(Option::ForceShowWindowFrameBorder)) {
|
if (config->isSet(Option::ForceShowWindowFrameBorder)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1662,6 +1850,18 @@ void Utils::setAeroSnappingEnabled(const WId windowId, const bool enable)
|
||||||
|
|
||||||
void Utils::tryToEnableHighestDpiAwarenessLevel()
|
void Utils::tryToEnableHighestDpiAwarenessLevel()
|
||||||
{
|
{
|
||||||
|
// We don't need this hack when running on Win10 1607 and newer, the PMv2
|
||||||
|
// DPI awareness mode will take care of it for us by default.
|
||||||
|
if (WindowsVersionHelper::isWin10OrGreater()
|
||||||
|
&& !WindowsVersionHelper::isWin10RS1OrGreater()) {
|
||||||
|
// This function need to be called before any dialogs are created, so
|
||||||
|
// to be safe we call it here.
|
||||||
|
if (EnablePerMonitorDialogScaling2() == FALSE) {
|
||||||
|
if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) {
|
||||||
|
WARNING << getSystemErrorMessage(kEnablePerMonitorDialogScaling);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
bool isHighestAlready = false;
|
bool isHighestAlready = false;
|
||||||
const DpiAwareness currentAwareness = getDpiAwarenessForCurrentProcess(&isHighestAlready);
|
const DpiAwareness currentAwareness = getDpiAwarenessForCurrentProcess(&isHighestAlready);
|
||||||
DEBUG << "Current DPI awareness mode:" << currentAwareness;
|
DEBUG << "Current DPI awareness mode:" << currentAwareness;
|
||||||
|
@ -1679,7 +1879,7 @@ void Utils::tryToEnableHighestDpiAwarenessLevel()
|
||||||
}
|
}
|
||||||
const DWORD dwError = GetLastError();
|
const DWORD dwError = GetLastError();
|
||||||
// "ERROR_ACCESS_DENIED" means set externally (mostly due to manifest file).
|
// "ERROR_ACCESS_DENIED" means set externally (mostly due to manifest file).
|
||||||
// Any attempt to change the DPI awareness level through API will always fail,
|
// Any attempt to change the DPI awareness mode through API will always fail,
|
||||||
// so we treat this situation as succeeded.
|
// so we treat this situation as succeeded.
|
||||||
if (dwError == ERROR_ACCESS_DENIED) {
|
if (dwError == ERROR_ACCESS_DENIED) {
|
||||||
DEBUG << kDpiNoAccessErrorMessage;
|
DEBUG << kDpiNoAccessErrorMessage;
|
||||||
|
@ -1720,7 +1920,7 @@ void Utils::tryToEnableHighestDpiAwarenessLevel()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// "E_ACCESSDENIED" means set externally (mostly due to manifest file).
|
// "E_ACCESSDENIED" means set externally (mostly due to manifest file).
|
||||||
// Any attempt to change the DPI awareness level through API will always fail,
|
// Any attempt to change the DPI awareness mode through API will always fail,
|
||||||
// so we treat this situation as succeeded.
|
// so we treat this situation as succeeded.
|
||||||
if (hr == E_ACCESSDENIED) {
|
if (hr == E_ACCESSDENIED) {
|
||||||
DEBUG << kDpiNoAccessErrorMessage;
|
DEBUG << kDpiNoAccessErrorMessage;
|
||||||
|
@ -1827,8 +2027,8 @@ bool Utils::shouldAppsUseDarkMode_windows()
|
||||||
// it works well.
|
// it works well.
|
||||||
// However, reverse engineering of Win11's Task Manager reveals that Microsoft still
|
// However, reverse engineering of Win11's Task Manager reveals that Microsoft still
|
||||||
// uses this function internally to determine the system theme, and the Task Manager
|
// uses this function internally to determine the system theme, and the Task Manager
|
||||||
// can correctly respond to the theme change event indeed. Is it fixed silently
|
// can correctly respond to the theme change event indeed. But strangely, I've checked
|
||||||
// in some unknown Windows versions? To be checked.
|
// that it's still broken on Win11 22H2. What's going on here?
|
||||||
if (WindowsVersionHelper::isWin10RS5OrGreater()
|
if (WindowsVersionHelper::isWin10RS5OrGreater()
|
||||||
&& !WindowsVersionHelper::isWin1019H1OrGreater()) {
|
&& !WindowsVersionHelper::isWin1019H1OrGreater()) {
|
||||||
return (ShouldAppsUseDarkMode() != FALSE);
|
return (ShouldAppsUseDarkMode() != FALSE);
|
||||||
|
|
|
@ -262,9 +262,16 @@ void WidgetsSharedHelper::handleScreenChanged(QScreen *screen)
|
||||||
void WidgetsSharedHelper::updateContentsMargins()
|
void WidgetsSharedHelper::updateContentsMargins()
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
m_targetWidget->setContentsMargins(0,
|
const auto margins = [this]() -> QMargins {
|
||||||
((Utils::windowStatesToWindowState(m_targetWidget->windowState()) == Qt::WindowNoState)
|
if (!Utils::isWindowFrameBorderVisible() || WindowsVersionHelper::isWin11OrGreater()) {
|
||||||
? kDefaultWindowFrameBorderThickness : 0), 0, 0);
|
return {};
|
||||||
|
}
|
||||||
|
if (Utils::windowStatesToWindowState(m_targetWidget->windowState()) != Qt::WindowNoState) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return {0, kDefaultWindowFrameBorderThickness, 0, 0};
|
||||||
|
}();
|
||||||
|
m_targetWidget->setContentsMargins(margins);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue