Skip to content
/ qTox Public
forked from TokTok/qTox

Commit

Permalink
feat(UI): Better integration with system dark modes.
Browse files Browse the repository at this point in the history
If the OS/desktop environment have dark mode set, then qTox will select
the default dark color scheme as well.

Also, if the user sets light mode, this sets Qt to light mode as well.
This avoids conflicting style hints resulting in invisible text (dark
grey on black).
  • Loading branch information
iphydf committed Jan 2, 2025
1 parent 2c95f4d commit ff2a252
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 15 deletions.
9 changes: 5 additions & 4 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
Checks: '
-*,
readability-named-parameter,
readability-inconsistent-declaration-parameter-name'
Checks: "-*
, modernize-use-emplace
, readability-named-parameter
, readability-inconsistent-declaration-parameter-name
"
WarningsAsErrors: "*"
22 changes: 15 additions & 7 deletions src/persistence/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,17 @@

#include "settings.h"
#include "src/core/core.h"
#include "src/core/corefile.h"
#include "src/nexus.h"
#include "src/persistence/globalsettingsupgrader.h"
#include "src/persistence/personalsettingsupgrader.h"
#include "src/persistence/profile.h"
#include "src/persistence/profilelocker.h"
#include "src/persistence/settingsserializer.h"
#include "src/persistence/smileypack.h"
#include "src/widget/style.h"
#include "src/widget/tool/imessageboxmanager.h"
#ifdef QTOX_PLATFORM_EXT
#include "src/platform/autorun.h"
#endif
#include "src/ipc.h"
#include "src/widget/style.h"
#include "src/widget/tool/imessageboxmanager.h"

#include <QApplication>
#include <QCryptographicHash>
Expand All @@ -33,6 +30,7 @@
#include <QNetworkProxy>
#include <QStandardPaths>
#include <QStyleFactory>
#include <QStyleHints>
#include <QThread>
#include <QtCore/QCommandLineParser>

Expand Down Expand Up @@ -185,19 +183,29 @@ void Settings::loadGlobal()
smileyPack = DEFAULT_SMILEYS;
}

const Style::MainTheme systemTheme =
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark
#else
QGuiApplication::palette().color(QPalette::Window).value() < 128
#endif
? Style::MainTheme::Dark
: Style::MainTheme::Light;
qDebug() << "System theme:" << systemTheme;

emojiFontPointSize = s.value("emojiFontPointSize", 24).toInt();
firstColumnHandlePos = s.value("firstColumnHandlePos", 50).toInt();
secondColumnHandlePosFromRight = s.value("secondColumnHandlePosFromRight", 50).toInt();
timestampFormat = s.value("timestampFormat", "hh:mm:ss").toString();
dateFormat = s.value("dateFormat", "yyyy-MM-dd").toString();
minimizeOnClose = s.value("minimizeOnClose", false).toBool();
minimizeToTray = s.value("minimizeToTray", false).toBool();
lightTrayIcon = s.value("lightTrayIcon", false).toBool();
lightTrayIcon = s.value("lightTrayIcon", systemTheme == Style::MainTheme::Dark).toBool();
useEmoticons = s.value("useEmoticons", true).toBool();
statusChangeNotificationEnabled = s.value("statusChangeNotificationEnabled", false).toBool();
showConferenceJoinLeaveMessages = s.value("showConferenceJoinLeaveMessages", false).toBool();
spellCheckingEnabled = s.value("spellCheckingEnabled", true).toBool();
themeColor = s.value("themeColor", 0).toInt();
themeColor = s.value("themeColor", Style::defaultThemeColor(systemTheme)).toInt();
style = s.value("style", "").toString();
if (style == "") // Default to Fusion if available, otherwise no style
{
Expand Down
34 changes: 30 additions & 4 deletions src/widget/style.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
#include <QDir>
#include <QFile>
#include <QFontInfo>
#include <QGuiApplication>
#include <QMap>
#include <QPainter>
#include <QRegularExpression>
#include <QSettings>
#include <QStandardPaths>
#include <QStringBuilder>
#include <QStyle>
#include <QStyleHints>
#include <QSvgRenderer>
#include <QWidget>

Expand Down Expand Up @@ -111,6 +113,16 @@ const QMap<ColorPalette, QString> aliasColors = {
};
} // namespace

int Style::defaultThemeColor(MainTheme theme)
{
for (int i = 0; i < themeNameColors.size(); ++i) {
if (themeNameColors[i].type == theme) {
return i;
}
}
return 0;
}

QStringList Style::getThemeColorNames()
{
QStringList l;
Expand Down Expand Up @@ -279,7 +291,7 @@ const QString Style::resolve(const QString& filename, int themeColor, const QFon
qss.replace(QRegularExpression(key % QLatin1String{"\\b"}), dictTheme[key]);
}

// @getImagePath() function
// "@getImagePath()" function
const QRegularExpression re{QStringLiteral(R"(@getImagePath\([^)\s]*\))")};
QRegularExpressionMatchIterator i = re.globalMatch(qss);

Expand Down Expand Up @@ -329,10 +341,24 @@ void Style::setThemeColor(int themeColor, int color)
dictColor.clear();
initPalette(themeColor);
initDictColor();
if (color < 0 || color >= themeNameColors.size())
if (color < 0 || color >= themeNameColors.size()) {
setThemeColor(QColor());
else
setThemeColor(themeNameColors[color].color);
} else {
const auto& themeName = themeNameColors[color];

#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
switch (themeName.type) {
case MainTheme::Light:
QGuiApplication::styleHints()->setColorScheme(Qt::ColorScheme::Light);
break;
case MainTheme::Dark:
QGuiApplication::styleHints()->setColorScheme(Qt::ColorScheme::Dark);
break;
}
#endif

setThemeColor(themeName.color);
}
}

/**
Expand Down
3 changes: 3 additions & 0 deletions src/widget/style.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ class Style : public QObject
Light,
Dark
};
Q_ENUM(MainTheme)

static int defaultThemeColor(MainTheme theme);

static QStringList getThemeColorNames();
static QString getThemeFolder(int themeColor);
Expand Down

0 comments on commit ff2a252

Please sign in to comment.