win: fix theme not updating
This commit is contained in:
parent
cb3827210c
commit
8d3ef93885
|
@ -25,6 +25,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <FramelessHelper/Core/framelesshelpercore_global.h>
|
#include <FramelessHelper/Core/framelesshelpercore_global.h>
|
||||||
|
#include <QtCore/qtimer.h>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||||
|
@ -66,6 +67,8 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initialize();
|
void initialize();
|
||||||
|
void doNotifySystemThemeHasChangedOrNot();
|
||||||
|
void doNotifyWallpaperHasChangedOrNot();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FramelessManager *q_ptr = nullptr;
|
FramelessManager *q_ptr = nullptr;
|
||||||
|
@ -77,6 +80,8 @@ private:
|
||||||
#endif
|
#endif
|
||||||
QString m_wallpaper = {};
|
QString m_wallpaper = {};
|
||||||
Global::WallpaperAspectStyle m_wallpaperAspectStyle = Global::WallpaperAspectStyle::Fill;
|
Global::WallpaperAspectStyle m_wallpaperAspectStyle = Global::WallpaperAspectStyle::Fill;
|
||||||
|
QTimer m_themeTimer{};
|
||||||
|
QTimer m_wallpaperTimer{};
|
||||||
};
|
};
|
||||||
|
|
||||||
FRAMELESSHELPER_END_NAMESPACE
|
FRAMELESSHELPER_END_NAMESPACE
|
||||||
|
|
|
@ -106,9 +106,21 @@ struct FramelessWin32HelperInternal
|
||||||
|
|
||||||
Q_GLOBAL_STATIC(FramelessWin32HelperInternal, g_framelessWin32HelperData)
|
Q_GLOBAL_STATIC(FramelessWin32HelperInternal, g_framelessWin32HelperData)
|
||||||
|
|
||||||
|
[[nodiscard]] extern bool operator==(const POINT &lhs, const POINT &rhs) noexcept;
|
||||||
|
[[nodiscard]] extern bool operator!=(const POINT &lhs, const POINT &rhs) noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] extern bool operator==(const SIZE &lhs, const SIZE &rhs) noexcept;
|
||||||
|
[[nodiscard]] extern bool operator!=(const SIZE &lhs, const SIZE &rhs) noexcept;
|
||||||
|
|
||||||
[[nodiscard]] extern bool operator==(const RECT &lhs, const RECT &rhs) noexcept;
|
[[nodiscard]] extern bool operator==(const RECT &lhs, const RECT &rhs) noexcept;
|
||||||
[[nodiscard]] extern bool operator!=(const RECT &lhs, const RECT &rhs) noexcept;
|
[[nodiscard]] extern bool operator!=(const RECT &lhs, const RECT &rhs) noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] extern QPoint point2qpoint(const POINT &point);
|
||||||
|
[[nodiscard]] extern POINT qpoint2point(const QPoint &point);
|
||||||
|
|
||||||
|
[[nodiscard]] extern QSize size2qsize(const SIZE &size);
|
||||||
|
[[nodiscard]] extern SIZE qsize2size(const QSize &size);
|
||||||
|
|
||||||
[[nodiscard]] extern QRect rect2qrect(const RECT &rect);
|
[[nodiscard]] extern QRect rect2qrect(const RECT &rect);
|
||||||
[[nodiscard]] extern RECT qrect2rect(const QRect &qrect);
|
[[nodiscard]] extern RECT qrect2rect(const QRect &qrect);
|
||||||
|
|
||||||
|
@ -388,6 +400,11 @@ Q_GLOBAL_STATIC(FramelessWin32HelperInternal, g_framelessWin32HelperData)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto parentWindowHandle = reinterpret_cast<HWND>(parentWindowId);
|
const auto parentWindowHandle = reinterpret_cast<HWND>(parentWindowId);
|
||||||
|
POINT parentWindowOriginPoint = { 0, 0 };
|
||||||
|
if (ClientToScreen(parentWindowHandle, &parentWindowOriginPoint) == FALSE) {
|
||||||
|
WARNING << Utils::getSystemErrorMessage(kClientToScreen);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
RECT parentWindowClientRect = {};
|
RECT parentWindowClientRect = {};
|
||||||
if (GetClientRect(parentWindowHandle, &parentWindowClientRect) == FALSE) {
|
if (GetClientRect(parentWindowHandle, &parentWindowClientRect) == FALSE) {
|
||||||
WARNING << Utils::getSystemErrorMessage(kGetClientRect);
|
WARNING << Utils::getSystemErrorMessage(kGetClientRect);
|
||||||
|
@ -395,13 +412,19 @@ Q_GLOBAL_STATIC(FramelessWin32HelperInternal, g_framelessWin32HelperData)
|
||||||
}
|
}
|
||||||
const int titleBarHeight = Utils::getTitleBarHeight(parentWindowId, true);
|
const int titleBarHeight = Utils::getTitleBarHeight(parentWindowId, true);
|
||||||
const auto fallbackTitleBarWindowHandle = reinterpret_cast<HWND>(fallbackTitleBarWindowId);
|
const auto fallbackTitleBarWindowHandle = reinterpret_cast<HWND>(fallbackTitleBarWindowId);
|
||||||
|
POINT fallbackTitleBarOriginPoint = { 0, 0 };
|
||||||
|
if (ClientToScreen(fallbackTitleBarWindowHandle, &fallbackTitleBarOriginPoint) == FALSE) {
|
||||||
|
WARNING << Utils::getSystemErrorMessage(kClientToScreen);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
RECT fallbackTitleBarClientRect = {};
|
RECT fallbackTitleBarClientRect = {};
|
||||||
if (GetClientRect(fallbackTitleBarWindowHandle, &fallbackTitleBarClientRect) == FALSE) {
|
if (GetClientRect(fallbackTitleBarWindowHandle, &fallbackTitleBarClientRect) == FALSE) {
|
||||||
WARNING << Utils::getSystemErrorMessage(kGetClientRect);
|
WARNING << Utils::getSystemErrorMessage(kGetClientRect);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((RECT_WIDTH(fallbackTitleBarClientRect) == RECT_WIDTH(parentWindowClientRect))
|
const SIZE currentSize = { RECT_WIDTH(fallbackTitleBarClientRect), RECT_HEIGHT(fallbackTitleBarClientRect) };
|
||||||
&& (RECT_HEIGHT(fallbackTitleBarClientRect) == RECT_HEIGHT(parentWindowClientRect))) {
|
const SIZE expectedSize = { RECT_WIDTH(parentWindowClientRect), LONG(titleBarHeight) };
|
||||||
|
if ((fallbackTitleBarOriginPoint == parentWindowOriginPoint) && (currentSize == expectedSize)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const UINT flags = (SWP_NOACTIVATE | (hide ? SWP_HIDEWINDOW : SWP_SHOWWINDOW));
|
const UINT flags = (SWP_NOACTIVATE | (hide ? SWP_HIDEWINDOW : SWP_SHOWWINDOW));
|
||||||
|
@ -415,7 +438,7 @@ Q_GLOBAL_STATIC(FramelessWin32HelperInternal, g_framelessWin32HelperData)
|
||||||
// it finally works. Since our current solution works well, I have no interest in digging
|
// it finally works. Since our current solution works well, I have no interest in digging
|
||||||
// into all the magic behind it.
|
// into all the magic behind it.
|
||||||
if (SetWindowPos(fallbackTitleBarWindowHandle, HWND_TOP, 0, 0,
|
if (SetWindowPos(fallbackTitleBarWindowHandle, HWND_TOP, 0, 0,
|
||||||
RECT_WIDTH(parentWindowClientRect), titleBarHeight, flags) == FALSE) {
|
int(expectedSize.cx), int(expectedSize.cy), flags) == FALSE) {
|
||||||
WARNING << Utils::getSystemErrorMessage(kSetWindowPos);
|
WARNING << Utils::getSystemErrorMessage(kSetWindowPos);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1350,11 +1373,9 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
|
||||||
// Sometimes the FramelessManager instance may be destroyed already.
|
// Sometimes the FramelessManager instance may be destroyed already.
|
||||||
if (FramelessManager * const manager = FramelessManager::instance()) {
|
if (FramelessManager * const manager = FramelessManager::instance()) {
|
||||||
if (FramelessManagerPrivate * const managerPriv = FramelessManagerPrivate::get(manager)) {
|
if (FramelessManagerPrivate * const managerPriv = FramelessManagerPrivate::get(manager)) {
|
||||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 5, 0))
|
|
||||||
if (systemThemeChanged) {
|
if (systemThemeChanged) {
|
||||||
managerPriv->notifySystemThemeHasChangedOrNot();
|
managerPriv->notifySystemThemeHasChangedOrNot();
|
||||||
}
|
}
|
||||||
#endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 0))
|
|
||||||
if (wallpaperChanged) {
|
if (wallpaperChanged) {
|
||||||
managerPriv->notifyWallpaperHasChangedOrNot();
|
managerPriv->notifyWallpaperHasChangedOrNot();
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,13 +60,12 @@ FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||||
|
|
||||||
using namespace Global;
|
using namespace Global;
|
||||||
|
|
||||||
struct FramelessManagerData
|
using FramelessManagerData = QList<WId>;
|
||||||
{
|
|
||||||
QList<WId> windowIds = {};
|
|
||||||
};
|
|
||||||
|
|
||||||
Q_GLOBAL_STATIC(FramelessManagerData, g_framelessManagerData)
|
Q_GLOBAL_STATIC(FramelessManagerData, g_framelessManagerData)
|
||||||
|
|
||||||
|
static constexpr const int kEventDelayInterval = 1000;
|
||||||
|
|
||||||
#ifndef FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE
|
#ifndef FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE
|
||||||
[[nodiscard]] static inline QString iconFontFamilyName()
|
[[nodiscard]] static inline QString iconFontFamilyName()
|
||||||
{
|
{
|
||||||
|
@ -184,10 +183,10 @@ void FramelessManagerPrivate::addWindow(FramelessParamsConst params)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const WId windowId = params->getWindowId();
|
const WId windowId = params->getWindowId();
|
||||||
if (g_framelessManagerData()->windowIds.contains(windowId)) {
|
if (g_framelessManagerData()->contains(windowId)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
g_framelessManagerData()->windowIds.append(windowId);
|
g_framelessManagerData()->append(windowId);
|
||||||
static const bool pureQt = usePureQtImplementation();
|
static const bool pureQt = usePureQtImplementation();
|
||||||
if (pureQt) {
|
if (pureQt) {
|
||||||
FramelessHelperQt::addWindow(params);
|
FramelessHelperQt::addWindow(params);
|
||||||
|
@ -207,10 +206,10 @@ void FramelessManagerPrivate::removeWindow(const WId windowId)
|
||||||
if (!windowId) {
|
if (!windowId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!g_framelessManagerData()->windowIds.contains(windowId)) {
|
if (!g_framelessManagerData()->contains(windowId)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
g_framelessManagerData()->windowIds.removeAll(windowId);
|
g_framelessManagerData()->removeAll(windowId);
|
||||||
static const bool pureQt = usePureQtImplementation();
|
static const bool pureQt = usePureQtImplementation();
|
||||||
if (pureQt) {
|
if (pureQt) {
|
||||||
FramelessHelperQt::removeWindow(windowId);
|
FramelessHelperQt::removeWindow(windowId);
|
||||||
|
@ -225,6 +224,16 @@ void FramelessManagerPrivate::removeWindow(const WId windowId)
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessManagerPrivate::notifySystemThemeHasChangedOrNot()
|
void FramelessManagerPrivate::notifySystemThemeHasChangedOrNot()
|
||||||
|
{
|
||||||
|
m_themeTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessManagerPrivate::notifyWallpaperHasChangedOrNot()
|
||||||
|
{
|
||||||
|
m_wallpaperTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FramelessManagerPrivate::doNotifySystemThemeHasChangedOrNot()
|
||||||
{
|
{
|
||||||
const SystemTheme currentSystemTheme = (Utils::shouldAppsUseDarkMode() ? SystemTheme::Dark : SystemTheme::Light);
|
const SystemTheme currentSystemTheme = (Utils::shouldAppsUseDarkMode() ? SystemTheme::Dark : SystemTheme::Light);
|
||||||
const QColor currentAccentColor = Utils::getAccentColor();
|
const QColor currentAccentColor = Utils::getAccentColor();
|
||||||
|
@ -259,7 +268,7 @@ void FramelessManagerPrivate::notifySystemThemeHasChangedOrNot()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramelessManagerPrivate::notifyWallpaperHasChangedOrNot()
|
void FramelessManagerPrivate::doNotifyWallpaperHasChangedOrNot()
|
||||||
{
|
{
|
||||||
const QString currentWallpaper = Utils::getWallpaperFilePath();
|
const QString currentWallpaper = Utils::getWallpaperFilePath();
|
||||||
const WallpaperAspectStyle currentWallpaperAspectStyle = Utils::getWallpaperAspectStyle();
|
const WallpaperAspectStyle currentWallpaperAspectStyle = Utils::getWallpaperAspectStyle();
|
||||||
|
@ -314,6 +323,16 @@ bool FramelessManagerPrivate::isThemeOverrided() const
|
||||||
|
|
||||||
void FramelessManagerPrivate::initialize()
|
void FramelessManagerPrivate::initialize()
|
||||||
{
|
{
|
||||||
|
m_themeTimer.setInterval(kEventDelayInterval);
|
||||||
|
m_themeTimer.callOnTimeout(this, [this](){
|
||||||
|
m_themeTimer.stop();
|
||||||
|
doNotifySystemThemeHasChangedOrNot();
|
||||||
|
});
|
||||||
|
m_wallpaperTimer.setInterval(kEventDelayInterval);
|
||||||
|
m_wallpaperTimer.callOnTimeout(this, [this](){
|
||||||
|
m_wallpaperTimer.stop();
|
||||||
|
doNotifyWallpaperHasChangedOrNot();
|
||||||
|
});
|
||||||
m_systemTheme = (Utils::shouldAppsUseDarkMode() ? SystemTheme::Dark : SystemTheme::Light);
|
m_systemTheme = (Utils::shouldAppsUseDarkMode() ? SystemTheme::Dark : SystemTheme::Light);
|
||||||
m_accentColor = Utils::getAccentColor();
|
m_accentColor = Utils::getAccentColor();
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
|
@ -329,7 +348,10 @@ void FramelessManagerPrivate::initialize()
|
||||||
<< ", wallpaper: " << m_wallpaper
|
<< ", wallpaper: " << m_wallpaper
|
||||||
<< ", aspect style: " << m_wallpaperAspectStyle
|
<< ", aspect style: " << m_wallpaperAspectStyle
|
||||||
<< '.';
|
<< '.';
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
|
// We are doing some tricks in our Windows message handling code, so
|
||||||
|
// we don't use Qt's theme notifier on Windows. But for other platforms
|
||||||
|
// we want to use as many Qt functionalities as possible.
|
||||||
|
#if ((QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)) && !defined(Q_OS_WINDOWS))
|
||||||
QStyleHints * const styleHints = QGuiApplication::styleHints();
|
QStyleHints * const styleHints = QGuiApplication::styleHints();
|
||||||
Q_ASSERT(styleHints);
|
Q_ASSERT(styleHints);
|
||||||
if (styleHints) {
|
if (styleHints) {
|
||||||
|
@ -338,7 +360,7 @@ void FramelessManagerPrivate::initialize()
|
||||||
notifySystemThemeHasChangedOrNot();
|
notifySystemThemeHasChangedOrNot();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
|
#endif // ((QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)) && !defined(Q_OS_WINDOWS))
|
||||||
static bool flagSet = false;
|
static bool flagSet = false;
|
||||||
if (!flagSet) {
|
if (!flagSet) {
|
||||||
flagSet = true;
|
flagSet = true;
|
||||||
|
|
|
@ -199,6 +199,46 @@ struct Win32UtilsInternal
|
||||||
|
|
||||||
Q_GLOBAL_STATIC(Win32UtilsInternal, g_win32UtilsData)
|
Q_GLOBAL_STATIC(Win32UtilsInternal, g_win32UtilsData)
|
||||||
|
|
||||||
|
[[nodiscard]] bool operator==(const POINT &lhs, const POINT &rhs) noexcept
|
||||||
|
{
|
||||||
|
return ((lhs.x == rhs.x) && (lhs.y == rhs.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool operator!=(const POINT &lhs, const POINT &rhs) noexcept
|
||||||
|
{
|
||||||
|
return !operator==(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool operator==(const SIZE &lhs, const SIZE &rhs) noexcept
|
||||||
|
{
|
||||||
|
return ((lhs.cx == rhs.cx) && (lhs.cy == rhs.cy));
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool operator!=(const SIZE &lhs, const SIZE &rhs) noexcept
|
||||||
|
{
|
||||||
|
return !operator==(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool operator>(const SIZE &lhs, const SIZE &rhs) noexcept
|
||||||
|
{
|
||||||
|
return ((lhs.cx * lhs.cy) > (rhs.cx * rhs.cy));
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool operator>=(const SIZE &lhs, const SIZE &rhs) noexcept
|
||||||
|
{
|
||||||
|
return (operator>(lhs, rhs) || operator==(lhs, rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool operator<(const SIZE &lhs, const SIZE &rhs) noexcept
|
||||||
|
{
|
||||||
|
return (operator!=(lhs, rhs) && !operator>(lhs, rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool operator<=(const SIZE &lhs, const SIZE &rhs) noexcept
|
||||||
|
{
|
||||||
|
return (operator<(lhs, rhs) || operator==(lhs, rhs));
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool operator==(const RECT &lhs, const RECT &rhs) noexcept
|
[[nodiscard]] bool operator==(const RECT &lhs, const RECT &rhs) noexcept
|
||||||
{
|
{
|
||||||
return ((lhs.left == rhs.left) && (lhs.top == rhs.top)
|
return ((lhs.left == rhs.left) && (lhs.top == rhs.top)
|
||||||
|
@ -210,14 +250,34 @@ Q_GLOBAL_STATIC(Win32UtilsInternal, g_win32UtilsData)
|
||||||
return !operator==(lhs, rhs);
|
return !operator==(lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] QPoint point2qpoint(const POINT &point)
|
||||||
|
{
|
||||||
|
return QPoint{ int(point.x), int(point.y) };
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] POINT qpoint2point(const QPoint &point)
|
||||||
|
{
|
||||||
|
return POINT{ LONG(point.x()), LONG(point.y()) };
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] QSize size2qsize(const SIZE &size)
|
||||||
|
{
|
||||||
|
return QSize{ int(size.cx), int(size.cy) };
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] SIZE qsize2size(const QSize &size)
|
||||||
|
{
|
||||||
|
return SIZE{ LONG(size.width()), LONG(size.height()) };
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] QRect rect2qrect(const RECT &rect)
|
[[nodiscard]] QRect rect2qrect(const RECT &rect)
|
||||||
{
|
{
|
||||||
return QRect{QPoint{rect.left, rect.top}, QSize{RECT_WIDTH(rect), RECT_HEIGHT(rect)}};
|
return QRect{ QPoint{ int(rect.left), int(rect.top) }, QSize{ int(RECT_WIDTH(rect)), int(RECT_HEIGHT(rect)) } };
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] RECT qrect2rect(const QRect &qrect)
|
[[nodiscard]] RECT qrect2rect(const QRect &qrect)
|
||||||
{
|
{
|
||||||
return {qrect.left(), qrect.top(), qrect.right(), qrect.bottom()};
|
return RECT{ LONG(qrect.left()), LONG(qrect.top()), LONG(qrect.right()), LONG(qrect.bottom()) };
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] QString hwnd2str(const WId windowId)
|
[[nodiscard]] QString hwnd2str(const WId windowId)
|
||||||
|
|
Loading…
Reference in New Issue