Utility method to check if a theme is supposed to be in dark or light mode. (#6785)
Some checks are pending
Build Desktop / Configure (push) Waiting to run
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Debian, DEB, 11) (push) Blocked by required conditions
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Debian, DEB, 13) (push) Blocked by required conditions
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Debian, DEB, skip, 12) (push) Blocked by required conditions
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Fedora, RPM, 44) (push) Blocked by required conditions
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Fedora, RPM, skip, 43) (push) Blocked by required conditions
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Servatrice_Debian, DEB, yes, skip, 11) (push) Blocked by required conditions
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Ubuntu, DEB, 24.04) (push) Blocked by required conditions
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Ubuntu, DEB, 26.04) (push) Blocked by required conditions
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (Ubuntu, DEB, skip, 22.04) (push) Blocked by required conditions
Build Desktop / ${{matrix.distro}} ${{matrix.version}} (yes, Arch, skip) (push) Blocked by required conditions
Build Desktop / ${{matrix.os}} ${{matrix.target}}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }} (7d, Ninja, 1, macOS, -macOS14, clang_64, qtimageformats qtmultimedia qtwebsockets, 6.11.*, macos-14, Apple, 14, Release, 1, … (push) Blocked by required conditions
Build Desktop / ${{matrix.os}} ${{matrix.target}}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }} (7d, Ninja, 1, macOS, -macOS15, clang_64, qtimageformats qtmultimedia qtwebsockets, 6.11.*, macos-15, Apple, 15, Release, 1, … (push) Blocked by required conditions
Build Desktop / ${{matrix.os}} ${{matrix.target}}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }} (7d, Ninja, 1, macOS, 13, -macOS13_Intel, clang_64, qtimageformats qtmultimedia qtwebsockets, 6.11.*, macos-15-intel, Intel, … (push) Blocked by required conditions
Build Desktop / ${{matrix.os}} ${{matrix.target}}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }} (7d, Ninja, macOS, clang_64, qtimageformats qtmultimedia qtwebsockets, 6.11.*, macos-15, Apple, 15, Debug, 1, 16.4) (push) Blocked by required conditions
Build Desktop / ${{matrix.os}} ${{matrix.target}}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }} (Visual Studio 17 2022, x64, 1, Windows, -Win10, win64_msvc2022_64, qtimageformats qtmultimedia qtwebsockets, 6.11.*, windows… (push) Blocked by required conditions
Build Docker Image / amd64 & arm64 (push) Waiting to run

* Utility method to check if a theme is supposed to be in dark or light mode.

Took 22 minutes

Took 4 seconds

* Method is public.

Took 3 minutes

* Add a utility method to check if we're using a built-in theme

Took 3 minutes

Took 3 seconds

* Use built-in theme detection for home screen.

Took 6 minutes

* Re-polish on theme change

Took 2 minutes

* Fetch background on theme change.

Took 4 minutes

Took 6 seconds

* No need to double polish.

Took 4 minutes

* No need to repaint.

Took 32 seconds

* Only repolish visible widgets.

Took 5 minutes

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
BruebachL 2026-05-08 13:47:14 +02:00 committed by GitHub
parent 43bee2316e
commit a4c2b1411f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 77 additions and 11 deletions

View File

@ -15,6 +15,7 @@
#include <QStyle>
#include <QStyleFactory>
#include <QStyleHints>
#include <QWidget>
#include <Qt>
#define NONE_THEME_NAME "Default"
@ -112,6 +113,39 @@ void ThemeManager::ensureThemeDirectoryExists()
}
}
bool ThemeManager::isDarkMode()
{
auto themeName = SettingsCache::instance().getThemeName();
// Explicit Dark Mode
if (themeName == FUSION_THEME_NAME_LIGHT || themeName.endsWith("(Light)")) {
return false;
}
// Explicit Light Mode
if (themeName == FUSION_THEME_NAME_DARK || themeName.endsWith("(Dark)")) {
return true;
}
// Auto detection on compatible Qt versions
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
if (QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark &&
(themeName == NONE_THEME_NAME || themeName == FUSION_THEME_NAME || themeName.endsWith("(System Default)"))) {
return true;
} else {
return false;
}
#endif
// Default to light mode
return false;
}
bool ThemeManager::isBuiltInTheme()
{
const auto themeName = SettingsCache::instance().getThemeName();
return themeName == NONE_THEME_NAME || themeName == FUSION_THEME_NAME || themeName == FUSION_THEME_NAME_LIGHT ||
themeName == FUSION_THEME_NAME_DARK;
}
QStringMap &ThemeManager::getAvailableThemes()
{
QDir dir;
@ -335,26 +369,53 @@ void ThemeManager::themeChangedSlot()
qApp->setStyleSheet("");
}
QStyle *newStyle = nullptr;
QPalette newPalette;
if (themeName == FUSION_THEME_NAME) {
QStyle *fusionStyle = QStyleFactory::create("Fusion");
qApp->setStyle(fusionStyle);
newStyle = QStyleFactory::create("Fusion");
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
// Start from Fusion's own palette so dark mode is handled correctly,
// then apply any tweaks on top of it.
QPalette palette = fusionStyle->standardPalette();
newPalette = newStyle->standardPalette();
if (QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark) {
palette.setColor(QPalette::AlternateBase, QColor(53, 53, 53));
newPalette.setColor(QPalette::AlternateBase, QColor(53, 53, 53));
}
qApp->setPalette(palette);
#else
newPalette = qApp->palette();
#endif
} else if (themeName == FUSION_THEME_NAME_LIGHT) {
qApp->setStyle(QStyleFactory::create("Fusion"));
qApp->setPalette(createLightGreenFusionPalette());
newStyle = QStyleFactory::create("Fusion");
newPalette = createLightGreenFusionPalette();
} else if (themeName == FUSION_THEME_NAME_DARK) {
qApp->setStyle(QStyleFactory::create("Fusion"));
qApp->setPalette(createDarkGreenFusionPalette());
newStyle = QStyleFactory::create("Fusion");
newPalette = createDarkGreenFusionPalette();
} else {
qApp->setStyle(QStyleFactory::create(defaultStyleName)); // setting the style also sets the palette
newStyle = QStyleFactory::create(defaultStyleName);
// Use the style's default palette.
newPalette = newStyle->standardPalette();
}
// Apply palette FIRST.
qApp->setPalette(newPalette);
// Then apply style.
qApp->setStyle(newStyle);
// Force every widget to re-polish and repaint immediately rather than
// waiting for natural expose events, which produces a patchwork of old
// and new colours during a live preview.
// Note: we do NOT call widget->setPalette(base) here — qApp->setPalette()
// already propagates to all widgets that haven't explicitly overridden their
// palette (WA_SetPalette not set). Calling it unconditionally would clobber
// intentional per-widget palette customisations across the whole app.
for (QWidget *widget : qApp->allWidgets()) {
if (widget->isVisible()) {
newStyle->unpolish(widget);
newStyle->polish(widget);
widget->update();
}
}
if (dirPath.isEmpty()) {

View File

@ -54,6 +54,8 @@ protected:
QBrush loadExtraBrush(QString fileName, QBrush &fallbackBrush);
public:
bool isBuiltInTheme();
bool isDarkMode();
QStringMap &getAvailableThemes();
QBrush &getBgBrush(Role zone);

View File

@ -2,6 +2,7 @@
#include "../../../client/settings/cache_settings.h"
#include "../../../interface/widgets/tabs/tab_supervisor.h"
#include "../../theme_manager.h"
#include "../../window_main.h"
#include "background_sources.h"
#include "home_styled_button.h"
@ -46,6 +47,8 @@ HomeWidget::HomeWidget(QWidget *parent, TabSupervisor *_tabSupervisor)
&HomeWidget::onBackgroundShuffleFrequencyChanged);
// Lambda is cleaner to read than overloading this
connect(&SettingsCache::instance(), &SettingsCache::homeTabDisplayCardNameChanged, this, [this] { repaint(); });
connect(&SettingsCache::instance(), &SettingsCache::themeChanged, this,
&HomeWidget::initializeBackgroundFromSource);
connect(&SettingsCache::instance(), &SettingsCache::themeChanged, this,
&HomeWidget::updateButtonsToBackgroundColor);
}
@ -256,7 +259,7 @@ void HomeWidget::updateConnectButton(const ClientStatus status)
QPair<QColor, QColor> HomeWidget::extractDominantColors(const QPixmap &pixmap)
{
if (SettingsCache::instance().getThemeName() == "Default" &&
if (themeManager->isBuiltInTheme() &&
SettingsCache::instance().getHomeTabBackgroundSource() == BackgroundSources::toId(BackgroundSources::Theme)) {
return QPair<QColor, QColor>(QColor::fromRgb(20, 140, 60), QColor::fromRgb(120, 200, 80));
}