minor improvement

Code simplification & adapt to latest Qt code.

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2022-09-23 14:04:47 +08:00
parent eeda750a61
commit 684ebc3fa3
5 changed files with 74 additions and 137 deletions

View File

@ -128,6 +128,7 @@ FRAMELESSHELPER_CORE_API void setQtDarkModeAwareEnabled(const bool enable);
[[nodiscard]] FRAMELESSHELPER_CORE_API bool shouldAppsUseDarkMode_macos(); [[nodiscard]] FRAMELESSHELPER_CORE_API bool shouldAppsUseDarkMode_macos();
FRAMELESSHELPER_CORE_API void setSystemTitleBarVisible(const WId windowId, const bool visible); FRAMELESSHELPER_CORE_API void setSystemTitleBarVisible(const WId windowId, const bool visible);
[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getControlsAccentColor(); [[nodiscard]] FRAMELESSHELPER_CORE_API QColor getControlsAccentColor();
FRAMELESSHELPER_CORE_API void removeWindowProxy(const WId windowId);
#endif // Q_OS_MACOS #endif // Q_OS_MACOS
} // namespace Utils } // namespace Utils

View File

@ -116,12 +116,16 @@ void FramelessHelperQt::removeWindow(const WId windowId)
if (!g_qtHelper()->data.contains(windowId)) { if (!g_qtHelper()->data.contains(windowId)) {
return; return;
} }
const QtHelperData data = g_qtHelper()->data.value(windowId); if (const auto eventFilter = g_qtHelper()->data.value(windowId).eventFilter) {
g_qtHelper()->data.remove(windowId);
if (QWindow * const window = Utils::findWindow(windowId)) { if (QWindow * const window = Utils::findWindow(windowId)) {
window->removeEventFilter(data.eventFilter); window->removeEventFilter(eventFilter);
} }
delete data.eventFilter; delete eventFilter;
}
g_qtHelper()->data.remove(windowId);
#ifdef Q_OS_MACOS
Utils::removeWindowProxy(windowId);
#endif
} }
bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event) bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)

View File

@ -123,6 +123,9 @@ QVariant RegistryKey::value(const QString &name) const
return {}; return {};
} }
#if REGISTRYKEY_QWINREGISTRYKEY #if REGISTRYKEY_QWINREGISTRYKEY
# if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
return m_registryKey->value(name);
# else // (QT_VERSION < QT_VERSION_CHECK(6, 5, 0))
const QPair<DWORD, bool> dwVal = m_registryKey->dwordValue(name); const QPair<DWORD, bool> dwVal = m_registryKey->dwordValue(name);
if (dwVal.second) { if (dwVal.second) {
return qulonglong(dwVal.first); return qulonglong(dwVal.first);
@ -132,9 +135,10 @@ QVariant RegistryKey::value(const QString &name) const
return strVal; return strVal;
} }
return {}; return {};
#else # endif // (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
#else // !REGISTRYKEY_QWINREGISTRYKEY
return m_settings->value(name); return m_settings->value(name);
#endif #endif // REGISTRYKEY_QWINREGISTRYKEY
} }
FRAMELESSHELPER_END_NAMESPACE FRAMELESSHELPER_END_NAMESPACE

View File

@ -757,6 +757,24 @@ void Utils::registerThemeChangeNotification()
Q_UNUSED(observer); Q_UNUSED(observer);
} }
void Utils::removeWindowProxy(const WId windowId)
{
Q_ASSERT(windowId);
if (!windowId) {
return;
}
const QMutexLocker locker(&g_macUtilsData()->mutex);
if (!g_macUtilsData()->hash.contains(windowId)) {
return;
}
if (const auto proxy = g_macUtilsData()->hash.value(windowId)) {
// We'll restore everything to default in the destructor,
// so no need to do it manually here.
delete proxy;
}
g_macUtilsData()->hash.remove(windowId);
}
FRAMELESSHELPER_END_NAMESPACE FRAMELESSHELPER_END_NAMESPACE
#include "utils_mac.moc" #include "utils_mac.moc"

View File

@ -43,7 +43,6 @@
#include "sysapiloader_p.h" #include "sysapiloader_p.h"
#include "registrykey_p.h" #include "registrykey_p.h"
#include <uxtheme.h> #include <uxtheme.h>
#include <d2d1.h>
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API HRESULT WINAPI EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API HRESULT WINAPI
SetWindowThemeAttribute2(const HWND hWnd, const _WINDOWTHEMEATTRIBUTETYPE attrib, SetWindowThemeAttribute2(const HWND hWnd, const _WINDOWTHEMEATTRIBUTETYPE attrib,
@ -86,7 +85,6 @@ Q_LOGGING_CATEGORY(lcUtilsWin, "wangwenx190.framelesshelper.core.utils.win")
using namespace Global; using namespace Global;
static constexpr const char kNoFixQtInternalEnvVar[] = "FRAMELESSHELPER_WINDOWS_DONT_FIX_QT"; static constexpr const char kNoFixQtInternalEnvVar[] = "FRAMELESSHELPER_WINDOWS_DONT_FIX_QT";
static constexpr const wchar_t kDummyWindowClassName[] = L"org.wangwenx190.FramelessHelper.DummyWindow\0";
static const QString qDwmColorKeyName = QString::fromWCharArray(kDwmColorKeyName); static const QString qDwmColorKeyName = QString::fromWCharArray(kDwmColorKeyName);
FRAMELESSHELPER_STRING_CONSTANT2(SuccessMessageText, "The operation completed successfully.") FRAMELESSHELPER_STRING_CONSTANT2(SuccessMessageText, "The operation completed successfully.")
FRAMELESSHELPER_STRING_CONSTANT2(EmptyMessageText, "FormatMessageW() returned empty string.") FRAMELESSHELPER_STRING_CONSTANT2(EmptyMessageText, "FormatMessageW() returned empty string.")
@ -99,7 +97,6 @@ FRAMELESSHELPER_STRING_CONSTANT(user32)
FRAMELESSHELPER_STRING_CONSTANT(dwmapi) FRAMELESSHELPER_STRING_CONSTANT(dwmapi)
FRAMELESSHELPER_STRING_CONSTANT(winmm) FRAMELESSHELPER_STRING_CONSTANT(winmm)
FRAMELESSHELPER_STRING_CONSTANT(shcore) FRAMELESSHELPER_STRING_CONSTANT(shcore)
FRAMELESSHELPER_STRING_CONSTANT(d2d1)
FRAMELESSHELPER_STRING_CONSTANT(uxtheme) FRAMELESSHELPER_STRING_CONSTANT(uxtheme)
FRAMELESSHELPER_STRING_CONSTANT(GetWindowRect) FRAMELESSHELPER_STRING_CONSTANT(GetWindowRect)
FRAMELESSHELPER_STRING_CONSTANT(DwmIsCompositionEnabled) FRAMELESSHELPER_STRING_CONSTANT(DwmIsCompositionEnabled)
@ -135,9 +132,6 @@ FRAMELESSHELPER_STRING_CONSTANT(SetProcessDpiAwarenessContext)
FRAMELESSHELPER_STRING_CONSTANT(SetProcessDpiAwareness) FRAMELESSHELPER_STRING_CONSTANT(SetProcessDpiAwareness)
FRAMELESSHELPER_STRING_CONSTANT(SetProcessDPIAware) FRAMELESSHELPER_STRING_CONSTANT(SetProcessDPIAware)
FRAMELESSHELPER_STRING_CONSTANT(GetDpiForMonitor) FRAMELESSHELPER_STRING_CONSTANT(GetDpiForMonitor)
FRAMELESSHELPER_STRING_CONSTANT(MonitorFromPoint)
FRAMELESSHELPER_STRING_CONSTANT(D2D1CreateFactory)
FRAMELESSHELPER_STRING_CONSTANT(ReloadSystemMetrics)
FRAMELESSHELPER_STRING_CONSTANT(GetDC) FRAMELESSHELPER_STRING_CONSTANT(GetDC)
FRAMELESSHELPER_STRING_CONSTANT(ReleaseDC) FRAMELESSHELPER_STRING_CONSTANT(ReleaseDC)
FRAMELESSHELPER_STRING_CONSTANT(GetDeviceCaps) FRAMELESSHELPER_STRING_CONSTANT(GetDeviceCaps)
@ -169,6 +163,8 @@ FRAMELESSHELPER_STRING_CONSTANT(TileWallpaper)
FRAMELESSHELPER_STRING_CONSTANT(UnregisterClassW) FRAMELESSHELPER_STRING_CONSTANT(UnregisterClassW)
FRAMELESSHELPER_STRING_CONSTANT(DestroyWindow) FRAMELESSHELPER_STRING_CONSTANT(DestroyWindow)
FRAMELESSHELPER_STRING_CONSTANT(SetWindowThemeAttribute) FRAMELESSHELPER_STRING_CONSTANT(SetWindowThemeAttribute)
FRAMELESSHELPER_STRING_CONSTANT(CreateDCW)
FRAMELESSHELPER_STRING_CONSTANT(DeleteDC)
struct Win32UtilsHelperData struct Win32UtilsHelperData
{ {
@ -213,61 +209,6 @@ struct SYSTEM_METRIC
{SM_CXPADDEDBORDER, { 4, 5, 5, 6, 6, 6, 7, 7, 8, 9, 10, 12, 14, 16, 18, 20}} {SM_CXPADDEDBORDER, { 4, 5, 5, 6, 6, 6, 7, 7, 8, 9, 10, 12, 14, 16, 18, 20}}
}; };
template<typename T>
class HumbleComPtr
{
Q_DISABLE_COPY_MOVE(HumbleComPtr)
public:
explicit HumbleComPtr() = default;
explicit HumbleComPtr(T *ptr)
{
p = ptr;
}
~HumbleComPtr()
{
if (p) {
p->Release();
p = nullptr;
}
}
[[nodiscard]] operator T*() const
{
return p;
}
[[nodiscard]] T &operator*() const
{
Q_ASSERT(p);
return *p;
}
// The assert on operator& usually indicates a bug. If this is really
// what is needed, however, take the address of the p member explicitly.
[[nodiscard]] T **operator&()
{
Q_ASSERT(false);
return &p;
}
[[nodiscard]] T *operator->() const
{
Q_ASSERT(p);
return p;
}
[[nodiscard]] bool operator!() const
{
return (p == nullptr);
}
private:
T *p = nullptr;
};
[[nodiscard]] static inline QString dwmRegistryKey() [[nodiscard]] static inline QString dwmRegistryKey()
{ {
static const QString key = QString::fromWCharArray(kDwmRegistryKey); static const QString key = QString::fromWCharArray(kDwmRegistryKey);
@ -286,51 +227,6 @@ private:
return key; return key;
} }
[[nodiscard]] static inline HWND ensureDummyWindow()
{
static const HWND hwnd = []() -> HWND {
const HINSTANCE instance = GetModuleHandleW(nullptr);
if (!instance) {
WARNING << Utils::getSystemErrorMessage(kGetModuleHandleW);
return nullptr;
}
WNDCLASSEXW wcex = {};
if (GetClassInfoExW(instance, kDummyWindowClassName, &wcex) == FALSE) {
SecureZeroMemory(&wcex, sizeof(wcex));
wcex.cbSize = sizeof(wcex);
wcex.lpfnWndProc = DefWindowProcW;
wcex.hInstance = instance;
wcex.lpszClassName = kDummyWindowClassName;
if (RegisterClassExW(&wcex) == INVALID_ATOM) {
WARNING << Utils::getSystemErrorMessage(kRegisterClassExW);
return nullptr;
}
}
const HWND window = CreateWindowExW(0, kDummyWindowClassName, nullptr,
WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, nullptr, nullptr, instance, nullptr);
if (!window) {
WARNING << Utils::getSystemErrorMessage(kCreateWindowExW);
return nullptr;
}
FramelessHelper::Core::registerUninitializeHook([window](){
if (window && (DestroyWindow(window) == FALSE)) {
//WARNING << Utils::getSystemErrorMessage(kDestroyWindow);
return;
}
const HINSTANCE instance = GetModuleHandleW(nullptr);
if (!instance) {
//WARNING << Utils::getSystemErrorMessage(kGetModuleHandleW);
return;
}
if (UnregisterClassW(kDummyWindowClassName, instance) == FALSE) {
//WARNING << Utils::getSystemErrorMessage(kUnregisterClassW);
}
});
return window;
}();
return hwnd;
}
[[nodiscard]] static inline bool doCompareWindowsVersion(const VersionNumber &targetOsVer) [[nodiscard]] static inline bool doCompareWindowsVersion(const VersionNumber &targetOsVer)
{ {
static const std::optional<VersionNumber> currentOsVer = []() -> std::optional<VersionNumber> { static const std::optional<VersionNumber> currentOsVer = []() -> std::optional<VersionNumber> {
@ -947,48 +843,61 @@ bool Utils::isHighContrastModeEnabled()
quint32 Utils::getPrimaryScreenDpi(const bool horizontal) quint32 Utils::getPrimaryScreenDpi(const bool horizontal)
{ {
const auto getPrimaryMonitor = []() -> HMONITOR { if (const HMONITOR hMonitor = MonitorFromWindow(GetDesktopWindow(), MONITOR_DEFAULTTOPRIMARY)) {
const HWND window = ensureDummyWindow();
if (window) {
return MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY);
}
static constexpr const int kTaskBarSize = 100;
return MonitorFromPoint(POINT{kTaskBarSize, kTaskBarSize}, MONITOR_DEFAULTTOPRIMARY);
};
if (API_SHCORE_AVAILABLE(GetDpiForMonitor)) { if (API_SHCORE_AVAILABLE(GetDpiForMonitor)) {
const HMONITOR monitor = getPrimaryMonitor();
if (monitor) {
UINT dpiX = 0, dpiY = 0; UINT dpiX = 0, dpiY = 0;
const HRESULT hr = API_CALL_FUNCTION(GetDpiForMonitor, monitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY); const HRESULT hr = API_CALL_FUNCTION(GetDpiForMonitor, hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
if (SUCCEEDED(hr) && (dpiX > 0) && (dpiY > 0)) { if (SUCCEEDED(hr) && (dpiX > 0) && (dpiY > 0)) {
return (horizontal ? dpiX : dpiY); return (horizontal ? dpiX : dpiY);
} else { } else {
WARNING << __getSystemErrorMessage(kGetDpiForMonitor, hr); WARNING << __getSystemErrorMessage(kGetDpiForMonitor, hr);
} }
} else {
WARNING << getSystemErrorMessage(kMonitorFromPoint);
}
} }
if (API_SHCORE_AVAILABLE(GetScaleFactorForMonitor)) { if (API_SHCORE_AVAILABLE(GetScaleFactorForMonitor)) {
const HMONITOR monitor = getPrimaryMonitor();
if (monitor) {
DEVICE_SCALE_FACTOR factor = DEVICE_SCALE_FACTOR_INVALID; DEVICE_SCALE_FACTOR factor = DEVICE_SCALE_FACTOR_INVALID;
const HRESULT hr = API_CALL_FUNCTION(GetScaleFactorForMonitor, monitor, &factor); const HRESULT hr = API_CALL_FUNCTION(GetScaleFactorForMonitor, hMonitor, &factor);
if (SUCCEEDED(hr) && (factor != DEVICE_SCALE_FACTOR_INVALID)) { if (SUCCEEDED(hr) && (factor != DEVICE_SCALE_FACTOR_INVALID)) {
return quint32(qRound(qreal(USER_DEFAULT_SCREEN_DPI) * qreal(factor) / qreal(100))); return quint32(qRound(qreal(USER_DEFAULT_SCREEN_DPI) * qreal(factor) / qreal(100)));
} else { } else {
WARNING << __getSystemErrorMessage(kGetScaleFactorForMonitor, hr); WARNING << __getSystemErrorMessage(kGetScaleFactorForMonitor, hr);
} }
}
MONITORINFOEXW monitorInfo;
SecureZeroMemory(&monitorInfo, sizeof(monitorInfo));
monitorInfo.cbSize = sizeof(monitorInfo);
if (GetMonitorInfoW(hMonitor, &monitorInfo) != FALSE) {
if (const HDC hdc = CreateDCW(monitorInfo.szDevice, monitorInfo.szDevice, nullptr, nullptr)) {
bool valid = false;
const int dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
const int dpiY = GetDeviceCaps(hdc, LOGPIXELSY);
if ((dpiX > 0) && (dpiY > 0)) {
valid = true;
} else { } else {
WARNING << getSystemErrorMessage(kMonitorFromPoint); WARNING << getSystemErrorMessage(kGetDeviceCaps);
} }
if (DeleteDC(hdc) == FALSE) {
WARNING << getSystemErrorMessage(kDeleteDC);
} }
if (valid) {
return (horizontal ? dpiX : dpiY);
}
} else {
WARNING << getSystemErrorMessage(kCreateDCW);
}
} else {
WARNING << getSystemErrorMessage(kGetMonitorInfoW);
}
} else {
WARNING << getSystemErrorMessage(kMonitorFromWindow);
}
#if 0 // The above solutions should be sufficient enough, no need to pull in a new dependency.
if (API_D2D_AVAILABLE(D2D1CreateFactory)) { if (API_D2D_AVAILABLE(D2D1CreateFactory)) {
using D2D1CreateFactoryPtr = using D2D1CreateFactoryPtr =
HRESULT(WINAPI *)(D2D1_FACTORY_TYPE, REFIID, CONST D2D1_FACTORY_OPTIONS *, void **); HRESULT(WINAPI *)(D2D1_FACTORY_TYPE, REFIID, CONST D2D1_FACTORY_OPTIONS *, void **);
const auto pD2D1CreateFactory = const auto pD2D1CreateFactory =
reinterpret_cast<D2D1CreateFactoryPtr>(SysApiLoader::instance()->get(kD2D1CreateFactory)); reinterpret_cast<D2D1CreateFactoryPtr>(SysApiLoader::instance()->get(kD2D1CreateFactory));
auto d2dFactory = HumbleComPtr<ID2D1Factory>(nullptr); auto d2dFactory = CComPtr<ID2D1Factory>(nullptr);
HRESULT hr = pD2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory), HRESULT hr = pD2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory),
nullptr, reinterpret_cast<void **>(&d2dFactory)); nullptr, reinterpret_cast<void **>(&d2dFactory));
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
@ -1011,8 +920,9 @@ quint32 Utils::getPrimaryScreenDpi(const bool horizontal)
WARNING << __getSystemErrorMessage(kD2D1CreateFactory, hr); WARNING << __getSystemErrorMessage(kD2D1CreateFactory, hr);
} }
} }
const HDC hdc = GetDC(nullptr); #endif
if (hdc) {
if (const HDC hdc = GetDC(nullptr)) {
bool valid = false; bool valid = false;
const int dpiX = GetDeviceCaps(hdc, LOGPIXELSX); const int dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
const int dpiY = GetDeviceCaps(hdc, LOGPIXELSY); const int dpiY = GetDeviceCaps(hdc, LOGPIXELSY);