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 bool QWindowsApplication::isDarkMode() const
{ {
return QWindowsContext::isDarkMode(); return QWindowsTheme::instance()->colorScheme() == Qt::ColorScheme::Dark;
} }
QWindowsApplication::DarkModeHandling QWindowsApplication::darkModeHandling() const QWindowsApplication::DarkModeHandling QWindowsApplication::darkModeHandling() const

View File

@ -154,11 +154,9 @@ struct QWindowsContextPrivate {
bool m_asyncExpose = false; bool m_asyncExpose = false;
HPOWERNOTIFY m_powerNotification = nullptr; HPOWERNOTIFY m_powerNotification = nullptr;
HWND m_powerDummyWindow = nullptr; HWND m_powerDummyWindow = nullptr;
static bool m_darkMode;
static bool m_v2DpiAware; static bool m_v2DpiAware;
}; };
bool QWindowsContextPrivate::m_darkMode = false;
bool QWindowsContextPrivate::m_v2DpiAware = false; bool QWindowsContextPrivate::m_v2DpiAware = false;
QWindowsContextPrivate::QWindowsContextPrivate() QWindowsContextPrivate::QWindowsContextPrivate()
@ -172,7 +170,6 @@ QWindowsContextPrivate::QWindowsContextPrivate()
m_systemInfo |= QWindowsContext::SI_RTL_Extensions; m_systemInfo |= QWindowsContext::SI_RTL_Extensions;
m_keyMapper.setUseRTLExtensions(true); m_keyMapper.setUseRTLExtensions(true);
} }
m_darkMode = QWindowsTheme::queryDarkMode();
if (FAILED(m_oleInitializeResult)) { if (FAILED(m_oleInitializeResult)) {
qWarning() << "QWindowsContext: OleInitialize() failed: " qWarning() << "QWindowsContext: OleInitialize() failed: "
<< QSystemError::windowsComString(m_oleInitializeResult); << QSystemError::windowsComString(m_oleInitializeResult);
@ -464,11 +461,6 @@ bool QWindowsContext::setProcessDpiAwareness(QtWindows::DpiAwareness dpiAwarenes
return true; return true;
} }
bool QWindowsContext::isDarkMode()
{
return QWindowsContextPrivate::m_darkMode;
}
QWindowsContext *QWindowsContext::instance() QWindowsContext *QWindowsContext::instance()
{ {
return m_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. // Only refresh the window theme if the user changes the personalize settings.
if ((wParam == 0) && (lParam != 0) // lParam sometimes may be NULL. if ((wParam == 0) && (lParam != 0) // lParam sometimes may be NULL.
&& (wcscmp(reinterpret_cast<LPCWSTR>(lParam), L"ImmersiveColorSet") == 0)) { && (wcscmp(reinterpret_cast<LPCWSTR>(lParam), L"ImmersiveColorSet") == 0)) {
const bool darkMode = QWindowsTheme::queryDarkMode(); QWindowsTheme::handleSettingsChanged();
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);
}
}
} }
return d->m_screenManager.handleScreenChanges(); return d->m_screenManager.handleScreenChanges();
} }

View File

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

View File

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

View File

@ -13,6 +13,7 @@
# include "qwindowssystemtrayicon.h" # include "qwindowssystemtrayicon.h"
#endif #endif
#include "qwindowsscreen.h" #include "qwindowsscreen.h"
#include "qwindowswindow.h"
#include <commctrl.h> #include <commctrl.h>
#include <objbase.h> #include <objbase.h>
#include <commoncontrols.h> #include <commoncontrols.h>
@ -451,6 +452,7 @@ QWindowsTheme *QWindowsTheme::m_instance = nullptr;
QWindowsTheme::QWindowsTheme() QWindowsTheme::QWindowsTheme()
{ {
m_instance = this; m_instance = this;
s_darkMode = QWindowsTheme::queryDarkMode();
std::fill(m_fonts, m_fonts + NFonts, nullptr); std::fill(m_fonts, m_fonts + NFonts, nullptr);
std::fill(m_palettes, m_palettes + NPalettes, nullptr); std::fill(m_palettes, m_palettes + NPalettes, nullptr);
refresh(); refresh();
@ -542,7 +544,26 @@ Qt::ColorScheme QWindowsTheme::colorScheme() const
{ {
if (queryHighContrast()) if (queryHighContrast())
return Qt::ColorScheme::Unknown; 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() void QWindowsTheme::clearPalettes()
@ -556,7 +577,7 @@ void QWindowsTheme::refreshPalettes()
if (!QGuiApplication::desktopSettingsAware()) if (!QGuiApplication::desktopSettingsAware())
return; return;
const bool light = const bool light =
!QWindowsContext::isDarkMode() !s_darkMode
|| !QWindowsIntegration::instance()->darkModeHandling().testFlag(QWindowsApplication::DarkModeStyle); || !QWindowsIntegration::instance()->darkModeHandling().testFlag(QWindowsApplication::DarkModeStyle);
clearPalettes(); clearPalettes();
m_palettes[SystemPalette] = new QPalette(QWindowsTheme::systemPalette(light ? Qt::ColorScheme::Light : Qt::ColorScheme::Dark)); 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; Qt::ColorScheme colorScheme() const override;
static void handleSettingsChanged();
const QPalette *palette(Palette type = SystemPalette) const override const QPalette *palette(Palette type = SystemPalette) const override
{ return m_palettes[type]; } { return m_palettes[type]; }
const QFont *font(Font type = SystemFont) const override const QFont *font(Font type = SystemFont) const override
@ -71,6 +73,7 @@ private:
void refreshIconPixmapSizes(); void refreshIconPixmapSizes();
static QWindowsTheme *m_instance; static QWindowsTheme *m_instance;
static inline bool s_darkMode = false;
QPalette *m_palettes[NPalettes]; QPalette *m_palettes[NPalettes];
QFont *m_fonts[NFonts]; QFont *m_fonts[NFonts];
QList<QSize> m_fileIconSizes; QList<QSize> m_fileIconSizes;

View File

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