diff --git a/kcmkwin/kwinrules/ruleitem.cpp b/kcmkwin/kwinrules/ruleitem.cpp index ff8047e71d..ff75f2120a 100644 --- a/kcmkwin/kwinrules/ruleitem.cpp +++ b/kcmkwin/kwinrules/ruleitem.cpp @@ -99,7 +99,7 @@ bool RuleItem::isEnabled() const void RuleItem::setEnabled(bool enabled) { - m_enabled = enabled | hasFlag(AlwaysEnabled); + m_enabled = (enabled && !hasFlag(SuggestionOnly)) || hasFlag(AlwaysEnabled); } bool RuleItem::hasFlag(RuleItem::Flags flag) const diff --git a/kcmkwin/kwinrules/ruleitem.h b/kcmkwin/kwinrules/ruleitem.h index a8fe25ec23..69e50b38f0 100644 --- a/kcmkwin/kwinrules/ruleitem.h +++ b/kcmkwin/kwinrules/ruleitem.h @@ -55,7 +55,8 @@ public: StartEnabled = 1u << 1, AffectsWarning = 1u << 2, AffectsDescription = 1u << 3, - AllFlags = 0b1111 + SuggestionOnly = 1u << 4, + AllFlags = 0b11111 }; public: diff --git a/kcmkwin/kwinrules/rulesmodel.cpp b/kcmkwin/kwinrules/rulesmodel.cpp index daa17a0c03..775413e403 100644 --- a/kcmkwin/kwinrules/rulesmodel.cpp +++ b/kcmkwin/kwinrules/rulesmodel.cpp @@ -107,7 +107,7 @@ QVariant RulesModel::data(const QModelIndex &index, int role) const case EnabledRole: return rule->isEnabled(); case SelectableRole: - return !rule->hasFlag(RuleItem::AlwaysEnabled); + return !rule->hasFlag(RuleItem::AlwaysEnabled) && !rule->hasFlag(RuleItem::SuggestionOnly); case ValueRole: return rule->value(); case TypeRole: @@ -140,6 +140,9 @@ bool RulesModel::setData(const QModelIndex &index, const QVariant &value, int ro rule->setEnabled(value.toBool()); break; case ValueRole: + if (rule->hasFlag(RuleItem::SuggestionOnly)) { + processSuggestion(rule->key(), value); + } if (value == rule->value()) { return true; } @@ -173,6 +176,15 @@ bool RulesModel::setData(const QModelIndex &index, const QVariant &value, int ro return true; } +QModelIndex RulesModel::indexOf(const QString& key) const +{ + const QModelIndexList indexes = match(index(0), RulesModel::KeyRole, key, 1, Qt::MatchFixedString); + if (indexes.isEmpty()) { + return QModelIndex(); + } + return indexes.at(0); +} + RuleItem *RulesModel::addRule(RuleItem *rule) { m_ruleList << rule; @@ -203,7 +215,7 @@ QString RulesModel::description() const void RulesModel::setDescription(const QString &description) { - setData(index(0, 0), description, RulesModel::ValueRole); + setData(indexOf("description"), description, RulesModel::ValueRole); } QString RulesModel::defaultDescription() const @@ -221,6 +233,14 @@ QString RulesModel::defaultDescription() const return i18n("New window settings"); } +void RulesModel::processSuggestion(const QString &key, const QVariant &value) +{ + if (key == QLatin1String("wmclasshelper")) { + setData(indexOf("wmclass"), value, RulesModel::ValueRole); + setData(indexOf("wmclasscomplete"), true, RulesModel::ValueRole); + } +} + QString RulesModel::warningMessage() const { if (wmclassWarning()) { @@ -233,7 +253,6 @@ QString RulesModel::warningMessage() const return QString(); } - bool RulesModel::wmclassWarning() const { const bool no_wmclass = !m_rules["wmclass"]->isEnabled() @@ -291,7 +310,9 @@ void RulesModel::writeToSettings(RuleSettings *settings) const KConfigSkeletonItem *configItem = settings->findItem(rule->key()); KConfigSkeletonItem *configPolicyItem = settings->findItem(rule->policyKey()); - Q_ASSERT (configItem); + if (!configItem) { + continue; + } if (rule->isEnabled()) { configItem->setProperty(rule->value()); @@ -373,6 +394,13 @@ void RulesModel::populateRuleList() QIcon::fromTheme("window"))); wmclasscomplete->setFlag(RuleItem::AlwaysEnabled); + // Helper item to store the detected whole window class when detecting properties + auto wmclasshelper = addRule(new RuleItem(QLatin1String("wmclasshelper"), + RulePolicy::NoPolicy, RuleItem::String, + i18n("Whole window class"), i18n("Window matching"), + QIcon::fromTheme("window"))); + wmclasshelper->setFlag(RuleItem::SuggestionOnly); + auto types = addRule(new RuleItem(QLatin1String("types"), RulePolicy::NoPolicy, RuleItem::FlagsOption, i18n("Window types"), i18n("Window matching"), @@ -625,10 +653,6 @@ void RulesModel::populateRuleList() const QHash RulesModel::x11PropertyHash() { static const auto propertyToRule = QHash { - /* The original detection dialog allows to choose depending on "Match complete window class": - * if Match Complete == false: wmclass = "resourceClass" - * if Match Complete == true: wmclass = "resourceName" + " " + "resourceClass" - */ { "resourceName", "wmclass" }, { "caption", "title" }, { "role", "windowrole" }, @@ -668,6 +692,12 @@ void RulesModel::setWindowProperties(const QVariantMap &info, bool forceValue) } m_rules["types"]->setSuggestedValue(1 << window_type, forceValue); + // Store "complete window class" as "resourceName" + " " + "resourceClass" + // Do not force the value, we want it only as a suggested value for the user to select + const QString wmcompleteclass = QStringLiteral("%1 %2").arg(info.value("resourceName").toString()) + .arg(info.value("resourceClass").toString()); + m_rules["wmclasshelper"]->setSuggestedValue(wmcompleteclass); + const auto ruleForProperty = x11PropertyHash(); for (QString &property : info.keys()) { if (!ruleForProperty.contains(property)) { diff --git a/kcmkwin/kwinrules/rulesmodel.h b/kcmkwin/kwinrules/rulesmodel.h index a62cff5525..a256dece78 100644 --- a/kcmkwin/kwinrules/rulesmodel.h +++ b/kcmkwin/kwinrules/rulesmodel.h @@ -73,6 +73,7 @@ public: QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; bool setData(const QModelIndex & index, const QVariant & value, int role) override; + QModelIndex indexOf(const QString &key) const; bool hasRule(const QString &key) const; RuleItem *ruleItem(const QString &key) const; @@ -104,6 +105,7 @@ private: bool wmclassWarning() const; RuleItem *addRule(RuleItem *rule); QString defaultDescription() const; + void processSuggestion(const QString &key, const QVariant &value); static const QHash x11PropertyHash(); void updateVirtualDesktops();