ColorScheme: consolidate dark mode handling on Windows into Theme

Move storage of whether dark mode is set into a static class member
of QWindowsTheme, and remove QWindowsContext::isDarkMode; ask the
theme instead using the colorScheme() implementation, which will return
the stored value.

Move the code handling settings changes into QWindowsTheme as well.

Task-number: QTBUG-124490
Change-Id: I4795e80b6ab2c94701385dc84771e9ad5578cf32
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Reviewed-by: Wladimir Leuschner <wladimir.leuschner@qt.io>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Volker Hilsheimer 2024-04-19 13:20:22 +02:00
parent 4f3f7d4622
commit d3b0d414b0
7 changed files with 33 additions and 31 deletions

View File

@ -74,7 +74,7 @@ bool QWindowsApplication::setWinTabEnabled(bool enabled)
bool QWindowsApplication::isDarkMode() const
{
return QWindowsContext::isDarkMode();
return QWindowsTheme::instance()->colorScheme() == Qt::ColorScheme::Dark;
}
QWindowsApplication::DarkModeHandling QWindowsApplication::darkModeHandling() const

View File

@ -154,11 +154,9 @@ struct QWindowsContextPrivate {
bool m_asyncExpose = false;
HPOWERNOTIFY m_powerNotification = nullptr;
HWND m_powerDummyWindow = nullptr;
static bool m_darkMode;
static bool m_v2DpiAware;
};
bool QWindowsContextPrivate::m_darkMode = false;
bool QWindowsContextPrivate::m_v2DpiAware = false;
QWindowsContextPrivate::QWindowsContextPrivate()
@ -172,7 +170,6 @@ QWindowsContextPrivate::QWindowsContextPrivate()
m_systemInfo |= QWindowsContext::SI_RTL_Extensions;
m_keyMapper.setUseRTLExtensions(true);
}
m_darkMode = QWindowsTheme::queryDarkMode();
if (FAILED(m_oleInitializeResult)) {
qWarning() << "QWindowsContext: OleInitialize() failed: "
<< QSystemError::windowsComString(m_oleInitializeResult);
@ -464,11 +461,6 @@ bool QWindowsContext::setProcessDpiAwareness(QtWindows::DpiAwareness dpiAwarenes
return true;
}
bool QWindowsContext::isDarkMode()
{
return QWindowsContextPrivate::m_darkMode;
}
QWindowsContext *QWindowsContext::instance()
{
return m_instance;
@ -1093,21 +1085,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
// Only refresh the window theme if the user changes the personalize settings.
if ((wParam == 0) && (lParam != 0) // lParam sometimes may be NULL.
&& (wcscmp(reinterpret_cast<LPCWSTR>(lParam), L"ImmersiveColorSet") == 0)) {
const bool darkMode = QWindowsTheme::queryDarkMode();
const bool darkModeChanged = darkMode != QWindowsContextPrivate::m_darkMode;
QWindowsContextPrivate::m_darkMode = darkMode;
auto integration = QWindowsIntegration::instance();
integration->updateApplicationBadge();
if (integration->darkModeHandling().testFlag(QWindowsApplication::DarkModeStyle)) {
QWindowsTheme::instance()->refresh();
QWindowSystemInterface::handleThemeChange();
}
if (darkModeChanged) {
if (integration->darkModeHandling().testFlag(QWindowsApplication::DarkModeWindowFrames)) {
for (QWindowsWindow *w : d->m_windows)
w->setDarkBorder(QWindowsContextPrivate::m_darkMode);
}
}
QWindowsTheme::handleSettingsChanged();
}
return d->m_screenManager.handleScreenChanges();
}

View File

@ -120,8 +120,6 @@ public:
static QtWindows::DpiAwareness processDpiAwareness();
static QtWindows::DpiAwareness windowDpiAwareness(HWND hwnd);
static bool isDarkMode();
void setDetectAltGrModifier(bool a);
// Returns a combination of SystemInfoFlags

View File

@ -642,7 +642,8 @@ void QWindowsIntegration::setApplicationBadge(qint64 number)
return;
}
const bool isDarkMode = QWindowsContext::isDarkMode();
const bool isDarkMode = QWindowsTheme::instance()->colorScheme()
== Qt::ColorScheme::Dark;
QColor badgeColor;
QColor textColor;

View File

@ -13,6 +13,7 @@
# include "qwindowssystemtrayicon.h"
#endif
#include "qwindowsscreen.h"
#include "qwindowswindow.h"
#include <commctrl.h>
#include <objbase.h>
#include <commoncontrols.h>
@ -451,6 +452,7 @@ QWindowsTheme *QWindowsTheme::m_instance = nullptr;
QWindowsTheme::QWindowsTheme()
{
m_instance = this;
s_darkMode = QWindowsTheme::queryDarkMode();
std::fill(m_fonts, m_fonts + NFonts, nullptr);
std::fill(m_palettes, m_palettes + NPalettes, nullptr);
refresh();
@ -542,7 +544,26 @@ Qt::ColorScheme QWindowsTheme::colorScheme() const
{
if (queryHighContrast())
return Qt::ColorScheme::Unknown;
return QWindowsContext::isDarkMode() ? Qt::ColorScheme::Dark : Qt::ColorScheme::Light;
return s_darkMode ? Qt::ColorScheme::Dark : Qt::ColorScheme::Light;
}
void QWindowsTheme::handleSettingsChanged()
{
const bool darkMode = QWindowsTheme::queryDarkMode();
const bool darkModeChanged = darkMode != QWindowsTheme::s_darkMode;
s_darkMode = darkMode;
auto integration = QWindowsIntegration::instance();
integration->updateApplicationBadge();
if (integration->darkModeHandling().testFlag(QWindowsApplication::DarkModeStyle)) {
QWindowsTheme::instance()->refresh();
QWindowSystemInterface::handleThemeChange();
}
if (darkModeChanged) {
if (integration->darkModeHandling().testFlag(QWindowsApplication::DarkModeWindowFrames)) {
for (QWindowsWindow *w : std::as_const(QWindowsContext::instance()->windows()))
w->setDarkBorder(s_darkMode);
}
}
}
void QWindowsTheme::clearPalettes()
@ -556,7 +577,7 @@ void QWindowsTheme::refreshPalettes()
if (!QGuiApplication::desktopSettingsAware())
return;
const bool light =
!QWindowsContext::isDarkMode()
!s_darkMode
|| !QWindowsIntegration::instance()->darkModeHandling().testFlag(QWindowsApplication::DarkModeStyle);
clearPalettes();
m_palettes[SystemPalette] = new QPalette(QWindowsTheme::systemPalette(light ? Qt::ColorScheme::Light : Qt::ColorScheme::Dark));

View File

@ -33,6 +33,8 @@ public:
Qt::ColorScheme colorScheme() const override;
static void handleSettingsChanged();
const QPalette *palette(Palette type = SystemPalette) const override
{ return m_palettes[type]; }
const QFont *font(Font type = SystemFont) const override
@ -71,6 +73,7 @@ private:
void refreshIconPixmapSizes();
static QWindowsTheme *m_instance;
static inline bool s_darkMode = false;
QPalette *m_palettes[NPalettes];
QFont *m_fonts[NFonts];
QList<QSize> m_fileIconSizes;

View File

@ -5,6 +5,7 @@
#include "qwindowswindow.h"
#include "qwindowscontext.h"
#include "qwindowstheme.h"
#if QT_CONFIG(draganddrop)
# include "qwindowsdrag.h"
#endif
@ -929,7 +930,7 @@ QWindowsWindowData
return result;
}
if (QWindowsContext::isDarkMode() && shouldApplyDarkFrame(w))
if (QWindowsTheme::instance()->colorScheme() == Qt::ColorScheme::Dark && shouldApplyDarkFrame(w))
QWindowsWindow::setDarkBorderToWindow(result.hwnd, true);
if (mirrorParentWidth != 0) {
@ -2689,7 +2690,7 @@ bool QWindowsWindow::windowEvent(QEvent *event)
{
switch (event->type()) {
case QEvent::ApplicationPaletteChange:
setDarkBorder(QWindowsContext::isDarkMode());
setDarkBorder(QWindowsTheme::instance()->colorScheme() == Qt::ColorScheme::Dark);
break;
case QEvent::WindowBlocked: // Blocked by another modal window.
setEnabled(false);