diff --git a/kcmkwin/kwinrules/ruleitem.h b/kcmkwin/kwinrules/ruleitem.h --- a/kcmkwin/kwinrules/ruleitem.h +++ b/kcmkwin/kwinrules/ruleitem.h @@ -55,7 +55,8 @@ StartEnabled = 1u << 1, AffectsWarning = 1u << 2, AffectsDescription = 1u << 3, - AllFlags = 0b1111 + SuggestionOnly = 1u << 4, + AllFlags = 0b11111 }; public: diff --git a/kcmkwin/kwinrules/ruleitem.cpp b/kcmkwin/kwinrules/ruleitem.cpp --- a/kcmkwin/kwinrules/ruleitem.cpp +++ b/kcmkwin/kwinrules/ruleitem.cpp @@ -99,7 +99,7 @@ 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/rulesmodel.cpp b/kcmkwin/kwinrules/rulesmodel.cpp --- a/kcmkwin/kwinrules/rulesmodel.cpp +++ b/kcmkwin/kwinrules/rulesmodel.cpp @@ -104,7 +104,7 @@ 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: @@ -137,6 +137,11 @@ rule->setEnabled(value.toBool()); break; case ValueRole: + if (rule->key() == "wmclasshelper") { + setData(this->index(1), value, RulesModel::ValueRole); // wmclass := value + setData(this->index(2), true, RulesModel::ValueRole); // wmclasscomplete := true + break; + } if (value == rule->value()) { return true; } @@ -200,7 +205,7 @@ void RulesModel::setDescription(const QString &description) { - setData(index(0, 0), description, RulesModel::ValueRole); + setData(index(0), description, RulesModel::ValueRole); } QString RulesModel::defaultDescription() const @@ -230,7 +235,6 @@ return QString(); } - bool RulesModel::wmclassWarning() const { const bool no_wmclass = !m_rules["wmclass"]->isEnabled() @@ -288,7 +292,9 @@ 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()); @@ -370,6 +376,13 @@ 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("Window whole 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"), @@ -618,10 +631,6 @@ 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" }, @@ -661,6 +670,12 @@ } 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)) {