From 3048d92c09393e0a6dce7f20942c934241f5d142 Mon Sep 17 00:00:00 2001 From: Ismael Asensio Date: Sat, 20 Mar 2021 23:34:15 +0700 Subject: [PATCH] kcm/kwinrules: Unify windows properties methods in KCM class Put together the two methods about window properties and rules into the same class, since they are tightly related and they seem a bit out of place within RuleBookModel Small refactor patch. No behavior changes --- src/kcmkwin/kwinrules/kcmrules.cpp | 100 ++++++++++++++++++++++-- src/kcmkwin/kwinrules/kcmrules.h | 4 +- src/kcmkwin/kwinrules/rulebookmodel.cpp | 85 -------------------- src/kcmkwin/kwinrules/rulebookmodel.h | 2 - 4 files changed, 95 insertions(+), 96 deletions(-) diff --git a/src/kcmkwin/kwinrules/kcmrules.cpp b/src/kcmkwin/kwinrules/kcmrules.cpp index bc47099687..74aa804c65 100644 --- a/src/kcmkwin/kwinrules/kcmrules.cpp +++ b/src/kcmkwin/kwinrules/kcmrules.cpp @@ -143,7 +143,7 @@ void KCMKWinRules::createRuleFromProperties() return; } - QModelIndex matchedIndex = m_ruleBookModel->findRuleWithProperties(m_winProperties, m_wholeApp); + QModelIndex matchedIndex = findRuleWithProperties(m_winProperties, m_wholeApp); if (!matchedIndex.isValid()) { m_ruleBookModel->insertRow(0); m_ruleBookModel->setRuleAt(0, ruleForProperties(m_winProperties, m_wholeApp)); @@ -331,14 +331,98 @@ void KCMKWinRules::importFromFile(const QUrl &path) } // Code adapted from original `findRule()` method in `kwin_rules_dialog::main.cpp` -Rules *KCMKWinRules::ruleForProperties(const QVariantMap &windowProperties, bool wholeApp) const +QModelIndex KCMKWinRules::findRuleWithProperties(const QVariantMap &info, bool wholeApp) const { - const QByteArray wmclass_class = windowProperties.value("resourceClass").toByteArray().toLower(); - const QByteArray wmclass_name = windowProperties.value("resourceName").toByteArray().toLower(); - const QByteArray role = windowProperties.value("role").toByteArray().toLower(); - const NET::WindowType type = static_cast(windowProperties.value("type").toInt()); - const QString title = windowProperties.value("caption").toString(); - const QByteArray machine = windowProperties.value("clientMachine").toByteArray(); + const QByteArray wmclass_class = info.value("resourceClass").toByteArray().toLower(); + const QByteArray wmclass_name = info.value("resourceName").toByteArray().toLower(); + const QByteArray role = info.value("role").toByteArray().toLower(); + const NET::WindowType type = static_cast(info.value("type").toInt()); + const QString title = info.value("caption").toString(); + const QByteArray machine = info.value("clientMachine").toByteArray(); + const bool isLocalHost = info.value("localhost").toBool(); + + int bestMatchRow = -1; + int bestMatchScore = 0; + + for (int row = 0; row < m_ruleBookModel->rowCount(); row++) { + Rules *rule = m_ruleBookModel->ruleAt(row); + + /* clang-format off */ + // If the rule doesn't match try the next one + if (!rule->matchWMClass(wmclass_class, wmclass_name) + || !rule->matchType(type) + || !rule->matchRole(role) + || !rule->matchTitle(title) + || !rule->matchClientMachine(machine, isLocalHost)) { + continue; + } + /* clang-format on */ + + if (rule->wmclassmatch != Rules::ExactMatch) { + continue; // too generic + } + + // Now that the rule matches the window, check the quality of the match + // It stablishes a quality depending on the match policy of the rule + int score = 0; + bool generic = true; + + // from now on, it matches the app - now try to match for a specific window + if (rule->wmclasscomplete) { + score += 1; + generic = false; // this can be considered specific enough (old X apps) + } + if (!wholeApp) { + if (rule->windowrolematch != Rules::UnimportantMatch) { + score += rule->windowrolematch == Rules::ExactMatch ? 5 : 1; + generic = false; + } + if (rule->titlematch != Rules::UnimportantMatch) { + score += rule->titlematch == Rules::ExactMatch ? 3 : 1; + generic = false; + } + if (rule->types != NET::AllTypesMask) { + // Checks that type fits the mask, and only one of the types + int bits = 0; + for (unsigned int bit = 1; bit < 1U << 31; bit <<= 1) { + if (rule->types & bit) { + ++bits; + } + } + if (bits == 1) { + score += 2; + } + } + if (generic) { // ignore generic rules, use only the ones that are for this window + continue; + } + } else { + if (rule->types == NET::AllTypesMask) { + score += 2; + } + } + + if (score > bestMatchScore) { + bestMatchRow = row; + bestMatchScore = score; + } + } + + if (bestMatchRow < 0) { + return QModelIndex(); + } + return m_ruleBookModel->index(bestMatchRow); +} + +// Code adapted from original `findRule()` method in `kwin_rules_dialog::main.cpp` +Rules *KCMKWinRules::ruleForProperties(const QVariantMap &info, bool wholeApp) const +{ + const QByteArray wmclass_class = info.value("resourceClass").toByteArray().toLower(); + const QByteArray wmclass_name = info.value("resourceName").toByteArray().toLower(); + const QByteArray role = info.value("role").toByteArray().toLower(); + const NET::WindowType type = static_cast(info.value("type").toInt()); + const QString title = info.value("caption").toString(); + const QByteArray machine = info.value("clientMachine").toByteArray(); Rules *rule = new Rules(); diff --git a/src/kcmkwin/kwinrules/kcmrules.h b/src/kcmkwin/kwinrules/kcmrules.h index 6f96eea8c2..97ed70d2c5 100644 --- a/src/kcmkwin/kwinrules/kcmrules.h +++ b/src/kcmkwin/kwinrules/kcmrules.h @@ -53,7 +53,9 @@ private: void saveCurrentRule(); void parseArguments(const QStringList &args); void createRuleFromProperties(); - Rules *ruleForProperties(const QVariantMap &windowProperties, bool wholeApp) const; + + QModelIndex findRuleWithProperties(const QVariantMap &info, bool wholeApp) const; + Rules *ruleForProperties(const QVariantMap &info, bool wholeApp) const; private: RuleBookModel *m_ruleBookModel; diff --git a/src/kcmkwin/kwinrules/rulebookmodel.cpp b/src/kcmkwin/kwinrules/rulebookmodel.cpp index 54e5534721..42dee14a16 100644 --- a/src/kcmkwin/kwinrules/rulebookmodel.cpp +++ b/src/kcmkwin/kwinrules/rulebookmodel.cpp @@ -1,5 +1,4 @@ /* - SPDX-FileCopyrightText: 2004 Lubos Lunak SPDX-FileCopyrightText: 2020 Ismael Asensio SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL @@ -172,88 +171,4 @@ void RuleBookModel::save() m_ruleBook->save(); } -// Code adapted from original `findRule()` method in `kwin_rules_dialog::main.cpp` -QModelIndex RuleBookModel::findRuleWithProperties(const QVariantMap &info, bool wholeApp) const -{ - const QByteArray wmclass_class = info.value("resourceClass").toByteArray().toLower(); - const QByteArray wmclass_name = info.value("resourceName").toByteArray().toLower(); - const QByteArray role = info.value("role").toByteArray().toLower(); - const NET::WindowType type = static_cast(info.value("type").toInt()); - const QString title = info.value("caption").toString(); - const QByteArray machine = info.value("clientMachine").toByteArray(); - const bool isLocalHost = info.value("localhost").toBool(); - - int bestMatchRow = -1; - int match_quality = 0; - - for (int row = 0; row < m_rules.count(); row++) { - Rules *rule = m_rules.at(row); - - /* clang-format off */ - // If the rule doesn't match try the next one - if (!rule->matchWMClass(wmclass_class, wmclass_name) - || !rule->matchType(type) - || !rule->matchRole(role) - || !rule->matchTitle(title) - || !rule->matchClientMachine(machine, isLocalHost)) { - continue; - } - /* clang-format on */ - - if (rule->wmclassmatch != Rules::ExactMatch) { - continue; // too generic - } - - // Now that the rule matches the window, check the quality of the match - // It stablishes a quality depending on the match policy of the rule - int quality = 0; - bool generic = true; - - // from now on, it matches the app - now try to match for a specific window - if (rule->wmclasscomplete) { - quality += 1; - generic = false; // this can be considered specific enough (old X apps) - } - if (!wholeApp) { - if (rule->windowrolematch != Rules::UnimportantMatch) { - quality += rule->windowrolematch == Rules::ExactMatch ? 5 : 1; - generic = false; - } - if (rule->titlematch != Rules::UnimportantMatch) { - quality += rule->titlematch == Rules::ExactMatch ? 3 : 1; - generic = false; - } - if (rule->types != NET::AllTypesMask) { - // Checks that type fits the mask, and only one of the types - int bits = 0; - for (unsigned int bit = 1; bit < 1U << 31; bit <<= 1) { - if (rule->types & bit) { - ++bits; - } - } - if (bits == 1) { - quality += 2; - } - } - if (generic) { // ignore generic rules, use only the ones that are for this window - continue; - } - } else { - if (rule->types == NET::AllTypesMask) { - quality += 2; - } - } - - if (quality > match_quality) { - bestMatchRow = row; - match_quality = quality; - } - } - - if (bestMatchRow < 0) { - return QModelIndex(); - } - return index(bestMatchRow); -} - } // namespace diff --git a/src/kcmkwin/kwinrules/rulebookmodel.h b/src/kcmkwin/kwinrules/rulebookmodel.h index 1dde70db4a..aaf39378d2 100644 --- a/src/kcmkwin/kwinrules/rulebookmodel.h +++ b/src/kcmkwin/kwinrules/rulebookmodel.h @@ -42,8 +42,6 @@ public: void load(); void save(); - QModelIndex findRuleWithProperties(const QVariantMap &info, bool wholeApp) const; - private: RuleBookSettings *m_ruleBook; QVector m_rules;