minor tweaks

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2022-07-24 14:54:55 +08:00
parent b2f443a592
commit 1264fe8341
3 changed files with 73 additions and 23 deletions

View File

@ -28,6 +28,7 @@
#include <QtCore/qmutex.h> #include <QtCore/qmutex.h>
#include <QtCore/qvariant.h> #include <QtCore/qvariant.h>
#include <QtCore/qcoreapplication.h> #include <QtCore/qcoreapplication.h>
#include <QtCore/qtimer.h>
#include <QtGui/qwindow.h> #include <QtGui/qwindow.h>
#include "framelessmanager.h" #include "framelessmanager.h"
#include "framelessmanager_p.h" #include "framelessmanager_p.h"
@ -46,7 +47,7 @@ Q_LOGGING_CATEGORY(lcFramelessHelperWin, "wangwenx190.framelesshelper.core.impl.
using namespace Global; using namespace Global;
static constexpr const wchar_t kFallbackTitleBarWindowClass[] = L"FALLBACK_TITLEBAR_WINDOW_CLASS\0"; static constexpr const wchar_t kFallbackTitleBarWindowClassName[] = L"org.wangwenx190.FramelessHelper.FallbackTitleBarWindow\0";
FRAMELESSHELPER_BYTEARRAY_CONSTANT2(Win32MessageTypeName, "windows_generic_MSG") FRAMELESSHELPER_BYTEARRAY_CONSTANT2(Win32MessageTypeName, "windows_generic_MSG")
FRAMELESSHELPER_STRING_CONSTANT(MonitorFromWindow) FRAMELESSHELPER_STRING_CONSTANT(MonitorFromWindow)
FRAMELESSHELPER_STRING_CONSTANT(GetMonitorInfoW) FRAMELESSHELPER_STRING_CONSTANT(GetMonitorInfoW)
@ -71,6 +72,7 @@ FRAMELESSHELPER_STRING_CONSTANT(SetLayeredWindowAttributes)
FRAMELESSHELPER_STRING_CONSTANT(SetWindowPos) FRAMELESSHELPER_STRING_CONSTANT(SetWindowPos)
FRAMELESSHELPER_STRING_CONSTANT(TrackMouseEvent) FRAMELESSHELPER_STRING_CONSTANT(TrackMouseEvent)
FRAMELESSHELPER_STRING_CONSTANT(FindWindowW) FRAMELESSHELPER_STRING_CONSTANT(FindWindowW)
FRAMELESSHELPER_STRING_CONSTANT(UnregisterClassW)
struct Win32HelperData struct Win32HelperData
{ {
@ -89,6 +91,21 @@ struct Win32Helper
Q_GLOBAL_STATIC(Win32Helper, g_win32Helper) Q_GLOBAL_STATIC(Win32Helper, g_win32Helper)
[[nodiscard]] static inline bool unregisterFallbackTitleBarWindowClass()
{
const HINSTANCE instance = GetModuleHandleW(nullptr);
if (instance) {
if (UnregisterClassW(kFallbackTitleBarWindowClassName, instance) == FALSE) {
WARNING << Utils::getSystemErrorMessage(kUnregisterClassW);
return false;
}
} else {
WARNING << Utils::getSystemErrorMessage(kGetModuleHandleW);
return false;
}
return true;
}
[[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)
{ {
@ -328,6 +345,25 @@ Q_GLOBAL_STATIC(Win32Helper, g_win32Helper)
case WM_NCRBUTTONDBLCLK: case WM_NCRBUTTONDBLCLK:
case WM_NCRBUTTONUP: case WM_NCRBUTTONUP:
return SendMessageW(parentWindowHandle, uMsg, wParam, lParam); return SendMessageW(parentWindowHandle, uMsg, wParam, lParam);
case WM_DESTROY: {
QMutexLocker locker(&g_win32Helper()->mutex);
g_win32Helper()->fallbackTitleBarToParentWindowMapping.remove(windowId);
if (g_win32Helper()->fallbackTitleBarToParentWindowMapping.count() < 1) {
// According to Microsoft Docs, window classes registered by DLLs will
// not be unregistered automatically on application termination, so we
// have to unregister them manually.
// And also from the docs, we are told that when the window received
// the "WM_DESTROY" message, the window may still exist, and we can't
// unregister the window class if it's corresponding windows are not
// all destroyed. So we have to wait a little bit to make sure the
// last window has been destroyed.
QTimer::singleShot(0, qApp, [](){
if (!unregisterFallbackTitleBarWindowClass()) {
WARNING << "Failed to unregister the window class of the fallback title bar window.";
}
});
}
} break;
default: default:
break; break;
} }
@ -387,31 +423,41 @@ Q_GLOBAL_STATIC(Win32Helper, g_win32Helper)
return false; return false;
} }
const auto parentWindowHandle = reinterpret_cast<HWND>(parentWindowId); const auto parentWindowHandle = reinterpret_cast<HWND>(parentWindowId);
const auto instance = static_cast<HINSTANCE>(GetModuleHandleW(nullptr)); const HINSTANCE instance = GetModuleHandleW(nullptr);
Q_ASSERT(instance); Q_ASSERT(instance);
if (!instance) { if (!instance) {
WARNING << Utils::getSystemErrorMessage(kGetModuleHandleW); WARNING << Utils::getSystemErrorMessage(kGetModuleHandleW);
return false; return false;
} }
static const ATOM fallbackTitleBarWindowClass = [instance]() -> ATOM { static const bool fallbackTitleBarWindowClass = [instance]() -> ATOM {
WNDCLASSEXW wcex; WNDCLASSEXW wcex = {};
// First try to find out if we have registered the window class already.
if (GetClassInfoExW(instance, kFallbackTitleBarWindowClassName, &wcex) != FALSE) {
// Register the same window class for multiple times will fail.
return true;
}
SecureZeroMemory(&wcex, sizeof(wcex)); SecureZeroMemory(&wcex, sizeof(wcex));
wcex.cbSize = sizeof(wcex); wcex.cbSize = sizeof(wcex);
// The "CS_DBLCLKS" style is necessary, don't remove it!
wcex.style = (CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS); wcex.style = (CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS);
wcex.lpszClassName = kFallbackTitleBarWindowClass; wcex.lpszClassName = kFallbackTitleBarWindowClassName;
wcex.hbrBackground = static_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)); wcex.hbrBackground = static_cast<HBRUSH>(GetStockObject(BLACK_BRUSH));
wcex.hCursor = LoadCursorW(nullptr, IDC_ARROW); wcex.hCursor = LoadCursorW(nullptr, IDC_ARROW);
wcex.lpfnWndProc = FallbackTitleBarWindowProc; wcex.lpfnWndProc = FallbackTitleBarWindowProc;
wcex.hInstance = instance; wcex.hInstance = instance;
return RegisterClassExW(&wcex); if (RegisterClassExW(&wcex) != INVALID_ATOM) {
return true;
}
WARNING << Utils::getSystemErrorMessage(kRegisterClassExW);
return false;
}(); }();
Q_ASSERT(fallbackTitleBarWindowClass); Q_ASSERT(fallbackTitleBarWindowClass);
if (!fallbackTitleBarWindowClass) { if (!fallbackTitleBarWindowClass) {
WARNING << Utils::getSystemErrorMessage(kRegisterClassExW); WARNING << "Failed to register the window class for the fallback title bar window.";
return false; return false;
} }
const HWND fallbackTitleBarWindowHandle = CreateWindowExW((WS_EX_LAYERED | WS_EX_NOREDIRECTIONBITMAP), const HWND fallbackTitleBarWindowHandle = CreateWindowExW((WS_EX_LAYERED | WS_EX_NOREDIRECTIONBITMAP),
kFallbackTitleBarWindowClass, nullptr, WS_CHILD, 0, 0, 0, 0, kFallbackTitleBarWindowClassName, nullptr, WS_CHILD, 0, 0, 0, 0,
parentWindowHandle, nullptr, instance, nullptr); parentWindowHandle, nullptr, instance, nullptr);
Q_ASSERT(fallbackTitleBarWindowHandle); Q_ASSERT(fallbackTitleBarWindowHandle);
if (!fallbackTitleBarWindowHandle) { if (!fallbackTitleBarWindowHandle) {

View File

@ -383,15 +383,18 @@ static inline void expblur(QImage &img, qreal radius, const bool improvedQuality
} }
if (p) { if (p) {
p->save();
p->scale(scale, scale); p->scale(scale, scale);
p->setRenderHints(QPainter::Antialiasing | p->setRenderHint(QPainter::Antialiasing, false);
QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform); p->setRenderHint(QPainter::TextAntialiasing, false);
p->setRenderHint(QPainter::SmoothPixmapTransform, false);
#if (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0))
const QSize imageSize = blurImage.deviceIndependentSize().toSize(); const QSize imageSize = blurImage.deviceIndependentSize().toSize();
#else #else
const QSize imageSize = QSizeF(QSizeF(blurImage.size()) / blurImage.devicePixelRatio()).toSize(); const QSize imageSize = QSizeF(QSizeF(blurImage.size()) / blurImage.devicePixelRatio()).toSize();
#endif #endif
p->drawImage(QRect(QPoint(0, 0), imageSize), blurImage); p->drawImage(QRect(QPoint(0, 0), imageSize), blurImage);
p->restore();
} }
} }
@ -535,7 +538,7 @@ void MicaMaterialPrivate::maybeGenerateBlurredWallpaper(const bool force)
g_micaMaterialData()->mutex.lock(); g_micaMaterialData()->mutex.lock();
QPainter painter(&g_micaMaterialData()->blurredWallpaper); QPainter painter(&g_micaMaterialData()->blurredWallpaper);
#if 1 #if 1
qt_blurImage(&painter, buffer, kDefaultBlurRadius, true, false); qt_blurImage(&painter, buffer, kDefaultBlurRadius, false, false);
#else #else
painter.drawImage(desktopOriginPoint, buffer); painter.drawImage(desktopOriginPoint, buffer);
#endif #endif

View File

@ -52,7 +52,7 @@ Q_LOGGING_CATEGORY(lcUtilsWin, "wangwenx190.framelesshelper.core.utils.win")
using namespace Global; using namespace Global;
static constexpr const wchar_t kDummyWindowClassName[] = L"FRAMELESSHELPER_DUMMY_WINDOW_CLASS"; 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.")
@ -258,21 +258,22 @@ private:
[[nodiscard]] static inline HWND ensureDummyWindow() [[nodiscard]] static inline HWND ensureDummyWindow()
{ {
static const HWND hwnd = []() -> HWND { static const HWND hwnd = []() -> HWND {
const HMODULE instance = GetModuleHandleW(nullptr); const HINSTANCE instance = GetModuleHandleW(nullptr);
if (!instance) { if (!instance) {
WARNING << Utils::getSystemErrorMessage(kGetModuleHandleW); WARNING << Utils::getSystemErrorMessage(kGetModuleHandleW);
return nullptr; return nullptr;
} }
WNDCLASSEXW wcex; WNDCLASSEXW wcex = {};
SecureZeroMemory(&wcex, sizeof(wcex)); if (GetClassInfoExW(instance, kDummyWindowClassName, &wcex) == FALSE) {
wcex.cbSize = sizeof(wcex); SecureZeroMemory(&wcex, sizeof(wcex));
wcex.lpfnWndProc = DefWindowProcW; wcex.cbSize = sizeof(wcex);
wcex.hInstance = instance; wcex.lpfnWndProc = DefWindowProcW;
wcex.lpszClassName = kDummyWindowClassName; wcex.hInstance = instance;
const ATOM atom = RegisterClassExW(&wcex); wcex.lpszClassName = kDummyWindowClassName;
if (!atom) { if (RegisterClassExW(&wcex) == INVALID_ATOM) {
WARNING << Utils::getSystemErrorMessage(kRegisterClassExW); WARNING << Utils::getSystemErrorMessage(kRegisterClassExW);
return nullptr; return nullptr;
}
} }
const HWND window = CreateWindowExW(0, kDummyWindowClassName, nullptr, const HWND window = CreateWindowExW(0, kDummyWindowClassName, nullptr,
WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, nullptr, nullptr, instance, nullptr); WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, nullptr, nullptr, instance, nullptr);