diff --git a/kcmkwin/common/effectmodel.h b/kcmkwin/common/effectmodel.h --- a/kcmkwin/common/effectmodel.h +++ b/kcmkwin/common/effectmodel.h @@ -159,12 +159,23 @@ **/ void updateEffectStatus(const QModelIndex &rowIndex, Status effectState); + /** + * This enum type is used to specify load options. + **/ + enum class LoadOptions { + None, + /** + * Do not discard unsaved changes when reloading the model. + **/ + KeepDirty + }; + /** * Loads effects. * * You have to call this method in order to populate the model. **/ - void load(); + void load(LoadOptions options = LoadOptions::None); /** * Saves status of each modified effect. @@ -240,10 +251,8 @@ void loadBuiltInEffects(const KConfigGroup &kwinConfig, const KPluginInfo::List &configs); void loadJavascriptEffects(const KConfigGroup &kwinConfig); void loadPluginEffects(const KConfigGroup &kwinConfig, const KPluginInfo::List &configs); - void syncEffectsToKWin(); QVector m_effectsList; - QVector m_effectsChanged; Q_DISABLE_COPY(EffectModel) }; diff --git a/kcmkwin/common/effectmodel.cpp b/kcmkwin/common/effectmodel.cpp --- a/kcmkwin/common/effectmodel.cpp +++ b/kcmkwin/common/effectmodel.cpp @@ -387,18 +387,37 @@ } } -void EffectModel::load() +void EffectModel::load(LoadOptions options) { KConfigGroup kwinConfig(KSharedConfig::openConfig("kwinrc"), "Plugins"); + const QVector oldEffects = m_effectsList; + beginResetModel(); - m_effectsChanged.clear(); m_effectsList.clear(); const KPluginInfo::List configs = KPluginTrader::self()->query(QStringLiteral("kwin/effects/configs/")); loadBuiltInEffects(kwinConfig, configs); loadJavascriptEffects(kwinConfig); loadPluginEffects(kwinConfig, configs); + if (options == LoadOptions::KeepDirty) { + for (const EffectData &oldEffect : oldEffects) { + if (!oldEffect.changed) { + continue; + } + auto effectIt = std::find_if(m_effectsList.begin(), m_effectsList.end(), + [serviceName = oldEffect.serviceName](const EffectData &data) { + return data.serviceName == serviceName; + } + ); + if (effectIt == m_effectsList.end()) { + continue; + } + effectIt->effectStatus = oldEffect.effectStatus; + effectIt->changed = effectIt->effectStatus != effectIt->originalStatus; + } + } + qSort(m_effectsList.begin(), m_effectsList.end(), [](const EffectData &a, const EffectData &b) { if (a.category == b.category) { if (a.exclusiveGroup == b.exclusiveGroup) { @@ -451,29 +470,9 @@ }); } - m_effectsChanged = m_effectsList; endResetModel(); } -void EffectModel::syncEffectsToKWin() -{ - OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"), - QStringLiteral("/Effects"), - QDBusConnection::sessionBus()); - for (int it = 0; it < m_effectsList.size(); it++) { - if (m_effectsList.at(it).effectStatus == m_effectsChanged.at(it).effectStatus) { - continue; - } - if (m_effectsList.at(it).effectStatus != Status::Disabled) { - interface.loadEffect(m_effectsList.at(it).serviceName); - } else { - interface.unloadEffect(m_effectsList.at(it).serviceName); - } - } - - m_effectsChanged = m_effectsList; -} - void EffectModel::updateEffectStatus(const QModelIndex &rowIndex, Status effectState) { setData(rowIndex, static_cast(effectState), EffectModel::EffectStatusRole); @@ -483,11 +482,13 @@ { KConfigGroup kwinConfig(KSharedConfig::openConfig("kwinrc"), "Plugins"); - for (auto it = m_effectsList.begin(); it != m_effectsList.end(); it++) { - EffectData &effect = *(it); + QVector dirtyEffects; + + for (EffectData &effect : m_effectsList) { if (!effect.changed) { continue; } + effect.changed = false; effect.originalStatus = effect.effectStatus; @@ -501,10 +502,31 @@ } else { kwinConfig.writeEntry(key, shouldEnable); } + + dirtyEffects.append(effect); + } + + if (dirtyEffects.isEmpty()) { + return; } kwinConfig.sync(); - syncEffectsToKWin(); + + OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"), + QStringLiteral("/Effects"), + QDBusConnection::sessionBus()); + + if (!interface.isValid()) { + return; + } + + for (const EffectData &effect : dirtyEffects) { + if (effect.effectStatus != Status::Disabled) { + interface.loadEffect(effect.serviceName); + } else { + interface.unloadEffect(effect.serviceName); + } + } } void EffectModel::defaults() diff --git a/kcmkwin/kwineffects/kcm.cpp b/kcmkwin/kwineffects/kcm.cpp --- a/kcmkwin/kwineffects/kcm.cpp +++ b/kcmkwin/kwineffects/kcm.cpp @@ -93,7 +93,7 @@ if (dialog->exec() == QDialog::Accepted) { if (!dialog->changedEntries().isEmpty()) { - m_model->load(); + m_model->load(EffectModel::LoadOptions::KeepDirty); } }