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 "puzzlepreferencesconfigurationpage.h"
#include "../../vpapplication.h" #include "../../vpapplication.h"
#include "../vganalytics/vganalytics.h"
#include "../vmisc/theme/vtheme.h"
#include "ui_puzzlepreferencesconfigurationpage.h" #include "ui_puzzlepreferencesconfigurationpage.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
#include "../vmisc/backport/qoverload.h" #include "../vmisc/backport/qoverload.h"
#endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0) #endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
#include "../vganalytics/vganalytics.h" #include <QStyleHints>
#include "../vmisc/theme/vtheme.h"
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
PuzzlePreferencesConfigurationPage::PuzzlePreferencesConfigurationPage(QWidget *parent) PuzzlePreferencesConfigurationPage::PuzzlePreferencesConfigurationPage(QWidget *parent)
@ -119,6 +121,23 @@ auto PuzzlePreferencesConfigurationPage::Apply() -> QStringList
auto themeMode = static_cast<VThemeMode>(ui->comboBoxThemeMode->currentData().toInt()); auto themeMode = static_cast<VThemeMode>(ui->comboBoxThemeMode->currentData().toInt());
if (settings->GetThemeMode() != themeMode) 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); settings->SetThemeMode(themeMode);
VTheme::Instance()->ResetThemeSettings(); VTheme::Instance()->ResetThemeSettings();
} }

View file

@ -29,14 +29,17 @@
#include "tapepreferencesconfigurationpage.h" #include "tapepreferencesconfigurationpage.h"
#include "../../mapplication.h" #include "../../mapplication.h"
#include "../../vtapesettings.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 "../qmuparser/qmudef.h"
#include "../vganalytics/vganalytics.h" #include "../vganalytics/vganalytics.h"
#include "../vmisc/theme/vtheme.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) TapePreferencesConfigurationPage::TapePreferencesConfigurationPage(QWidget *parent)
@ -122,6 +125,23 @@ auto TapePreferencesConfigurationPage::Apply() -> QStringList
auto themeMode = static_cast<VThemeMode>(ui->comboBoxThemeMode->currentData().toInt()); auto themeMode = static_cast<VThemeMode>(ui->comboBoxThemeMode->currentData().toInt());
if (settings->GetThemeMode() != themeMode) 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); settings->SetThemeMode(themeMode);
VTheme::Instance()->ResetThemeSettings(); VTheme::Instance()->ResetThemeSettings();
} }

View file

@ -28,20 +28,22 @@
#include "preferencesconfigurationpage.h" #include "preferencesconfigurationpage.h"
#include "../../core/vapplication.h" #include "../../core/vapplication.h"
#include "../qmuparser/qmudef.h"
#include "../vganalytics/vganalytics.h"
#include "../vmisc/literals.h" #include "../vmisc/literals.h"
#include "../vmisc/theme/vtheme.h"
#include "../vmisc/vvalentinasettings.h" #include "../vmisc/vvalentinasettings.h"
#include "../vpatterndb/pmsystems.h" #include "../vpatterndb/pmsystems.h"
#include "theme/vtheme.h"
#include "ui_preferencesconfigurationpage.h" #include "ui_preferencesconfigurationpage.h"
#include "vcommonsettings.h" #include "vcommonsettings.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
#include "../vmisc/backport/qoverload.h" #include "../vmisc/backport/qoverload.h"
#endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0) #endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
#include "../qmuparser/qmudef.h"
#include "../vganalytics/vganalytics.h"
#include <QDir> #include <QDir>
#include <QDirIterator> #include <QDirIterator>
#include <QStyleHints>
#include <QTimer> #include <QTimer>
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -197,6 +199,23 @@ auto PreferencesConfigurationPage::Apply() -> QStringList
auto themeMode = static_cast<VThemeMode>(ui->comboBoxThemeMode->currentData().toInt()); auto themeMode = static_cast<VThemeMode>(ui->comboBoxThemeMode->currentData().toInt());
if (settings->GetThemeMode() != themeMode) 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); settings->SetThemeMode(themeMode);
VTheme::Instance()->ResetThemeSettings(); VTheme::Instance()->ResetThemeSettings();
} }

View file

@ -280,11 +280,20 @@ auto VTheme::IsInDarkTheme() -> bool
{ {
if (NativeDarkThemeAvailable()) 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) #if defined(Q_OS_MACX)
return NSMacIsInDarkTheme(); 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(); return ShouldApplyDarkTheme();
#endif #endif
#endif // QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
} }
return false; return false;
@ -353,11 +362,8 @@ void VTheme::InitApplicationStyle()
QStyle *style = QStyleFactory::create(QStringLiteral("fusion")); QStyle *style = QStyleFactory::create(QStringLiteral("fusion"));
if (style != nullptr) if (style != nullptr)
{ {
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast)
Instance()->SetDefaultApplicationStyle(qApp->style());
style = new VApplicationStyle(style); style = new VApplicationStyle(style);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast) QApplication::setStyle(style);
qApp->setStyle(style);
} }
return; return;
@ -369,14 +375,7 @@ void VTheme::InitApplicationStyle()
{ {
if (QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark) if (QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark)
{ {
QStyle *style = QStyleFactory::create(QStringLiteral("fusion")); QApplication::setStyle(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);
}
} }
} }
#endif #endif
@ -538,9 +537,8 @@ auto VTheme::ThemeStylesheet() -> QString
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VTheme::ResetThemeSettings() const void VTheme::ResetThemeSettings() const
{ {
qApp->setStyle(Instance()->GetDefaultApplicationStyle());
SetToAutoTheme();
InitApplicationStyle(); InitApplicationStyle();
SetToAutoTheme();
SetIconTheme(); SetIconTheme();
InitThemeMode(); InitThemeMode();
VSceneStylesheet::ResetStyles(); VSceneStylesheet::ResetStyles();
@ -597,7 +595,29 @@ VTheme::VTheme(QObject *parent)
{ {
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
QStyleHints *hints = QGuiApplication::styleHints(); 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 #else
if (VTheme::NativeDarkThemeAvailable()) if (VTheme::NativeDarkThemeAvailable())
{ {
@ -611,33 +631,10 @@ VTheme::VTheme(QObject *parent)
if (m_darkTheme != darkTheme) if (m_darkTheme != darkTheme)
{ {
m_darkTheme = darkTheme; m_darkTheme = darkTheme;
VTheme::Instance()->ResetThemeSettings(); ResetThemeSettings();
} }
}); });
m_themeTimer->start(V_SECONDS(5)); m_themeTimer->start(V_SECONDS(5));
} }
#endif #endif // QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
}
//---------------------------------------------------------------------------------------------------------------------
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;
}
} }

View file

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