From 0d0bca58cfd6dcdba6bb12f8f69d7b0f7d9e1b69 Mon Sep 17 00:00:00 2001 From: Benjamin Port Date: Thu, 29 Apr 2021 21:05:34 +0000 Subject: [PATCH] Change defaults for color, widget style... to match current Global Theme This commit changes what counts as the default settings to take into account the default settings of the current Global Theme. e.g. if you change the Global Theme to Breeze Dark, when you go to the color KCM, clicking the "Defaults" button will revert to the Breeze Dark color scheme (because it is the default color scheme of the active Global Theme), rather than Breeze Light. --- kcms/lookandfeel/kcm.cpp | 139 +++++++++++++++++++++++++++------------ kcms/lookandfeel/kcm.h | 8 +++ startkde/startplasma.cpp | 6 ++ 3 files changed, 111 insertions(+), 42 deletions(-) diff --git a/kcms/lookandfeel/kcm.cpp b/kcms/lookandfeel/kcm.cpp index 9ac6c7cd5..77d068dc6 100644 --- a/kcms/lookandfeel/kcm.cpp +++ b/kcms/lookandfeel/kcm.cpp @@ -2,6 +2,7 @@ Copyright (c) 2014 Marco Martin Copyright (c) 2014 Vishesh Handa Copyright (c) 2019 Cyril Rossi + Copyright (c) 2021 Benjamin Port This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -436,30 +437,53 @@ void KCMLookandFeel::setWidgetStyle(const QString &style) // Test if style can be installed before updating the config. QScopedPointer newStyle(QStyleFactory::create(style)); if (newStyle) { - m_configGroup.writeEntry("widgetStyle", style, KConfig::Notify); - m_configGroup.sync(); + writeNewDefaults(QStringLiteral("kdeglobals"), QStringLiteral("KDE"), QStringLiteral("widgetStyle"), style, KConfig::Notify); + // FIXME: changing style on the fly breaks QQuickWidgets notifyKcmChange(GlobalChangeType::StyleChanged); } } +void KCMLookandFeel::revertKeyIfNeeded(KConfigGroup &group, KConfigGroup &home, KConfigGroup &defaults) +{ + for (const QString &key : group.keyList()) { + home.revertToDefault(key); + if (m_data->isDefaults()) { + defaults.revertToDefault(key); + } + } + for (const QString &subgroupname : group.groupList()) { + KConfigGroup subgroup(group.group(subgroupname)); + KConfigGroup subgroupHome(home.group(subgroupname)); + KConfigGroup subgroupDefaults(defaults.group(subgroupname)); + revertKeyIfNeeded(subgroup, subgroupHome, subgroupDefaults); + } +} + void KCMLookandFeel::setColors(const QString &scheme, const QString &colorFile) { if (scheme.isEmpty() && colorFile.isEmpty()) { return; } - KSharedConfigPtr conf = KSharedConfig::openConfig(colorFile, KSharedConfig::CascadeConfig); - foreach (const QString &grp, conf->groupList()) { - KConfigGroup cg(conf, grp); - KConfigGroup cg2(&m_config, grp); - cg.copyTo(&cg2, KConfig::Notify); - } - KConfigGroup configGroup(&m_config, "General"); - configGroup.writeEntry("ColorScheme", scheme, KConfig::Notify); + KConfig configDefault(configDefaults("kdeglobals")); + KSharedConfigPtr colorConf = KSharedConfig::openConfig(colorFile, KSharedConfig::CascadeConfig); + if (!m_data->isDefaults()) { + colorConf->copyTo(configDefault.name(), &configDefault); + } else { + for (const QString &grp : colorConf->groupList()) { + KConfigGroup colorConfGroup(colorConf, grp); + KConfigGroup cghome(&m_config, grp); + KConfigGroup cgd(&configDefault, grp); + revertKeyIfNeeded(colorConfGroup, cghome, cgd); + colorConf->deleteGroup(grp); + } + } - configGroup.sync(); + writeNewDefaults(m_config, configDefault, QStringLiteral("General"), QStringLiteral("ColorScheme"), scheme, KConfig::Notify); + m_config.sync(); + configDefault.sync(); notifyKcmChange(GlobalChangeType::PaletteChanged); } @@ -469,9 +493,7 @@ void KCMLookandFeel::setIcons(const QString &theme) return; } - KConfigGroup cg(&m_config, "Icons"); - cg.writeEntry("Theme", theme, KConfig::Notify); - cg.sync(); + writeNewDefaults(QStringLiteral("kdeglobals"), QStringLiteral("Icons"), QStringLiteral("Theme"), theme, KConfig::Notify); for (int i = 0; i < KIconLoader::LastGroup; i++) { KIconLoader::emitChange(KIconLoader::Group(i)); @@ -484,10 +506,7 @@ void KCMLookandFeel::setPlasmaTheme(const QString &theme) return; } - KConfig config(QStringLiteral("plasmarc")); - KConfigGroup cg(&config, "Theme"); - cg.writeEntry("name", theme); - cg.sync(); + writeNewDefaults(QStringLiteral("plasmarc"), QStringLiteral("Theme"), QStringLiteral("name"), theme); } void KCMLookandFeel::setCursorTheme(const QString themeName) @@ -497,16 +516,15 @@ void KCMLookandFeel::setCursorTheme(const QString themeName) return; } - KConfig config(QStringLiteral("kcminputrc")); - KConfigGroup cg(&config, "Mouse"); - cg.writeEntry("cursorTheme", themeName, KConfig::Notify); - cg.sync(); + writeNewDefaults(QStringLiteral("kcminputrc"), QStringLiteral("Mouse"), QStringLiteral("cursorTheme"), themeName, KConfig::Notify); #ifdef HAVE_XCURSOR // Require the Xcursor version that shipped with X11R6.9 or greater, since // in previous versions the Xfixes code wasn't enabled due to a bug in the // build system (freedesktop bug #975). #if defined(HAVE_XFIXES) && XFIXES_MAJOR >= 2 && XCURSOR_LIB_VERSION >= 10105 + KConfig config(QStringLiteral("kcminputrc")); + KConfigGroup cg(&config, QStringLiteral("Mouse")); const int cursorSize = cg.readEntry("cursorSize", 24); QDir themeDir = cursorThemeDir(themeName, 0); @@ -653,11 +671,13 @@ void KCMLookandFeel::setSplashScreen(const QString &theme) } KConfig config(QStringLiteral("ksplashrc")); - KConfigGroup cg(&config, "KSplash"); - cg.writeEntry("Theme", theme); + KConfigGroup cg(&config, QStringLiteral("KSplash")); + + KConfig configDefault(configDefaults(QStringLiteral("ksplashrc"))); + KConfigGroup cgd(&configDefault, QStringLiteral("KSplash")); + writeNewDefaults(cg, cgd, QStringLiteral("Theme"), theme); // TODO: a way to set none as spash in the l&f - cg.writeEntry("Engine", "KSplashQML"); - cg.sync(); + writeNewDefaults(cg, cgd, QStringLiteral("Engine"), QStringLiteral("KSplashQML")); } void KCMLookandFeel::setLockScreen(const QString &theme) @@ -666,10 +686,7 @@ void KCMLookandFeel::setLockScreen(const QString &theme) return; } - KConfig config(QStringLiteral("kscreenlockerrc")); - KConfigGroup cg(&config, "Greeter"); - cg.writeEntry("Theme", theme); - cg.sync(); + writeNewDefaults(QStringLiteral("kscreenlockerrc"), QStringLiteral("Greeter"), QStringLiteral("Theme"), theme); } void KCMLookandFeel::setWindowSwitcher(const QString &theme) @@ -678,10 +695,7 @@ void KCMLookandFeel::setWindowSwitcher(const QString &theme) return; } - KConfig config(QStringLiteral("kwinrc")); - KConfigGroup cg(&config, "TabBox"); - cg.writeEntry("LayoutName", theme); - cg.sync(); + writeNewDefaults(QStringLiteral("kwinrc"), QStringLiteral("TabBox"), QStringLiteral("LayoutName"), theme); } void KCMLookandFeel::setDesktopSwitcher(const QString &theme) @@ -691,10 +705,12 @@ void KCMLookandFeel::setDesktopSwitcher(const QString &theme) } KConfig config(QStringLiteral("kwinrc")); - KConfigGroup cg(&config, "TabBox"); - cg.writeEntry("DesktopLayout", theme); - cg.writeEntry("DesktopListLayout", theme); - cg.sync(); + KConfigGroup cg(&config, QStringLiteral("TabBox")); + + KConfig configDefault(configDefaults(QStringLiteral("kwinrc"))); + KConfigGroup cgd(&configDefault, QStringLiteral("TabBox")); + writeNewDefaults(cg, cgd, QStringLiteral("DesktopLayout"), theme); + writeNewDefaults(cg, cgd, QStringLiteral("DesktopListLayout"), theme); } void KCMLookandFeel::setWindowDecoration(const QString &library, const QString &theme) @@ -704,11 +720,13 @@ void KCMLookandFeel::setWindowDecoration(const QString &library, const QString & } KConfig config(QStringLiteral("kwinrc")); - KConfigGroup cg(&config, "org.kde.kdecoration2"); - cg.writeEntry("library", library); - cg.writeEntry("theme", theme, KConfig::Notify); + KConfigGroup cg(&config, QStringLiteral("org.kde.kdecoration2")); + + KConfig configDefault(configDefaults(QStringLiteral("kwinrc"))); + KConfigGroup cgd(&configDefault, QStringLiteral("org.kde.kdecoration2")); + writeNewDefaults(cg, cgd, QStringLiteral("library"), library); + writeNewDefaults(cg, cgd, QStringLiteral("theme"), theme, KConfig::Notify); - cg.sync(); // Reload KWin. QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/KWin"), QStringLiteral("org.kde.KWin"), QStringLiteral("reloadConfig")); QDBusConnection::sessionBus().send(message); @@ -730,3 +748,40 @@ bool KCMLookandFeel::resetDefaultLayout() const { return m_resetDefaultLayout; } + +void KCMLookandFeel::writeNewDefaults(const QString &filename, const QString &group, const QString &key, const QString &value, KConfig::WriteConfigFlags writeFlags) +{ + KConfig config(filename); + KConfigGroup cg(&config, group); + + KConfig configDefault(configDefaults(filename)); + KConfigGroup cgd(&configDefault, group); + + writeNewDefaults(cg, cgd, key, value, writeFlags); +} + +void KCMLookandFeel::writeNewDefaults(KConfig &config, KConfig &configDefault, const QString &group, const QString &key, const QString &value, KConfig::WriteConfigFlags writeFlags) +{ + KConfigGroup cg(&config, group); + KConfigGroup cgd(&configDefault, group); + + writeNewDefaults(cg, cgd, key, value, writeFlags); +} + +void KCMLookandFeel::writeNewDefaults(KConfigGroup &cg, KConfigGroup &cgd, const QString &key, const QString &value, KConfig::WriteConfigFlags writeFlags) +{ + if (m_data->isDefaults()) { + cgd.revertToDefault(key); + } else { + cgd.writeEntry(key, value, writeFlags); + } + cgd.sync(); + + cg.revertToDefault(key, writeFlags); + cg.sync(); +} + +KConfig KCMLookandFeel::configDefaults(const QString &filename) +{ + return KConfig(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kdedefaults/" + filename, KConfig::SimpleConfig); +} diff --git a/kcms/lookandfeel/kcm.h b/kcms/lookandfeel/kcm.h index 6c64aa224..d3a7191f6 100644 --- a/kcms/lookandfeel/kcm.h +++ b/kcms/lookandfeel/kcm.h @@ -2,6 +2,7 @@ Copyright (c) 2014 Marco Martin Copyright (c) 2014 Vishesh Handa Copyright (c) 2019 Cyril Rossi + Copyright (c) 2021 Benjamin Port This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -98,6 +99,13 @@ private: QDir cursorThemeDir(const QString &theme, const int depth); const QStringList cursorSearchPaths(); + void revertKeyIfNeeded(KConfigGroup &group, KConfigGroup &home, KConfigGroup &defaults); + + void writeNewDefaults(const QString &filename, const QString &group, const QString &key, const QString &value, KConfig::WriteConfigFlags writeFlags = KConfig::Normal); + void writeNewDefaults(KConfig &config, KConfig &configDefault, const QString &group, const QString &key, const QString &value, KConfig::WriteConfigFlags writeFlags = KConfig::Normal); + void writeNewDefaults(KConfigGroup &cg, KConfigGroup &cgd, const QString &key, const QString &value, KConfig::WriteConfigFlags writeFlags = KConfig::Normal); + static KConfig configDefaults(const QString &filename); + LookAndFeelData *m_data; QStandardItemModel *m_model; KPackage::Package m_package; diff --git a/startkde/startplasma.cpp b/startkde/startplasma.cpp index f6b078e7e..c14cd9e22 100644 --- a/startkde/startplasma.cpp +++ b/startkde/startplasma.cpp @@ -323,6 +323,12 @@ void setupPlasmaEnvironment() qputenv("XDG_CURRENT_DESKTOP", "KDE"); qputenv("KDE_APPLICATIONS_AS_SCOPE", "1"); + + // Add kdedefaults dir to allow config defaults overriding from a writable location + const auto current_xdg_config_dirs = qgetenv("XDG_CONFIG_DIRS"); + const auto new_xdg_dir = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation).toUtf8() + "/kdedefaults"; + qputenv("XDG_CONFIG_DIRS", new_xdg_dir + ":" + current_xdg_config_dirs); + } void setupX11()