From 231d96c5c6b1127c46702237d47a41a66f60f131 Mon Sep 17 00:00:00 2001 From: Ismael Asensio Date: Mon, 4 Jan 2021 17:28:09 +0100 Subject: [PATCH] kcm/kwinrules: Add hint about ignore geometry Some applications set their own geometry after start, which overrides the initial rule settings for placement: position, size and initial placement. This happens now more often, after introducing the "Remember app last position" feature for KXMLgui apps. There is a mechanism to avoid that, by Forcing the rule property "Ignore geometry", but it is unknown to many users. This MR adds a hint when some rule properties might not be respected by the application, so users can set this property and hopefully avoid bug reports. BUG: 428781 --- .../package/contents/ui/RulesEditor.qml | 17 ++-- kcmkwin/kwinrules/rulesmodel.cpp | 80 +++++++++++++------ kcmkwin/kwinrules/rulesmodel.h | 11 ++- 3 files changed, 75 insertions(+), 33 deletions(-) diff --git a/kcmkwin/kwinrules/package/contents/ui/RulesEditor.qml b/kcmkwin/kwinrules/package/contents/ui/RulesEditor.qml index 5af4da8ee0..97b4d236be 100644 --- a/kcmkwin/kwinrules/package/contents/ui/RulesEditor.qml +++ b/kcmkwin/kwinrules/package/contents/ui/RulesEditor.qml @@ -69,11 +69,18 @@ ScrollViewKCM { } } - header: Kirigami.InlineMessage { - Layout.fillWidth: true - Layout.fillHeight: true - text: rulesModel.warningMessage - visible: text != "" + header: ColumnLayout { + visible: warningList.count > 0 + Repeater { + id: warningList + model: rulesModel.warningMessages + + delegate: Kirigami.InlineMessage { + text: modelData + visible: true + Layout.fillWidth: true + } + } } footer: RowLayout { diff --git a/kcmkwin/kwinrules/rulesmodel.cpp b/kcmkwin/kwinrules/rulesmodel.cpp index a3ad8ade02..9d6b4115fe 100644 --- a/kcmkwin/kwinrules/rulesmodel.cpp +++ b/kcmkwin/kwinrules/rulesmodel.cpp @@ -162,7 +162,7 @@ bool RulesModel::setData(const QModelIndex &index, const QVariant &value, int ro emit descriptionChanged(); } if (rule->hasFlag(RuleItem::AffectsWarning)) { - emit warningMessageChanged(); + emit warningMessagesChanged(); } return true; @@ -233,16 +233,25 @@ void RulesModel::processSuggestion(const QString &key, const QVariant &value) } } -QString RulesModel::warningMessage() const +QStringList RulesModel::warningMessages() const { + QStringList messages; + if (wmclassWarning()) { - return i18n("You have specified the window class as unimportant.\n" - "This means the settings will possibly apply to windows from all applications." - " If you really want to create a generic setting, it is recommended" - " you at least limit the window types to avoid special window types."); + messages << i18n("You have specified the window class as unimportant.\n" + "This means the settings will possibly apply to windows from all applications." + " If you really want to create a generic setting, it is recommended" + " you at least limit the window types to avoid special window types."); } - return QString(); + if (geometryWarning()) { + messages << i18n("Some applications set their own geometry after starting," + " overriding your initial settings for size and position. " + "To enforce these settings, also force the property \"%1\" to \"Yes\".", + m_rules["ignoregeometry"]->name()); + } + + return messages; } bool RulesModel::wmclassWarning() const @@ -257,6 +266,25 @@ bool RulesModel::wmclassWarning() const return (no_wmclass && alltypes); } +bool RulesModel::geometryWarning() const +{ + const bool ignoregeometry = m_rules["ignoregeometry"]->isEnabled() + && m_rules["ignoregeometry"]->policy() == Rules::Force + && m_rules["ignoregeometry"]->value() == true; + + const bool initialPos = m_rules["position"]->isEnabled() + && (m_rules["position"]->policy() == Rules::Apply + || m_rules["position"]->policy() == Rules::Remember); + + const bool initialSize = m_rules["size"]->isEnabled() + && (m_rules["size"]->policy() == Rules::Apply + || m_rules["size"]->policy() == Rules::Remember); + + const bool initialPlacement = m_rules["placement"]->isEnabled() + && m_rules["placement"]->policy() == Rules::Force; + + return (!ignoregeometry && (initialPos || initialSize || initialPlacement)); +} void RulesModel::readFromSettings(RuleSettings *settings) { @@ -288,7 +316,7 @@ void RulesModel::readFromSettings(RuleSettings *settings) endResetModel(); emit descriptionChanged(); - emit warningMessageChanged(); + emit warningMessagesChanged(); } void RulesModel::writeToSettings(RuleSettings *settings) const @@ -418,15 +446,17 @@ void RulesModel::populateRuleList() QIcon::fromTheme("computer"))); // Size & Position - addRule(new RuleItem(QLatin1String("position"), - RulePolicy::SetRule, RuleItem::Point, - i18n("Position"), i18n("Size & Position"), - QIcon::fromTheme("transform-move"))); + auto position = addRule(new RuleItem(QLatin1String("position"), + RulePolicy::SetRule, RuleItem::Point, + i18n("Position"), i18n("Size & Position"), + QIcon::fromTheme("transform-move"))); + position->setFlag(RuleItem::AffectsWarning); - addRule(new RuleItem(QLatin1String("size"), - RulePolicy::SetRule, RuleItem::Size, - i18n("Size"), i18n("Size & Position"), - QIcon::fromTheme("image-resize-symbolic"))); + auto size = addRule(new RuleItem(QLatin1String("size"), + RulePolicy::SetRule, RuleItem::Size, + i18n("Size"), i18n("Size & Position"), + QIcon::fromTheme("image-resize-symbolic"))); + size->setFlag(RuleItem::AffectsWarning); addRule(new RuleItem(QLatin1String("maximizehoriz"), RulePolicy::SetRule, RuleItem::Boolean, @@ -490,15 +520,17 @@ void RulesModel::populateRuleList() i18n("Initial placement"), i18n("Size & Position"), QIcon::fromTheme("region"))); placement->setOptionsData(placementModelData()); + placement->setFlag(RuleItem::AffectsWarning); - addRule(new RuleItem(QLatin1String("ignoregeometry"), - RulePolicy::SetRule, RuleItem::Boolean, - i18n("Ignore requested geometry"), i18n("Size & Position"), - QIcon::fromTheme("view-time-schedule-baselined-remove"), - i18n("Windows can ask to appear in a certain position.\n" - "By default this overrides the placement strategy\n" - "what might be nasty if the client abuses the feature\n" - "to unconditionally popup in the middle of your screen."))); + auto ignoregeometry = addRule(new RuleItem(QLatin1String("ignoregeometry"), + RulePolicy::SetRule, RuleItem::Boolean, + i18n("Ignore requested geometry"), i18n("Size & Position"), + QIcon::fromTheme("view-time-schedule-baselined-remove"), + i18n("Windows can ask to appear in a certain position.\n" + "By default this overrides the placement strategy\n" + "what might be nasty if the client abuses the feature\n" + "to unconditionally popup in the middle of your screen."))); + ignoregeometry->setFlag(RuleItem::AffectsWarning); addRule(new RuleItem(QLatin1String("minsize"), RulePolicy::ForceRule, RuleItem::Size, diff --git a/kcmkwin/kwinrules/rulesmodel.h b/kcmkwin/kwinrules/rulesmodel.h index bfadcbbf90..fe97e6e26b 100644 --- a/kcmkwin/kwinrules/rulesmodel.h +++ b/kcmkwin/kwinrules/rulesmodel.h @@ -29,7 +29,7 @@ class RulesModel : public QAbstractListModel Q_OBJECT Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged) - Q_PROPERTY(QString warningMessage READ warningMessage NOTIFY warningMessageChanged) + Q_PROPERTY(QStringList warningMessages READ warningMessages NOTIFY warningMessagesChanged) public: enum RulesRole { @@ -74,13 +74,13 @@ public: QString description() const; void setDescription(const QString &description); - QString warningMessage() const; + QStringList warningMessages() const; Q_INVOKABLE void detectWindowProperties(int miliseconds); signals: void descriptionChanged(); - void warningMessageChanged(); + void warningMessagesChanged(); void showSuggestions(); void showErrorMessage(const QString &message); @@ -89,11 +89,14 @@ signals: private: void populateRuleList(); - bool wmclassWarning() const; RuleItem *addRule(RuleItem *rule); + QString defaultDescription() const; void processSuggestion(const QString &key, const QVariant &value); + bool wmclassWarning() const; + bool geometryWarning() const; + static const QHash x11PropertyHash(); void updateVirtualDesktops();