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:
parent
90a8563ace
commit
ec1d664b0c
6 changed files with 141 additions and 11 deletions
|
@ -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) \
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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*)
|
||||
|
|
Loading…
Add table
Reference in a new issue