[kcm/kwinrules] Detect also window complete class

Summary:
When detecting the properties of a window, now it shows and lets the user select the window complete class.
If this property is selected in the overlay, `Window class` takes the whole class value, and the option `Match window whole class` is set.

This adds back a feature the old kcm was offering.

BUG: 421542
FIXED-IN: 5.20

Test Plan:
- `Detect window properties` and pick a firefox window
- The property selector shows: `Window class: navigator` and `Whole window class: navigator firefox`
- Selecting the latter set the properties as per summary

{F8334118}

Reviewers: ngraham, #kwin, #plasma, meven

Reviewed By: ngraham, #kwin, #plasma, meven

Subscribers: broulik, davidedmundson, meven, anthonyfieroni, zzag, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D29791
icc-effect-master
Ismael Asensio 2020-05-28 23:41:39 +02:00
parent 1dcf514e21
commit d725fc59bf
4 changed files with 43 additions and 10 deletions

View File

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

View File

@ -55,7 +55,8 @@ public:
StartEnabled = 1u << 1,
AffectsWarning = 1u << 2,
AffectsDescription = 1u << 3,
AllFlags = 0b1111
SuggestionOnly = 1u << 4,
AllFlags = 0b11111
};
public:

View File

@ -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<QString, QString> RulesModel::x11PropertyHash()
{
static const auto propertyToRule = QHash<QString, QString> {
/* 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)) {

View File

@ -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<QString, QString> x11PropertyHash();
void updateVirtualDesktops();