Skip to content
This repository has been archived by the owner on Dec 19, 2023. It is now read-only.

Commit

Permalink
win: fix theme not updating
Browse files Browse the repository at this point in the history
  • Loading branch information
wangwenx190 committed Aug 5, 2023
1 parent cb38272 commit 8d3ef93
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 18 deletions.
5 changes: 5 additions & 0 deletions include/FramelessHelper/Core/private/framelessmanager_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#pragma once

#include <FramelessHelper/Core/framelesshelpercore_global.h>
#include <QtCore/qtimer.h>
#include <optional>

FRAMELESSHELPER_BEGIN_NAMESPACE
Expand Down Expand Up @@ -66,6 +67,8 @@ class FRAMELESSHELPER_CORE_API FramelessManagerPrivate : public QObject

private:
void initialize();
void doNotifySystemThemeHasChangedOrNot();
void doNotifyWallpaperHasChangedOrNot();

private:
FramelessManager *q_ptr = nullptr;
Expand All @@ -77,6 +80,8 @@ class FRAMELESSHELPER_CORE_API FramelessManagerPrivate : public QObject
#endif
QString m_wallpaper = {};
Global::WallpaperAspectStyle m_wallpaperAspectStyle = Global::WallpaperAspectStyle::Fill;
QTimer m_themeTimer{};
QTimer m_wallpaperTimer{};
};

FRAMELESSHELPER_END_NAMESPACE
31 changes: 26 additions & 5 deletions src/core/framelesshelper_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,21 @@ struct FramelessWin32HelperInternal

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 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 RECT qrect2rect(const QRect &qrect);

Expand Down Expand Up @@ -388,20 +400,31 @@ Q_GLOBAL_STATIC(FramelessWin32HelperInternal, g_framelessWin32HelperData)
return false;
}
const auto parentWindowHandle = reinterpret_cast<HWND>(parentWindowId);
POINT parentWindowOriginPoint = { 0, 0 };
if (ClientToScreen(parentWindowHandle, &parentWindowOriginPoint) == FALSE) {
WARNING << Utils::getSystemErrorMessage(kClientToScreen);
return false;
}
RECT parentWindowClientRect = {};
if (GetClientRect(parentWindowHandle, &parentWindowClientRect) == FALSE) {
WARNING << Utils::getSystemErrorMessage(kGetClientRect);
return false;
}
const int titleBarHeight = Utils::getTitleBarHeight(parentWindowId, true);
const auto fallbackTitleBarWindowHandle = reinterpret_cast<HWND>(fallbackTitleBarWindowId);
POINT fallbackTitleBarOriginPoint = { 0, 0 };
if (ClientToScreen(fallbackTitleBarWindowHandle, &fallbackTitleBarOriginPoint) == FALSE) {
WARNING << Utils::getSystemErrorMessage(kClientToScreen);
return false;
}
RECT fallbackTitleBarClientRect = {};
if (GetClientRect(fallbackTitleBarWindowHandle, &fallbackTitleBarClientRect) == FALSE) {
WARNING << Utils::getSystemErrorMessage(kGetClientRect);
return false;
}
if ((RECT_WIDTH(fallbackTitleBarClientRect) == RECT_WIDTH(parentWindowClientRect))
&& (RECT_HEIGHT(fallbackTitleBarClientRect) == RECT_HEIGHT(parentWindowClientRect))) {
const SIZE currentSize = { RECT_WIDTH(fallbackTitleBarClientRect), RECT_HEIGHT(fallbackTitleBarClientRect) };
const SIZE expectedSize = { RECT_WIDTH(parentWindowClientRect), LONG(titleBarHeight) };
if ((fallbackTitleBarOriginPoint == parentWindowOriginPoint) && (currentSize == expectedSize)) {
return true;
}
const UINT flags = (SWP_NOACTIVATE | (hide ? SWP_HIDEWINDOW : SWP_SHOWWINDOW));
Expand All @@ -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
// into all the magic behind it.
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);
return false;
}
Expand Down Expand Up @@ -1350,11 +1373,9 @@ bool FramelessHelperWin::nativeEventFilter(const QByteArray &eventType, void *me
// Sometimes the FramelessManager instance may be destroyed already.
if (FramelessManager * const manager = FramelessManager::instance()) {
if (FramelessManagerPrivate * const managerPriv = FramelessManagerPrivate::get(manager)) {
#if (QT_VERSION < QT_VERSION_CHECK(6, 5, 0))
if (systemThemeChanged) {
managerPriv->notifySystemThemeHasChangedOrNot();
}
#endif // (QT_VERSION < QT_VERSION_CHECK(6, 5, 0))
if (wallpaperChanged) {
managerPriv->notifyWallpaperHasChangedOrNot();
}
Expand Down
44 changes: 33 additions & 11 deletions src/core/framelessmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,12 @@ FRAMELESSHELPER_BEGIN_NAMESPACE

using namespace Global;

struct FramelessManagerData
{
QList<WId> windowIds = {};
};
using FramelessManagerData = QList<WId>;

Q_GLOBAL_STATIC(FramelessManagerData, g_framelessManagerData)

static constexpr const int kEventDelayInterval = 1000;

#ifndef FRAMELESSHELPER_CORE_NO_BUNDLE_RESOURCE
[[nodiscard]] static inline QString iconFontFamilyName()
{
Expand Down Expand Up @@ -184,10 +183,10 @@ void FramelessManagerPrivate::addWindow(FramelessParamsConst params)
return;
}
const WId windowId = params->getWindowId();
if (g_framelessManagerData()->windowIds.contains(windowId)) {
if (g_framelessManagerData()->contains(windowId)) {
return;
}
g_framelessManagerData()->windowIds.append(windowId);
g_framelessManagerData()->append(windowId);
static const bool pureQt = usePureQtImplementation();
if (pureQt) {
FramelessHelperQt::addWindow(params);
Expand All @@ -207,10 +206,10 @@ void FramelessManagerPrivate::removeWindow(const WId windowId)
if (!windowId) {
return;
}
if (!g_framelessManagerData()->windowIds.contains(windowId)) {
if (!g_framelessManagerData()->contains(windowId)) {
return;
}
g_framelessManagerData()->windowIds.removeAll(windowId);
g_framelessManagerData()->removeAll(windowId);
static const bool pureQt = usePureQtImplementation();
if (pureQt) {
FramelessHelperQt::removeWindow(windowId);
Expand All @@ -225,6 +224,16 @@ void FramelessManagerPrivate::removeWindow(const WId windowId)
}

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 QColor currentAccentColor = Utils::getAccentColor();
Expand Down Expand Up @@ -259,7 +268,7 @@ void FramelessManagerPrivate::notifySystemThemeHasChangedOrNot()
}
}

void FramelessManagerPrivate::notifyWallpaperHasChangedOrNot()
void FramelessManagerPrivate::doNotifyWallpaperHasChangedOrNot()
{
const QString currentWallpaper = Utils::getWallpaperFilePath();
const WallpaperAspectStyle currentWallpaperAspectStyle = Utils::getWallpaperAspectStyle();
Expand Down Expand Up @@ -314,6 +323,16 @@ bool FramelessManagerPrivate::isThemeOverrided() const

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_accentColor = Utils::getAccentColor();
#ifdef Q_OS_WINDOWS
Expand All @@ -329,7 +348,10 @@ void FramelessManagerPrivate::initialize()
<< ", wallpaper: " << m_wallpaper
<< ", 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();
Q_ASSERT(styleHints);
if (styleHints) {
Expand All @@ -338,7 +360,7 @@ void FramelessManagerPrivate::initialize()
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;
if (!flagSet) {
flagSet = true;
Expand Down
64 changes: 62 additions & 2 deletions src/core/utils_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,46 @@ struct Win32UtilsInternal

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
{
return ((lhs.left == rhs.left) && (lhs.top == rhs.top)
Expand All @@ -210,14 +250,34 @@ Q_GLOBAL_STATIC(Win32UtilsInternal, g_win32UtilsData)
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)
{
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)
{
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)
Expand Down

0 comments on commit 8d3ef93

Please sign in to comment.