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
This commit is contained in:
Martin Gräßlin 2014-03-09 10:02:12 +01:00
parent b70928fce6
commit 503c221733
3 changed files with 98 additions and 7 deletions

View file

@ -65,6 +65,7 @@ QHash< int, QByteArray > EffectModel::roleNames() const
roleNames[ServiceNameRole] = "ServiceNameRole"; roleNames[ServiceNameRole] = "ServiceNameRole";
roleNames[EffectStatusRole] = "EffectStatusRole"; roleNames[EffectStatusRole] = "EffectStatusRole";
roleNames[VideoRole] = "VideoRole"; roleNames[VideoRole] = "VideoRole";
roleNames[SupportedRole] = "SupportedRole";
return roleNames; return roleNames;
} }
@ -127,6 +128,8 @@ QVariant EffectModel::data(const QModelIndex &index, int role) const
return m_effectsList.at(index.row()).effectStatus; return m_effectsList.at(index.row()).effectStatus;
case VideoRole: case VideoRole:
return m_effectsList.at(index.row()).video; return m_effectsList.at(index.row()).video;
case SupportedRole:
return m_effectsList.at(index.row()).supported;
default: default:
return QVariant(); return QVariant();
} }
@ -184,6 +187,7 @@ void EffectModel::loadEffects()
effect.effectStatus = kwinConfig.readEntry(effect.serviceName + "Enabled", plugin.isPluginEnabledByDefault()); effect.effectStatus = kwinConfig.readEntry(effect.serviceName + "Enabled", plugin.isPluginEnabledByDefault());
effect.enabledByDefault = plugin.isPluginEnabledByDefault(); effect.enabledByDefault = plugin.isPluginEnabledByDefault();
effect.video = service->property(QStringLiteral("X-KWin-Video-Url"), QVariant::Url).toUrl(); effect.video = service->property(QStringLiteral("X-KWin-Video-Url"), QVariant::Url).toUrl();
effect.supported = true;
m_effectsList << effect; m_effectsList << effect;
} }
@ -192,6 +196,45 @@ void EffectModel::loadEffects()
return a.category < b.category; 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<int>() << SupportedRole);
}
}
}
}
}
self->deleteLater();
});
}
m_effectsChanged = m_effectsList; m_effectsChanged = m_effectsList;
endResetModel(); endResetModel();
} }
@ -307,8 +350,9 @@ void EffectModel::defaults()
} }
EffectFilterModel::EffectFilterModel(QObject *parent) EffectFilterModel::EffectFilterModel(QObject *parent)
:QSortFilterProxyModel(parent), : QSortFilterProxyModel(parent)
m_effectModel( new EffectModel(this)) , m_effectModel(new EffectModel(this))
, m_supported(true)
{ {
setSourceModel(m_effectModel); setSourceModel(m_effectModel);
} }
@ -329,21 +373,39 @@ void EffectFilterModel::setFilter(const QString &filter)
invalidateFilter(); 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 bool EffectFilterModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{ {
if (!m_effectModel) { if (!m_effectModel) {
return false; return false;
} }
if (m_filter.isEmpty()) {
return true;
}
QModelIndex index = m_effectModel->index(source_row, 0, source_parent); QModelIndex index = m_effectModel->index(source_row, 0, source_parent);
if (!index.isValid()) { if (!index.isValid()) {
return false; 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(); QVariant data = index.data();
if (!data.isValid()) { if (!data.isValid()) {
//An invalid QVariant is valid data //An invalid QVariant is valid data

View file

@ -46,6 +46,7 @@ struct EffectData {
bool effectStatus; bool effectStatus;
bool enabledByDefault; bool enabledByDefault;
QUrl video; QUrl video;
bool supported;
}; };
class EffectModel : public QAbstractItemModel class EffectModel : public QAbstractItemModel
@ -65,7 +66,8 @@ public:
ServiceNameRole, ServiceNameRole,
EffectStatusRole, EffectStatusRole,
WindowManagementRole, WindowManagementRole,
VideoRole VideoRole,
SupportedRole
}; };
explicit EffectModel(QObject *parent = 0); explicit EffectModel(QObject *parent = 0);
@ -125,6 +127,11 @@ class EffectFilterModel : public QSortFilterProxyModel
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QString filter READ filter WRITE setFilter NOTIFY filterChanged) 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 backgroundActiveColor READ backgroundActiveColor CONSTANT);
Q_PROPERTY(QColor backgroundNormalColor READ backgroundNormalColor CONSTANT); Q_PROPERTY(QColor backgroundNormalColor READ backgroundNormalColor CONSTANT);
Q_PROPERTY(QColor backgroundAlternateColor READ backgroundAlternateColor CONSTANT); Q_PROPERTY(QColor backgroundAlternateColor READ backgroundAlternateColor CONSTANT);
@ -148,6 +155,11 @@ public:
return color; return color;
} }
void setFilterOnSupported(bool supported);
bool isFilterOnSupported() const {
return m_supported;
}
void defaults(); void defaults();
public Q_SLOTS: public Q_SLOTS:
@ -159,10 +171,12 @@ protected:
Q_SIGNALS: Q_SIGNALS:
void effectModelChanged(); void effectModelChanged();
void filterChanged(); void filterChanged();
void filterOnSupportedChanged();
private: private:
EffectModel *m_effectModel; EffectModel *m_effectModel;
QString m_filter; QString m_filter;
bool m_supported;
}; };
} }
} }

View file

@ -75,6 +75,21 @@ Item {
focus: true 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 { Button {
id: ghnsButton id: ghnsButton
text: i18n("Get New Effects ...") text: i18n("Get New Effects ...")