Fixing artifacts while changing system theme color on Windows.

This commit is contained in:
Roman Telezhynskyi 2023-08-09 19:21:04 +03:00
parent 70b527a3c9
commit d433287be7
5 changed files with 106 additions and 55 deletions

View file

@ -28,13 +28,15 @@
#include "puzzlepreferencesconfigurationpage.h"
#include "../../vpapplication.h"
#include "../vganalytics/vganalytics.h"
#include "../vmisc/theme/vtheme.h"
#include "ui_puzzlepreferencesconfigurationpage.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
#include "../vmisc/backport/qoverload.h"
#endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
#include "../vganalytics/vganalytics.h"
#include "../vmisc/theme/vtheme.h"
#include <QStyleHints>
//---------------------------------------------------------------------------------------------------------------------
PuzzlePreferencesConfigurationPage::PuzzlePreferencesConfigurationPage(QWidget *parent)
@ -119,6 +121,23 @@ auto PuzzlePreferencesConfigurationPage::Apply() -> QStringList
auto themeMode = static_cast<VThemeMode>(ui->comboBoxThemeMode->currentData().toInt());
if (settings->GetThemeMode() != themeMode)
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
if (themeMode == VThemeMode::System && VTheme::NativeDarkThemeAvailable())
{
if (QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark)
{
settings->SetThemeMode(VThemeMode::Light);
}
else
{
settings->SetThemeMode(VThemeMode::Dark);
}
VTheme::Instance()->ResetThemeSettings();
QCoreApplication::processEvents();
}
#endif
settings->SetThemeMode(themeMode);
VTheme::Instance()->ResetThemeSettings();
}

View file

@ -29,14 +29,17 @@
#include "tapepreferencesconfigurationpage.h"
#include "../../mapplication.h"
#include "../../vtapesettings.h"
#include "../vpatterndb/pmsystems.h"
#include "ui_tapepreferencesconfigurationpage.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
#include "../vmisc/backport/qoverload.h"
#endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
#include "../qmuparser/qmudef.h"
#include "../vganalytics/vganalytics.h"
#include "../vmisc/theme/vtheme.h"
#include "../vpatterndb/pmsystems.h"
#include "ui_tapepreferencesconfigurationpage.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
#include "../vmisc/backport/qoverload.h"
#endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
#include <QStyleHints>
//---------------------------------------------------------------------------------------------------------------------
TapePreferencesConfigurationPage::TapePreferencesConfigurationPage(QWidget *parent)
@ -122,6 +125,23 @@ auto TapePreferencesConfigurationPage::Apply() -> QStringList
auto themeMode = static_cast<VThemeMode>(ui->comboBoxThemeMode->currentData().toInt());
if (settings->GetThemeMode() != themeMode)
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
if (themeMode == VThemeMode::System && VTheme::NativeDarkThemeAvailable())
{
if (QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark)
{
settings->SetThemeMode(VThemeMode::Light);
}
else
{
settings->SetThemeMode(VThemeMode::Dark);
}
VTheme::Instance()->ResetThemeSettings();
QCoreApplication::processEvents();
}
#endif
settings->SetThemeMode(themeMode);
VTheme::Instance()->ResetThemeSettings();
}

View file

@ -28,20 +28,22 @@
#include "preferencesconfigurationpage.h"
#include "../../core/vapplication.h"
#include "../qmuparser/qmudef.h"
#include "../vganalytics/vganalytics.h"
#include "../vmisc/literals.h"
#include "../vmisc/theme/vtheme.h"
#include "../vmisc/vvalentinasettings.h"
#include "../vpatterndb/pmsystems.h"
#include "theme/vtheme.h"
#include "ui_preferencesconfigurationpage.h"
#include "vcommonsettings.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
#include "../vmisc/backport/qoverload.h"
#endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
#include "../qmuparser/qmudef.h"
#include "../vganalytics/vganalytics.h"
#include <QDir>
#include <QDirIterator>
#include <QStyleHints>
#include <QTimer>
//---------------------------------------------------------------------------------------------------------------------
@ -197,6 +199,23 @@ auto PreferencesConfigurationPage::Apply() -> QStringList
auto themeMode = static_cast<VThemeMode>(ui->comboBoxThemeMode->currentData().toInt());
if (settings->GetThemeMode() != themeMode)
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
if (themeMode == VThemeMode::System && VTheme::NativeDarkThemeAvailable())
{
if (QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark)
{
settings->SetThemeMode(VThemeMode::Light);
}
else
{
settings->SetThemeMode(VThemeMode::Dark);
}
VTheme::Instance()->ResetThemeSettings();
QCoreApplication::processEvents();
}
#endif
settings->SetThemeMode(themeMode);
VTheme::Instance()->ResetThemeSettings();
}

View file

@ -280,11 +280,20 @@ auto VTheme::IsInDarkTheme() -> bool
{
if (NativeDarkThemeAvailable())
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
QStyleHints *hints = QGuiApplication::styleHints();
return hints->colorScheme() == Qt::ColorScheme::Dark;
#else
#if defined(Q_OS_MACX)
return NSMacIsInDarkTheme();
#else
#elif defined(Q_OS_WIN)
QSettings settings("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
QSettings::NativeFormat);
return settings.value("AppsUseLightTheme", 1).toInt() == 0;
#elif defined(Q_OS_LINUX)
return ShouldApplyDarkTheme();
#endif
#endif // QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
}
return false;
@ -353,11 +362,8 @@ void VTheme::InitApplicationStyle()
QStyle *style = QStyleFactory::create(QStringLiteral("fusion"));
if (style != nullptr)
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast)
Instance()->SetDefaultApplicationStyle(qApp->style());
style = new VApplicationStyle(style);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast)
qApp->setStyle(style);
QApplication::setStyle(style);
}
return;
@ -369,14 +375,7 @@ void VTheme::InitApplicationStyle()
{
if (QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark)
{
QStyle *style = QStyleFactory::create(QStringLiteral("fusion"));
if (style != nullptr)
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast)
Instance()->SetDefaultApplicationStyle(qApp->style());
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast)
qApp->setStyle(style);
}
QApplication::setStyle(QStyleFactory::create(QStringLiteral("fusion")));
}
}
#endif
@ -538,9 +537,8 @@ auto VTheme::ThemeStylesheet() -> QString
//---------------------------------------------------------------------------------------------------------------------
void VTheme::ResetThemeSettings() const
{
qApp->setStyle(Instance()->GetDefaultApplicationStyle());
SetToAutoTheme();
InitApplicationStyle();
SetToAutoTheme();
SetIconTheme();
InitThemeMode();
VSceneStylesheet::ResetStyles();
@ -597,7 +595,29 @@ VTheme::VTheme(QObject *parent)
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
QStyleHints *hints = QGuiApplication::styleHints();
connect(hints, &QStyleHints::colorSchemeChanged, this, []() { VTheme::Instance()->ResetThemeSettings(); });
connect(hints, &QStyleHints::colorSchemeChanged, this,
[this]()
{
VCommonSettings *settings = VAbstractApplication::VApp()->Settings();
VThemeMode themeMode = settings->GetThemeMode();
if (themeMode == VThemeMode::System && VTheme::NativeDarkThemeAvailable())
{
if (QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark)
{
settings->SetThemeMode(VThemeMode::Light);
}
else
{
settings->SetThemeMode(VThemeMode::Dark);
}
ResetThemeSettings();
QCoreApplication::processEvents();
settings->SetThemeMode(themeMode);
}
ResetThemeSettings();
});
#else
if (VTheme::NativeDarkThemeAvailable())
{
@ -611,33 +631,10 @@ VTheme::VTheme(QObject *parent)
if (m_darkTheme != darkTheme)
{
m_darkTheme = darkTheme;
VTheme::Instance()->ResetThemeSettings();
ResetThemeSettings();
}
});
m_themeTimer->start(V_SECONDS(5));
}
#endif
}
//---------------------------------------------------------------------------------------------------------------------
auto VTheme::GetDefaultApplicationStyle() const -> QStyle *
{
return m_defaultApplicationStyle;
}
//---------------------------------------------------------------------------------------------------------------------
void VTheme::SetDefaultApplicationStyle(QStyle *defaultApplicationStyle)
{
QStyle *old = m_defaultApplicationStyle;
m_defaultApplicationStyle = defaultApplicationStyle;
if (m_defaultApplicationStyle)
{
m_defaultApplicationStyle->setParent(this);
}
if (old && old->parent() == this)
{
delete old;
}
#endif // QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
}

View file

@ -82,14 +82,10 @@ private:
explicit VTheme(QObject *parent = nullptr);
QString m_defaultThemeName{};
QStyle *m_defaultApplicationStyle{nullptr};
#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0)
QTimer *m_themeTimer{nullptr};
bool m_darkTheme{false};
#endif
auto GetDefaultApplicationStyle() const -> QStyle *;
void SetDefaultApplicationStyle(QStyle *defaultApplicationStyle);
};
#endif // VTHEME_H