1
0
Fork 0
mirror of https://git.jami.net/savoirfairelinux/jami-client-qt.git synced 2025-08-10 01:35:40 +02:00

gnulinux: add support for system theme

Use 'color-scheme' from gsettings if available to check if dark theme
is preferred.  Otherwise, fall back on theme name from 'gtk-theme'.

The default is to follow the system theme (if supported), and
'EnableDarkTheme' would be unused.  'AppTheme' can currently have
one of three values: 'System', 'Dark', 'Light'.

Change-Id: I8008c8fe0f4750c97e71838fff0031f80b685f5e
GitLab: #723
This commit is contained in:
Sébastien Blin 2022-08-25 17:02:14 -04:00
parent 90a8563ace
commit ec1d664b0c
6 changed files with 141 additions and 11 deletions

View file

@ -45,6 +45,7 @@ extern const QString defaultDownloadPath;
X(DisplayHyperlinkPreviews, true) \
X(EnableExperimentalSwarm, false) \
X(EnableDarkTheme, false) \
X(AppTheme, "System") \
X(BaseZoom, 1.0) \
X(ParticipantsSide, false) \
X(HideSelf, false) \

View file

@ -422,9 +422,11 @@ Item {
// SystemSettings
property string system: qsTr("System")
property string dark: qsTr("Dark")
property string light: qsTr("Light")
property string selectFolder: qsTr("Select a folder")
property string enableNotifications: qsTr("Enable notifications")
property string enableDarkTheme: qsTr("Enable dark theme")
property string applicationTheme: qsTr("Application theme")
property string enableDesktopNotifications: qsTr("Enable desktop notifications")
property string keepMinimized: qsTr("Keep minimized on close")
property string tipRunStartup: qsTr("Run application on system startup")

View file

@ -25,7 +25,7 @@ import net.jami.Adapters 1.1
import net.jami.Enums 1.1
Item {
property bool darkTheme: UtilsAdapter.getAppValue(Settings.EnableDarkTheme)
property bool darkTheme: UtilsAdapter.useApplicationTheme()
Connections {
target: UtilsAdapter
@ -33,6 +33,10 @@ Item {
function onChangeFontSize() {
baseZoom = UtilsAdapter.getAppValue(Settings.BaseZoom)
}
function onAppThemeChanged() {
darkTheme = UtilsAdapter.useApplicationTheme()
}
}
// Jami theme colors

View file

@ -64,21 +64,53 @@ ColumnLayout {
verticalAlignment: Text.AlignVCenter
}
ToggleSwitch {
id: darkThemeCheckBox
SettingsComboBox {
id: themeComboBoxSettings
Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize
checked: UtilsAdapter.getAppValue(Settings.EnableDarkTheme)
labelText: JamiStrings.enableDarkTheme
labelText: JamiStrings.applicationTheme
fontPointSize: JamiTheme.settingsFontSize
tooltipText: JamiStrings.enableDarkTheme
comboModel: ListModel {
Component.onCompleted: {
append({ textDisplay: JamiStrings.dark })
append({ textDisplay: JamiStrings.light })
if (UtilsAdapter.hasNativeDarkTheme())
append({ textDisplay: JamiStrings.system })
}
}
widthOfComboBox: itemWidth
tipText: JamiStrings.selectAudioInputDevice
role: "textDisplay"
onSwitchToggled: {
JamiTheme.setTheme(checked)
UtilsAdapter.setAppValue(Settings.Key.EnableDarkTheme, checked)
modelIndex: {
if (UtilsAdapter.hasNativeDarkTheme()) {
var theme = UtilsAdapter.getAppValue(Settings.Key.AppTheme)
if (theme === "Dark") {
return 0
} else if (theme === "Light") {
return 1
}
return 2
}
return UtilsAdapter.getAppValue(Settings.Key.EnableDarkTheme) ? 0 : 1
}
onActivated: {
if (UtilsAdapter.hasNativeDarkTheme()) {
if (modelIndex === 0)
UtilsAdapter.setAppValue(Settings.Key.AppTheme, "Dark")
else if (modelIndex === 1)
UtilsAdapter.setAppValue(Settings.Key.AppTheme, "Light")
else if (modelIndex === 2)
UtilsAdapter.setAppValue(Settings.Key.AppTheme, "System")
} else {
UtilsAdapter.setAppValue(Settings.Key.EnableDarkTheme, modelIndex === 0)
}
}
}

View file

@ -375,6 +375,8 @@ UtilsAdapter::setAppValue(const Settings::Key key, const QVariant& value)
Q_EMIT changeFontSize();
else if (key == Settings::Key::ShowChatviewHorizontally)
Q_EMIT chatviewPositionChanged();
else if (key == Settings::Key::AppTheme)
Q_EMIT appThemeChanged();
}
QString
@ -584,3 +586,72 @@ UtilsAdapter::luma(const QColor& color) const
return (0.2126 * color.red() + 0.7152 * color.green() + 0.0722 * color.blue())
< 153 /* .6 * 256 */;
}
#if __has_include(<gio/gio.h>)
void
settingsCallback(GSettings* self, gchar* key, gpointer user_data)
{
QString keyString = key;
if (keyString == "color-scheme" || keyString == "gtk-theme") {
Q_EMIT((UtilsAdapter*) (user_data))->appThemeChanged();
}
}
#endif
bool
UtilsAdapter::isSystemThemeDark()
{
#if __has_include(<gio/gio.h>)
if (!settings) {
settings = g_settings_new("org.gnome.desktop.interface");
if (!settings)
return false;
g_signal_connect(settings, "changed", G_CALLBACK(settingsCallback), this);
}
if (!schema) {
g_object_get(settings, "settings-schema", &schema, nullptr);
if (!schema)
return false;
}
std::vector<std::string> keys = {"gtk-color-scheme", "color-scheme", "gtk-theme"};
auto** gtk_keys = g_settings_schema_list_keys(schema);
for (const auto& key : keys) {
auto hasKey = false;
for (int i = 0; gtk_keys[i]; i++) {
if (key == gtk_keys[i]) {
hasKey = true;
break;
}
}
if (hasKey) {
if (auto* valueCstr = g_settings_get_string(settings, key.c_str())) {
QString value = valueCstr;
if (!value.isEmpty()) {
return value.contains("dark", Qt::CaseInsensitive)
|| value.contains("black", Qt::CaseInsensitive);
}
}
}
}
return false;
#else
qWarning("System theme detection is not implemented");
return false;
#endif
}
bool
UtilsAdapter::useApplicationTheme()
{
if (hasNativeDarkTheme()) {
QString theme = getAppValue(Settings::Key::AppTheme).toString();
if (theme == "Dark")
return true;
else if (theme == "Light")
return false;
return isSystemThemeDark();
}
bool enableDark = getAppValue(Settings::Key::EnableDarkTheme).toBool();
setAppValue(Settings::Key::AppTheme, enableDark ? "Dark" : "Light");
return enableDark;
}

View file

@ -29,6 +29,10 @@
#include "appsettingsmanager.h"
#include "qtutils.h"
#if __has_include(<gio/gio.h>)
#include <gio/gio.h>
#endif
class QClipboard;
class SystemTray;
@ -107,12 +111,22 @@ public:
const QString& convId,
const QString& uri);
Q_INVOKABLE bool luma(const QColor& color) const;
Q_INVOKABLE bool useApplicationTheme();
Q_INVOKABLE bool hasNativeDarkTheme() const
{
#if __has_include(<gio/gio.h>)
return true;
#else
return false;
#endif
}
Q_SIGNALS:
void debugMessageReceived(const QString& message);
void showExperimentalSwarm();
void changeFontSize();
void chatviewPositionChanged();
void appThemeChanged();
private:
QClipboard* clipboard_;
@ -121,5 +135,11 @@ private:
QMetaObject::Connection debugMessageReceivedConnection_;
QString getDefaultRecordPath() const;
bool isSystemThemeDark();
#if __has_include(<gio/gio.h>)
GSettings* settings {nullptr};
GSettingsSchema* schema {nullptr};
#endif
};
Q_DECLARE_METATYPE(UtilsAdapter*)