From 503c221733aca0796e3911b5bdedcc17a0189137 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Sun, 9 Mar 2014 10:02:12 +0100 Subject: [PATCH] Add supported to EffectData For each effect added to the list the KWin DBus interface is queried for whether the effect is supported. By default all effects are set to supported, thus if the DBus service is not around (e.g. compositing disabled) it is assumed that all effects are supported. In fact it's not possible to figure it out at all. REVIEW: 116667 --- kcmkwin/kwincompositing/model.cpp | 74 ++++++++++++++++++++-- kcmkwin/kwincompositing/model.h | 16 ++++- kcmkwin/kwincompositing/qml/EffectView.qml | 15 +++++ 3 files changed, 98 insertions(+), 7 deletions(-) diff --git a/kcmkwin/kwincompositing/model.cpp b/kcmkwin/kwincompositing/model.cpp index bc5b3e0f30..777a5abfc6 100644 --- a/kcmkwin/kwincompositing/model.cpp +++ b/kcmkwin/kwincompositing/model.cpp @@ -65,6 +65,7 @@ QHash< int, QByteArray > EffectModel::roleNames() const roleNames[ServiceNameRole] = "ServiceNameRole"; roleNames[EffectStatusRole] = "EffectStatusRole"; roleNames[VideoRole] = "VideoRole"; + roleNames[SupportedRole] = "SupportedRole"; return roleNames; } @@ -127,6 +128,8 @@ QVariant EffectModel::data(const QModelIndex &index, int role) const return m_effectsList.at(index.row()).effectStatus; case VideoRole: return m_effectsList.at(index.row()).video; + case SupportedRole: + return m_effectsList.at(index.row()).supported; default: return QVariant(); } @@ -184,6 +187,7 @@ void EffectModel::loadEffects() effect.effectStatus = kwinConfig.readEntry(effect.serviceName + "Enabled", plugin.isPluginEnabledByDefault()); effect.enabledByDefault = plugin.isPluginEnabledByDefault(); effect.video = service->property(QStringLiteral("X-KWin-Video-Url"), QVariant::Url).toUrl(); + effect.supported = true; m_effectsList << effect; } @@ -192,6 +196,45 @@ void EffectModel::loadEffects() return a.category < b.category; }); + OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"), + QStringLiteral("/Effects"), + QDBusConnection::sessionBus()); + if (interface.isValid()) { + QStringList effectNames; + std::for_each(m_effectsList.constBegin(), m_effectsList.constEnd(), [&effectNames](const EffectData &data) { + effectNames << data.serviceName; + }); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(interface.areEffectsSupported(effectNames), this); + watcher->setProperty("effectNames", effectNames); + connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher *self) { + const QStringList effectNames = self->property("effectNames").toStringList(); + const QDBusPendingReply< QList< bool > > reply = *self; + QList< bool> supportValues; + if (reply.isValid()) { + supportValues.append(reply.value()); + } + if (effectNames.size() == supportValues.size()) { + for (int i = 0; i < effectNames.size(); ++i) { + const bool supportedValue = supportValues.at(i); + const QString &effectName = effectNames.at(i); + auto it = std::find_if(m_effectsList.begin(), m_effectsList.end(), [effectName](const EffectData &data) { + return data.serviceName == effectName; + }); + if (it != m_effectsList.end()) { + if ((*it).supported != supportedValue) { + (*it).supported = supportedValue; + QModelIndex i = index(findRowByServiceName(effectName), 0); + if (i.isValid()) { + emit dataChanged(i, i, QVector() << SupportedRole); + } + } + } + } + } + self->deleteLater(); + }); + } + m_effectsChanged = m_effectsList; endResetModel(); } @@ -307,8 +350,9 @@ void EffectModel::defaults() } EffectFilterModel::EffectFilterModel(QObject *parent) - :QSortFilterProxyModel(parent), - m_effectModel( new EffectModel(this)) + : QSortFilterProxyModel(parent) + , m_effectModel(new EffectModel(this)) + , m_supported(true) { setSourceModel(m_effectModel); } @@ -329,21 +373,39 @@ void EffectFilterModel::setFilter(const QString &filter) invalidateFilter(); } +void EffectFilterModel::setFilterOnSupported(bool supported) +{ + if (m_supported == supported) { + return; + } + + m_supported = supported; + emit filterOnSupportedChanged(); + invalidateFilter(); +} + bool EffectFilterModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { if (!m_effectModel) { return false; } - if (m_filter.isEmpty()) { - return true; - } - QModelIndex index = m_effectModel->index(source_row, 0, source_parent); if (!index.isValid()) { return false; } + if (m_supported) { + bool supported = index.data(EffectModel::SupportedRole).toBool(); + if (!supported) { + return false; + } + } + + if (m_filter.isEmpty()) { + return true; + } + QVariant data = index.data(); if (!data.isValid()) { //An invalid QVariant is valid data diff --git a/kcmkwin/kwincompositing/model.h b/kcmkwin/kwincompositing/model.h index 7807a97e2d..b03a184b59 100644 --- a/kcmkwin/kwincompositing/model.h +++ b/kcmkwin/kwincompositing/model.h @@ -46,6 +46,7 @@ struct EffectData { bool effectStatus; bool enabledByDefault; QUrl video; + bool supported; }; class EffectModel : public QAbstractItemModel @@ -65,7 +66,8 @@ public: ServiceNameRole, EffectStatusRole, WindowManagementRole, - VideoRole + VideoRole, + SupportedRole }; explicit EffectModel(QObject *parent = 0); @@ -125,6 +127,11 @@ class EffectFilterModel : public QSortFilterProxyModel { Q_OBJECT Q_PROPERTY(QString filter READ filter WRITE setFilter NOTIFY filterChanged) + /** + * If @c true not supported effects are excluded, if @c false no restriction on supported. + * Default value is @c true. + **/ + Q_PROPERTY(bool filterOnSupported READ isFilterOnSupported WRITE setFilterOnSupported NOTIFY filterOnSupportedChanged) Q_PROPERTY(QColor backgroundActiveColor READ backgroundActiveColor CONSTANT); Q_PROPERTY(QColor backgroundNormalColor READ backgroundNormalColor CONSTANT); Q_PROPERTY(QColor backgroundAlternateColor READ backgroundAlternateColor CONSTANT); @@ -148,6 +155,11 @@ public: return color; } + void setFilterOnSupported(bool supported); + bool isFilterOnSupported() const { + return m_supported; + } + void defaults(); public Q_SLOTS: @@ -159,10 +171,12 @@ protected: Q_SIGNALS: void effectModelChanged(); void filterChanged(); + void filterOnSupportedChanged(); private: EffectModel *m_effectModel; QString m_filter; + bool m_supported; }; } } diff --git a/kcmkwin/kwincompositing/qml/EffectView.qml b/kcmkwin/kwincompositing/qml/EffectView.qml index f58b41e841..3e1bf5f75f 100644 --- a/kcmkwin/kwincompositing/qml/EffectView.qml +++ b/kcmkwin/kwincompositing/qml/EffectView.qml @@ -75,6 +75,21 @@ Item { focus: true } + Button { + iconName: "configure" + tooltip: "Configure filter" + menu: Menu { + MenuItem { + text: i18n("Filter only on Desktop Effects supported by the Compositor") + checkable: true + checked: searchModel.filterOnSupported + onTriggered: { + searchModel.filterOnSupported = !searchModel.filterOnSupported; + } + } + } + } + Button { id: ghnsButton text: i18n("Get New Effects ...")