forked from github_mirror/framelesshelper
minor improvement
Code simplification & adapt to latest Qt code. Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
parent
eeda750a61
commit
684ebc3fa3
|
@ -128,6 +128,7 @@ FRAMELESSHELPER_CORE_API void setQtDarkModeAwareEnabled(const bool enable);
|
|||
[[nodiscard]] FRAMELESSHELPER_CORE_API bool shouldAppsUseDarkMode_macos();
|
||||
FRAMELESSHELPER_CORE_API void setSystemTitleBarVisible(const WId windowId, const bool visible);
|
||||
[[nodiscard]] FRAMELESSHELPER_CORE_API QColor getControlsAccentColor();
|
||||
FRAMELESSHELPER_CORE_API void removeWindowProxy(const WId windowId);
|
||||
#endif // Q_OS_MACOS
|
||||
} // namespace Utils
|
||||
|
||||
|
|
|
@ -116,12 +116,16 @@ void FramelessHelperQt::removeWindow(const WId windowId)
|
|||
if (!g_qtHelper()->data.contains(windowId)) {
|
||||
return;
|
||||
}
|
||||
const QtHelperData data = g_qtHelper()->data.value(windowId);
|
||||
g_qtHelper()->data.remove(windowId);
|
||||
if (QWindow * const window = Utils::findWindow(windowId)) {
|
||||
window->removeEventFilter(data.eventFilter);
|
||||
if (const auto eventFilter = g_qtHelper()->data.value(windowId).eventFilter) {
|
||||
if (QWindow * const window = Utils::findWindow(windowId)) {
|
||||
window->removeEventFilter(eventFilter);
|
||||
}
|
||||
delete eventFilter;
|
||||
}
|
||||
delete data.eventFilter;
|
||||
g_qtHelper()->data.remove(windowId);
|
||||
#ifdef Q_OS_MACOS
|
||||
Utils::removeWindowProxy(windowId);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FramelessHelperQt::eventFilter(QObject *object, QEvent *event)
|
||||
|
|
|
@ -123,6 +123,9 @@ QVariant RegistryKey::value(const QString &name) const
|
|||
return {};
|
||||
}
|
||||
#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);
|
||||
if (dwVal.second) {
|
||||
return qulonglong(dwVal.first);
|
||||
|
@ -132,9 +135,10 @@ QVariant RegistryKey::value(const QString &name) const
|
|||
return strVal;
|
||||
}
|
||||
return {};
|
||||
#else
|
||||
# endif // (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
|
||||
#else // !REGISTRYKEY_QWINREGISTRYKEY
|
||||
return m_settings->value(name);
|
||||
#endif
|
||||
#endif // REGISTRYKEY_QWINREGISTRYKEY
|
||||
}
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
|
@ -757,6 +757,24 @@ void Utils::registerThemeChangeNotification()
|
|||
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
|
||||
|
||||
#include "utils_mac.moc"
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
#include "sysapiloader_p.h"
|
||||
#include "registrykey_p.h"
|
||||
#include <uxtheme.h>
|
||||
#include <d2d1.h>
|
||||
|
||||
EXTERN_C [[nodiscard]] FRAMELESSHELPER_CORE_API HRESULT WINAPI
|
||||
SetWindowThemeAttribute2(const HWND hWnd, const _WINDOWTHEMEATTRIBUTETYPE attrib,
|
||||
|
@ -86,7 +85,6 @@ Q_LOGGING_CATEGORY(lcUtilsWin, "wangwenx190.framelesshelper.core.utils.win")
|
|||
using namespace Global;
|
||||
|
||||
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);
|
||||
FRAMELESSHELPER_STRING_CONSTANT2(SuccessMessageText, "The operation completed successfully.")
|
||||
FRAMELESSHELPER_STRING_CONSTANT2(EmptyMessageText, "FormatMessageW() returned empty string.")
|
||||
|
@ -99,7 +97,6 @@ FRAMELESSHELPER_STRING_CONSTANT(user32)
|
|||
FRAMELESSHELPER_STRING_CONSTANT(dwmapi)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(winmm)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(shcore)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(d2d1)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(uxtheme)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(GetWindowRect)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(DwmIsCompositionEnabled)
|
||||
|
@ -135,9 +132,6 @@ FRAMELESSHELPER_STRING_CONSTANT(SetProcessDpiAwarenessContext)
|
|||
FRAMELESSHELPER_STRING_CONSTANT(SetProcessDpiAwareness)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(SetProcessDPIAware)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(GetDpiForMonitor)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(MonitorFromPoint)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(D2D1CreateFactory)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(ReloadSystemMetrics)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(GetDC)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(ReleaseDC)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(GetDeviceCaps)
|
||||
|
@ -169,6 +163,8 @@ FRAMELESSHELPER_STRING_CONSTANT(TileWallpaper)
|
|||
FRAMELESSHELPER_STRING_CONSTANT(UnregisterClassW)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(DestroyWindow)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(SetWindowThemeAttribute)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(CreateDCW)
|
||||
FRAMELESSHELPER_STRING_CONSTANT(DeleteDC)
|
||||
|
||||
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}}
|
||||
};
|
||||
|
||||
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()
|
||||
{
|
||||
static const QString key = QString::fromWCharArray(kDwmRegistryKey);
|
||||
|
@ -286,51 +227,6 @@ private:
|
|||
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)
|
||||
{
|
||||
static const std::optional<VersionNumber> currentOsVer = []() -> std::optional<VersionNumber> {
|
||||
|
@ -947,48 +843,61 @@ bool Utils::isHighContrastModeEnabled()
|
|||
|
||||
quint32 Utils::getPrimaryScreenDpi(const bool horizontal)
|
||||
{
|
||||
const auto getPrimaryMonitor = []() -> HMONITOR {
|
||||
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)) {
|
||||
const HMONITOR monitor = getPrimaryMonitor();
|
||||
if (monitor) {
|
||||
if (const HMONITOR hMonitor = MonitorFromWindow(GetDesktopWindow(), MONITOR_DEFAULTTOPRIMARY)) {
|
||||
if (API_SHCORE_AVAILABLE(GetDpiForMonitor)) {
|
||||
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)) {
|
||||
return (horizontal ? dpiX : dpiY);
|
||||
} else {
|
||||
WARNING << __getSystemErrorMessage(kGetDpiForMonitor, hr);
|
||||
}
|
||||
} else {
|
||||
WARNING << getSystemErrorMessage(kMonitorFromPoint);
|
||||
}
|
||||
}
|
||||
if (API_SHCORE_AVAILABLE(GetScaleFactorForMonitor)) {
|
||||
const HMONITOR monitor = getPrimaryMonitor();
|
||||
if (monitor) {
|
||||
if (API_SHCORE_AVAILABLE(GetScaleFactorForMonitor)) {
|
||||
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)) {
|
||||
return quint32(qRound(qreal(USER_DEFAULT_SCREEN_DPI) * qreal(factor) / qreal(100)));
|
||||
} else {
|
||||
WARNING << __getSystemErrorMessage(kGetScaleFactorForMonitor, hr);
|
||||
}
|
||||
} else {
|
||||
WARNING << getSystemErrorMessage(kMonitorFromPoint);
|
||||
}
|
||||
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 {
|
||||
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)) {
|
||||
using D2D1CreateFactoryPtr =
|
||||
HRESULT(WINAPI *)(D2D1_FACTORY_TYPE, REFIID, CONST D2D1_FACTORY_OPTIONS *, void **);
|
||||
const auto pD2D1CreateFactory =
|
||||
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),
|
||||
nullptr, reinterpret_cast<void **>(&d2dFactory));
|
||||
if (SUCCEEDED(hr)) {
|
||||
|
@ -1011,8 +920,9 @@ quint32 Utils::getPrimaryScreenDpi(const bool horizontal)
|
|||
WARNING << __getSystemErrorMessage(kD2D1CreateFactory, hr);
|
||||
}
|
||||
}
|
||||
const HDC hdc = GetDC(nullptr);
|
||||
if (hdc) {
|
||||
#endif
|
||||
|
||||
if (const HDC hdc = GetDC(nullptr)) {
|
||||
bool valid = false;
|
||||
const int dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
|
||||
const int dpiY = GetDeviceCaps(hdc, LOGPIXELSY);
|
||||
|
|
Loading…
Reference in New Issue