File indexing completed on 2024-05-12 05:36:15
0001 // SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org> 0002 // SPDX-License-Identifier: GPL-2.0-or-later 0003 0004 #include "settings.h" 0005 #include "config.h" 0006 #include "utils.h" 0007 0008 #include <KPackage/PackageLoader> 0009 #include <KRuntimePlatform> 0010 0011 #include <QDBusConnection> 0012 #include <QDBusMessage> 0013 #include <QDebug> 0014 #include <QProcess> 0015 0016 using namespace Qt::Literals::StringLiterals; 0017 0018 const QString CONFIG_FILE = u"plasmamobilerc"_s; 0019 const QString SAVED_CONFIG_GROUP = u"SavedConfig"_s; 0020 0021 Settings::Settings(QObject *parent) 0022 : QObject{parent} 0023 , m_isMobilePlatform{KRuntimePlatform::runtimePlatform().contains(u"phone"_s)} 0024 , m_mobileConfig{KSharedConfig::openConfig(CONFIG_FILE, KConfig::SimpleConfig)} 0025 , m_kwinrcConfig{KSharedConfig::openConfig(u"kwinrc"_s, KConfig::SimpleConfig)} 0026 , m_appBlacklistConfig{KSharedConfig::openConfig(u"applications-blacklistrc"_s, KConfig::SimpleConfig)} 0027 , m_kdeglobalsConfig{KSharedConfig::openConfig(u"kdeglobals"_s, KConfig::SimpleConfig)} 0028 , m_configWatcher{KConfigWatcher::create(m_mobileConfig)} 0029 { 0030 } 0031 0032 Settings &Settings::self() 0033 { 0034 static Settings settings; 0035 return settings; 0036 } 0037 0038 void Settings::applyConfiguration() 0039 { 0040 if (!m_isMobilePlatform) { 0041 qCDebug(LOGGING_CATEGORY) << "Configuration will not be applied, as the session is not Plasma Mobile."; 0042 qCDebug(LOGGING_CATEGORY) << "Restoring any previously saved configuration..."; 0043 loadSavedConfiguration(); 0044 return; 0045 } 0046 0047 qCDebug(LOGGING_CATEGORY) << "Checking and applying mobile configuration..."; 0048 applyMobileConfiguration(); 0049 } 0050 0051 void Settings::loadSavedConfiguration() 0052 { 0053 // kwinrc 0054 loadKeys(u"kwinrc"_s, m_kwinrcConfig, getKwinrcSettings(m_mobileConfig)); 0055 m_kwinrcConfig->sync(); 0056 reloadKWinConfig(); 0057 0058 // applications-blacklistrc 0059 loadKeys(u"applications-blacklistrc"_s, m_appBlacklistConfig, APPLICATIONS_BLACKLIST_DEFAULT_SETTINGS); 0060 m_appBlacklistConfig->sync(); 0061 0062 // kdeglobals 0063 loadKeys(u"kdeglobals"_s, m_kdeglobalsConfig, KDEGLOBALS_DEFAULT_SETTINGS); 0064 loadKeys(u"kdeglobals"_s, m_kdeglobalsConfig, KDEGLOBALS_SETTINGS); 0065 m_kdeglobalsConfig->sync(); 0066 0067 // save our changes 0068 m_mobileConfig->sync(); 0069 } 0070 0071 void Settings::applyMobileConfiguration() 0072 { 0073 // kwinrc 0074 writeKeys(u"kwinrc"_s, m_kwinrcConfig, getKwinrcSettings(m_mobileConfig), false); 0075 m_kwinrcConfig->sync(); 0076 reloadKWinConfig(); 0077 0078 // applications-blacklistrc 0079 writeKeys(u"applications-blacklistrc"_s, 0080 m_appBlacklistConfig, 0081 APPLICATIONS_BLACKLIST_DEFAULT_SETTINGS, 0082 true); // only write entries if they are not already defined in the config 0083 m_appBlacklistConfig->sync(); 0084 0085 // kdeglobals 0086 writeKeys(u"kdeglobals"_s, m_kdeglobalsConfig, KDEGLOBALS_DEFAULT_SETTINGS, 0087 true); // only write entries if they are not already defined in the config 0088 writeKeys(u"kdeglobals"_s, m_kdeglobalsConfig, KDEGLOBALS_SETTINGS, false); 0089 m_kdeglobalsConfig->sync(); 0090 0091 // save our changes 0092 m_mobileConfig->sync(); 0093 } 0094 0095 void Settings::writeKeys(const QString &fileName, KSharedConfig::Ptr &config, const QMap<QString, QMap<QString, QVariant>> &settings, bool overwriteOnlyIfEmpty) 0096 { 0097 const auto groupNames = settings.keys(); 0098 for (const auto &groupName : groupNames) { 0099 auto group = KConfigGroup{config, groupName}; 0100 0101 const auto keys = settings[groupName].keys(); 0102 for (const auto &key : keys) { 0103 if (!group.hasKey(key) || !overwriteOnlyIfEmpty) { 0104 // save key 0105 saveConfigSetting(fileName, groupName, key, group.readEntry(key)); 0106 0107 // overwrite with mobile setting 0108 group.writeEntry(key, settings[groupName][key], KConfigGroup::Notify); 0109 } 0110 } 0111 } 0112 } 0113 0114 void Settings::loadKeys(const QString &fileName, KSharedConfig::Ptr &config, const QMap<QString, QMap<QString, QVariant>> &settings) 0115 { 0116 const auto groupNames = settings.keys(); 0117 for (const auto &groupName : groupNames) { 0118 const auto group = KConfigGroup{config, groupName}; 0119 0120 const auto keys = settings[groupName].keys(); 0121 for (const auto &key : keys) { 0122 loadSavedConfigSetting(config, fileName, groupName, key); 0123 } 0124 } 0125 } 0126 0127 // NOTE: this only saves a value if it hasn't already been saved 0128 void Settings::saveConfigSetting(const QString &fileName, const QString &group, const QString &key, const QVariant value) 0129 { 0130 const auto savedGroup = KConfigGroup{m_mobileConfig, SAVED_CONFIG_GROUP}; 0131 const auto fileGroup = KConfigGroup{&savedGroup, fileName}; 0132 auto keyGroup = KConfigGroup{&fileGroup, group}; 0133 0134 if (!keyGroup.hasKey(key)) { 0135 qCDebug(LOGGING_CATEGORY) << "In" << fileName << "saved" << key << "=" << value; 0136 keyGroup.writeEntry(key, value); 0137 } 0138 } 0139 0140 // NOTE: this deletes the stored value from the config after loading 0141 const QString Settings::loadSavedConfigSetting(KSharedConfig::Ptr &config, const QString &fileName, const QString &group, const QString &key, bool write) 0142 { 0143 auto savedGroup = KConfigGroup{m_mobileConfig, SAVED_CONFIG_GROUP}; 0144 auto fileGroup = KConfigGroup{&savedGroup, fileName}; 0145 auto keyGroup = KConfigGroup{&fileGroup, group}; 0146 0147 if (!keyGroup.hasKey(key)) { 0148 return {}; 0149 } 0150 0151 const auto value = keyGroup.readEntry(key); 0152 0153 // write to real config 0154 auto configGroup = KConfigGroup{config, group}; 0155 0156 if ((!configGroup.hasKey(key) || configGroup.readEntry(key) != value) && write) { 0157 qCDebug(LOGGING_CATEGORY) << "In" << fileName << "loading saved value of" << key << "which is" << value << "in" << group; 0158 0159 if (value.isEmpty()) { // delete blank entries! 0160 configGroup.deleteEntry(key); 0161 } else { 0162 configGroup.writeEntry(key, value, KConfigGroup::Notify); 0163 } 0164 } 0165 0166 // remove saved config option 0167 keyGroup.deleteEntry(key); 0168 return value; 0169 } 0170 0171 void Settings::reloadKWinConfig() 0172 { 0173 QDBusMessage message = QDBusMessage::createSignal(u"/KWin"_s, u"org.kde.KWin"_s, u"reloadConfig"_s); 0174 QDBusConnection::sessionBus().send(message); 0175 }