Changeset View
Changeset View
Standalone View
Standalone View
kcmkwin/common/effectsmodel.cpp
Show First 20 Lines • Show All 263 Lines • ▼ Show 20 Line(s) | 234 | for (auto builtin : builtins) { | |||
---|---|---|---|---|---|
264 | 264 | | |||
265 | effect.configurable = std::any_of(configs.constBegin(), configs.constEnd(), | 265 | effect.configurable = std::any_of(configs.constBegin(), configs.constEnd(), | ||
266 | [data](const KPluginInfo &info) { | 266 | [data](const KPluginInfo &info) { | ||
267 | return info.property(QStringLiteral("X-KDE-ParentComponents")).toString() == data.name; | 267 | return info.property(QStringLiteral("X-KDE-ParentComponents")).toString() == data.name; | ||
268 | } | 268 | } | ||
269 | ); | 269 | ); | ||
270 | 270 | | |||
271 | if (shouldStore(effect)) { | 271 | if (shouldStore(effect)) { | ||
272 | m_effects << effect; | 272 | m_pendingEffects << effect; | ||
273 | } | 273 | } | ||
274 | } | 274 | } | ||
275 | } | 275 | } | ||
276 | 276 | | |||
277 | void EffectsModel::loadJavascriptEffects(const KConfigGroup &kwinConfig) | 277 | void EffectsModel::loadJavascriptEffects(const KConfigGroup &kwinConfig) | ||
278 | { | 278 | { | ||
279 | const auto plugins = KPackage::PackageLoader::self()->listPackages( | 279 | const auto plugins = KPackage::PackageLoader::self()->listPackages( | ||
280 | QStringLiteral("KWin/Effect"), | 280 | QStringLiteral("KWin/Effect"), | ||
Show All 28 Lines | 283 | for (const KPluginMetaData &metaData : plugins) { | |||
309 | if (!pluginKeyword.isEmpty()) { | 309 | if (!pluginKeyword.isEmpty()) { | ||
310 | // scripted effects have their pluginName() as the keyword | 310 | // scripted effects have their pluginName() as the keyword | ||
311 | effect.configurable = plugin.property(QStringLiteral("X-KDE-ParentComponents")).toString() == pluginKeyword; | 311 | effect.configurable = plugin.property(QStringLiteral("X-KDE-ParentComponents")).toString() == pluginKeyword; | ||
312 | } else { | 312 | } else { | ||
313 | effect.configurable = false; | 313 | effect.configurable = false; | ||
314 | } | 314 | } | ||
315 | 315 | | |||
316 | if (shouldStore(effect)) { | 316 | if (shouldStore(effect)) { | ||
317 | m_effects << effect; | 317 | m_pendingEffects << effect; | ||
318 | } | 318 | } | ||
319 | } | 319 | } | ||
320 | } | 320 | } | ||
321 | 321 | | |||
322 | void EffectsModel::loadPluginEffects(const KConfigGroup &kwinConfig, const KPluginInfo::List &configs) | 322 | void EffectsModel::loadPluginEffects(const KConfigGroup &kwinConfig, const KPluginInfo::List &configs) | ||
323 | { | 323 | { | ||
324 | const auto pluginEffects = KPluginLoader::findPlugins( | 324 | const auto pluginEffects = KPluginLoader::findPlugins( | ||
325 | QStringLiteral("kwin/effects/plugins/"), | 325 | QStringLiteral("kwin/effects/plugins/"), | ||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Line(s) | 330 | for (const KPluginMetaData &pluginEffect : pluginEffects) { | |||
377 | 377 | | |||
378 | effect.configurable = std::any_of(configs.constBegin(), configs.constEnd(), | 378 | effect.configurable = std::any_of(configs.constBegin(), configs.constEnd(), | ||
379 | [pluginEffect](const KPluginInfo &info) { | 379 | [pluginEffect](const KPluginInfo &info) { | ||
380 | return info.property(QStringLiteral("X-KDE-ParentComponents")).toString() == pluginEffect.pluginId(); | 380 | return info.property(QStringLiteral("X-KDE-ParentComponents")).toString() == pluginEffect.pluginId(); | ||
381 | } | 381 | } | ||
382 | ); | 382 | ); | ||
383 | 383 | | |||
384 | if (shouldStore(effect)) { | 384 | if (shouldStore(effect)) { | ||
385 | m_effects << effect; | 385 | m_pendingEffects << effect; | ||
386 | } | 386 | } | ||
387 | } | 387 | } | ||
388 | } | 388 | } | ||
389 | 389 | | |||
390 | void EffectsModel::load(LoadOptions options) | 390 | void EffectsModel::load(LoadOptions options) | ||
391 | { | 391 | { | ||
392 | KConfigGroup kwinConfig(KSharedConfig::openConfig("kwinrc"), "Plugins"); | 392 | KConfigGroup kwinConfig(KSharedConfig::openConfig("kwinrc"), "Plugins"); | ||
393 | 393 | | |||
394 | const QVector<EffectData> oldEffects = m_effects; | 394 | m_pendingEffects.clear(); | ||
395 | | ||||
396 | beginResetModel(); | | |||
397 | m_effects.clear(); | | |||
398 | const KPluginInfo::List configs = KPluginTrader::self()->query(QStringLiteral("kwin/effects/configs/")); | 395 | const KPluginInfo::List configs = KPluginTrader::self()->query(QStringLiteral("kwin/effects/configs/")); | ||
399 | loadBuiltInEffects(kwinConfig, configs); | 396 | loadBuiltInEffects(kwinConfig, configs); | ||
400 | loadJavascriptEffects(kwinConfig); | 397 | loadJavascriptEffects(kwinConfig); | ||
401 | loadPluginEffects(kwinConfig, configs); | 398 | loadPluginEffects(kwinConfig, configs); | ||
402 | 399 | | |||
400 | qSort(m_pendingEffects.begin(), m_pendingEffects.end(), | ||||
401 | [](const EffectData &a, const EffectData &b) { | ||||
402 | if (a.category == b.category) { | ||||
403 | if (a.exclusiveGroup == b.exclusiveGroup) { | ||||
404 | return a.name < b.name; | ||||
405 | } | ||||
406 | return a.exclusiveGroup < b.exclusiveGroup; | ||||
407 | } | ||||
408 | return a.category < b.category; | ||||
409 | } | ||||
410 | ); | ||||
411 | | ||||
412 | auto commit = [this, options] { | ||||
403 | if (options == LoadOptions::KeepDirty) { | 413 | if (options == LoadOptions::KeepDirty) { | ||
404 | for (const EffectData &oldEffect : oldEffects) { | 414 | for (const EffectData &oldEffect : m_effects) { | ||
405 | if (!oldEffect.changed) { | 415 | if (!oldEffect.changed) { | ||
406 | continue; | 416 | continue; | ||
407 | } | 417 | } | ||
408 | auto effectIt = std::find_if(m_effects.begin(), m_effects.end(), | 418 | auto effectIt = std::find_if(m_pendingEffects.begin(), m_pendingEffects.end(), | ||
409 | [serviceName = oldEffect.serviceName](const EffectData &data) { | 419 | [oldEffect](const EffectData &data) { | ||
410 | return data.serviceName == serviceName; | 420 | return data.serviceName == oldEffect.serviceName; | ||
411 | } | 421 | } | ||
412 | ); | 422 | ); | ||
413 | if (effectIt == m_effects.end()) { | 423 | if (effectIt == m_pendingEffects.end()) { | ||
414 | continue; | 424 | continue; | ||
415 | } | 425 | } | ||
416 | effectIt->status = oldEffect.status; | 426 | effectIt->status = oldEffect.status; | ||
417 | effectIt->changed = effectIt->status != effectIt->originalStatus; | 427 | effectIt->changed = effectIt->status != effectIt->originalStatus; | ||
418 | } | 428 | } | ||
419 | } | 429 | } | ||
420 | 430 | | |||
421 | qSort(m_effects.begin(), m_effects.end(), [](const EffectData &a, const EffectData &b) { | 431 | beginResetModel(); | ||
422 | if (a.category == b.category) { | 432 | m_effects = m_pendingEffects; | ||
423 | if (a.exclusiveGroup == b.exclusiveGroup) { | 433 | m_pendingEffects.clear(); | ||
424 | return a.name < b.name; | 434 | endResetModel(); | ||
425 | } | 435 | | ||
426 | return a.exclusiveGroup < b.exclusiveGroup; | 436 | emit loaded(); | ||
427 | } | 437 | }; | ||
428 | return a.category < b.category; | | |||
429 | }); | | |||
430 | 438 | | |||
431 | OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"), | 439 | OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"), | ||
432 | QStringLiteral("/Effects"), | 440 | QStringLiteral("/Effects"), | ||
433 | QDBusConnection::sessionBus()); | 441 | QDBusConnection::sessionBus()); | ||
434 | 442 | | |||
435 | if (interface.isValid()) { | 443 | if (interface.isValid()) { | ||
436 | QStringList effectNames; | 444 | QStringList effectNames; | ||
437 | effectNames.reserve(m_effects.count()); | 445 | effectNames.reserve(m_pendingEffects.count()); | ||
438 | for (const EffectData &data : m_effects) { | 446 | for (const EffectData &data : m_pendingEffects) { | ||
439 | effectNames.append(data.serviceName); | 447 | effectNames.append(data.serviceName); | ||
440 | } | 448 | } | ||
441 | 449 | | |||
450 | const int serial = ++m_lastSerial; | ||||
451 | | ||||
442 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(interface.areEffectsSupported(effectNames), this); | 452 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(interface.areEffectsSupported(effectNames), this); | ||
443 | watcher->setProperty("effectNames", effectNames); | 453 | connect(watcher, &QDBusPendingCallWatcher::finished, this, | ||
444 | connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher *self) { | 454 | [=](QDBusPendingCallWatcher *self) { | ||
445 | const QStringList effectNames = self->property("effectNames").toStringList(); | 455 | self->deleteLater(); | ||
456 | | ||||
457 | if (m_lastSerial != serial) { | ||||
458 | return; | ||||
459 | } | ||||
460 | | ||||
446 | const QDBusPendingReply<QList<bool > > reply = *self; | 461 | const QDBusPendingReply<QList<bool > > reply = *self; | ||
447 | QList<bool> supportValues; | 462 | if (reply.isError()) { | ||
448 | if (reply.isValid()) { | 463 | commit(); | ||
449 | supportValues.append(reply.value()); | 464 | return; | ||
465 | } | ||||
466 | | ||||
467 | const QList<bool> supportedValues = reply.value(); | ||||
468 | if (supportedValues.count() != effectNames.count()) { | ||||
469 | return; | ||||
450 | } | 470 | } | ||
451 | if (effectNames.size() == supportValues.size()) { | 471 | | ||
452 | for (int i = 0; i < effectNames.size(); ++i) { | 472 | for (int i = 0; i < effectNames.size(); ++i) { | ||
453 | const bool supportedValue = supportValues.at(i); | 473 | const bool supported = supportedValues.at(i); | ||
454 | const QString &effectName = effectNames.at(i); | 474 | const QString effectName = effectNames.at(i); | ||
455 | auto it = std::find_if(m_effects.begin(), m_effects.end(), [effectName](const EffectData &data) { | 475 | | ||
476 | auto it = std::find_if(m_pendingEffects.begin(), m_pendingEffects.end(), | ||||
477 | [effectName](const EffectData &data) { | ||||
456 | return data.serviceName == effectName; | 478 | return data.serviceName == effectName; | ||
457 | }); | | |||
458 | if (it != m_effects.end()) { | | |||
459 | if ((*it).supported != supportedValue) { | | |||
460 | (*it).supported = supportedValue; | | |||
461 | QModelIndex i = findByPluginId(effectName); | | |||
462 | if (i.isValid()) { | | |||
463 | emit dataChanged(i, i, QVector<int>() << SupportedRole); | | |||
464 | } | 479 | } | ||
480 | ); | ||||
481 | if (it == m_pendingEffects.end()) { | ||||
482 | continue; | ||||
465 | } | 483 | } | ||
484 | | ||||
485 | if ((*it).supported != supported) { | ||||
486 | (*it).supported = supported; | ||||
466 | } | 487 | } | ||
467 | } | 488 | } | ||
489 | | ||||
490 | commit(); | ||||
468 | } | 491 | } | ||
469 | self->deleteLater(); | 492 | ); | ||
470 | }); | 493 | } else { | ||
494 | commit(); | ||||
471 | } | 495 | } | ||
472 | | ||||
473 | endResetModel(); | | |||
474 | } | 496 | } | ||
475 | 497 | | |||
476 | void EffectsModel::updateEffectStatus(const QModelIndex &rowIndex, Status effectState) | 498 | void EffectsModel::updateEffectStatus(const QModelIndex &rowIndex, Status effectState) | ||
477 | { | 499 | { | ||
478 | setData(rowIndex, static_cast<int>(effectState), StatusRole); | 500 | setData(rowIndex, static_cast<int>(effectState), StatusRole); | ||
479 | } | 501 | } | ||
480 | 502 | | |||
481 | void EffectsModel::save() | 503 | void EffectsModel::save() | ||
▲ Show 20 Lines • Show All 163 Lines • Show Last 20 Lines |