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[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<int>() << 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

View file

@ -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;
};
}
}

View file

@ -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 ...")