KWinRules KCM Redesign
Summary:
Replacement KCM to configure kwin rules, using a QML-based UI.
After some work on the task T12729, it is almost feature-par with the previous module, and adapted to the recent move to KConfigXT.
Test Plan:
{F8208046}
{F8208047}
Reviewers: #plasma, #kwin, #vdg, ngraham, davidedmundson, zzag
Reviewed By: #plasma, #kwin, #vdg, ngraham, davidedmundson, zzag
Subscribers: ngraham, davidedmundson, hchain, broulik, zzag, kwin
Tags: #kwin, #vdg
Differential Revision: https://phabricator.kde.org/D28152
2020-04-20 20:01:55 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2020 Ismael Asensio <isma.af@gmail.com>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
|
|
|
* published by the Free Software Foundation; either version 2 of
|
|
|
|
* the License or (at your option) version 3 or any later version
|
|
|
|
* accepted by the membership of KDE e.V. (or its successor approved
|
|
|
|
* by the membership of KDE e.V.), which shall act as a proxy
|
|
|
|
* defined in Section 14 of version 3 of the license.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
import QtQuick 2.14
|
|
|
|
import QtQuick.Layouts 1.14
|
|
|
|
import QtQuick.Controls 2.14 as QQC2
|
2020-04-23 20:16:24 +00:00
|
|
|
import org.kde.kirigami 2.12 as Kirigami
|
KWinRules KCM Redesign
Summary:
Replacement KCM to configure kwin rules, using a QML-based UI.
After some work on the task T12729, it is almost feature-par with the previous module, and adapted to the recent move to KConfigXT.
Test Plan:
{F8208046}
{F8208047}
Reviewers: #plasma, #kwin, #vdg, ngraham, davidedmundson, zzag
Reviewed By: #plasma, #kwin, #vdg, ngraham, davidedmundson, zzag
Subscribers: ngraham, davidedmundson, hchain, broulik, zzag, kwin
Tags: #kwin, #vdg
Differential Revision: https://phabricator.kde.org/D28152
2020-04-20 20:01:55 +00:00
|
|
|
import org.kde.kcm 1.2
|
|
|
|
import org.kde.kitemmodels 1.0
|
|
|
|
import org.kde.kcms.kwinrules 1.0
|
|
|
|
|
|
|
|
|
|
|
|
ScrollViewKCM {
|
|
|
|
id: rulesEditor
|
|
|
|
|
|
|
|
property var rulesModel: kcm.rulesModel
|
|
|
|
|
|
|
|
title: rulesModel.description
|
|
|
|
|
|
|
|
view: ListView {
|
|
|
|
id: rulesView
|
|
|
|
clip: true
|
|
|
|
|
|
|
|
model: enabledRulesModel
|
|
|
|
delegate: RuleItemDelegate {}
|
|
|
|
section {
|
|
|
|
property: "section"
|
|
|
|
delegate: Kirigami.ListSectionHeader { label: section }
|
|
|
|
}
|
|
|
|
|
2020-04-23 20:16:24 +00:00
|
|
|
Kirigami.PlaceholderMessage {
|
KWinRules KCM Redesign
Summary:
Replacement KCM to configure kwin rules, using a QML-based UI.
After some work on the task T12729, it is almost feature-par with the previous module, and adapted to the recent move to KConfigXT.
Test Plan:
{F8208046}
{F8208047}
Reviewers: #plasma, #kwin, #vdg, ngraham, davidedmundson, zzag
Reviewed By: #plasma, #kwin, #vdg, ngraham, davidedmundson, zzag
Subscribers: ngraham, davidedmundson, hchain, broulik, zzag, kwin
Tags: #kwin, #vdg
Differential Revision: https://phabricator.kde.org/D28152
2020-04-20 20:01:55 +00:00
|
|
|
id: hintArea
|
|
|
|
visible: rulesView.count <= 4
|
2020-05-15 16:29:23 +00:00
|
|
|
anchors {
|
|
|
|
// We need to center on the free space below contentItem, not the full ListView.
|
|
|
|
// Setting both top and bottom anchors (or using anchors.fill) stretches the component
|
|
|
|
// and distorts the spacing between its internal items.
|
|
|
|
// This is fine as long as we have a single item here.
|
|
|
|
horizontalCenter: parent.horizontalCenter
|
|
|
|
top: parent.contentItem.bottom
|
|
|
|
bottom: parent.bottom
|
|
|
|
}
|
2020-05-12 20:12:04 +00:00
|
|
|
width: parent.width - (units.largeSpacing * 4)
|
2020-04-23 20:16:24 +00:00
|
|
|
helpfulAction: QQC2.Action {
|
KWinRules KCM Redesign
Summary:
Replacement KCM to configure kwin rules, using a QML-based UI.
After some work on the task T12729, it is almost feature-par with the previous module, and adapted to the recent move to KConfigXT.
Test Plan:
{F8208046}
{F8208047}
Reviewers: #plasma, #kwin, #vdg, ngraham, davidedmundson, zzag
Reviewed By: #plasma, #kwin, #vdg, ngraham, davidedmundson, zzag
Subscribers: ngraham, davidedmundson, hchain, broulik, zzag, kwin
Tags: #kwin, #vdg
Differential Revision: https://phabricator.kde.org/D28152
2020-04-20 20:01:55 +00:00
|
|
|
text: i18n("Add Properties...")
|
|
|
|
icon.name: "list-add-symbolic"
|
2020-04-23 20:16:24 +00:00
|
|
|
onTriggered: {
|
KWinRules KCM Redesign
Summary:
Replacement KCM to configure kwin rules, using a QML-based UI.
After some work on the task T12729, it is almost feature-par with the previous module, and adapted to the recent move to KConfigXT.
Test Plan:
{F8208046}
{F8208047}
Reviewers: #plasma, #kwin, #vdg, ngraham, davidedmundson, zzag
Reviewed By: #plasma, #kwin, #vdg, ngraham, davidedmundson, zzag
Subscribers: ngraham, davidedmundson, hchain, broulik, zzag, kwin
Tags: #kwin, #vdg
Differential Revision: https://phabricator.kde.org/D28152
2020-04-20 20:01:55 +00:00
|
|
|
propertySheet.open();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: InlineMessage.qml:241:13: QML Label: Binding loop detected for property "verticalAlignment"
|
|
|
|
header: Kirigami.InlineMessage {
|
|
|
|
Layout.fillWidth: true
|
|
|
|
Layout.fillHeight: true
|
|
|
|
text: rulesModel.warningMessage
|
|
|
|
visible: text != ""
|
|
|
|
}
|
|
|
|
|
|
|
|
footer: RowLayout {
|
|
|
|
QQC2.Button {
|
|
|
|
text: checked ? i18n("Close") : i18n("Add Properties...")
|
|
|
|
icon.name: checked ? "dialog-close" : "list-add-symbolic"
|
|
|
|
checkable: true
|
|
|
|
checked: propertySheet.sheetOpen
|
|
|
|
visible: !hintArea.visible || checked
|
|
|
|
onToggled: {
|
|
|
|
propertySheet.sheetOpen = checked;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Item {
|
|
|
|
Layout.fillWidth: true
|
|
|
|
}
|
|
|
|
QQC2.Button {
|
|
|
|
text: i18n("Detect Window Properties")
|
|
|
|
icon.name: "edit-find"
|
|
|
|
onClicked: {
|
|
|
|
overlayModel.onlySuggestions = true;
|
|
|
|
rulesModel.detectWindowProperties(delaySpin.value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
QQC2.SpinBox {
|
|
|
|
id: delaySpin
|
|
|
|
Layout.preferredWidth: Kirigami.Units.gridUnit * 8
|
|
|
|
from: 0
|
|
|
|
to: 30
|
|
|
|
textFromValue: (value, locale) => {
|
|
|
|
return (value == 0) ? i18n("Instantly")
|
|
|
|
: i18np("After %1 second", "After %1 seconds", value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Connections {
|
|
|
|
target: rulesModel
|
|
|
|
onSuggestionsChanged: {
|
|
|
|
propertySheet.sheetOpen = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Kirigami.OverlaySheet {
|
|
|
|
id: propertySheet
|
|
|
|
|
|
|
|
parent: view
|
|
|
|
|
|
|
|
header: Kirigami.Heading {
|
|
|
|
text: i18n("Select properties")
|
|
|
|
}
|
|
|
|
footer: Kirigami.SearchField {
|
|
|
|
id: searchField
|
|
|
|
horizontalAlignment: Text.AlignLeft
|
|
|
|
}
|
|
|
|
|
|
|
|
ListView {
|
|
|
|
id: overlayView
|
|
|
|
model: overlayModel
|
|
|
|
Layout.preferredWidth: Kirigami.Units.gridUnit * 28
|
|
|
|
|
|
|
|
section {
|
|
|
|
property: "section"
|
|
|
|
delegate: Kirigami.ListSectionHeader { label: section }
|
|
|
|
}
|
|
|
|
|
|
|
|
delegate: Kirigami.AbstractListItem {
|
|
|
|
id: propertyDelegate
|
|
|
|
highlighted: false
|
|
|
|
width: ListView.view.width
|
|
|
|
|
|
|
|
RowLayout {
|
|
|
|
Kirigami.Icon {
|
|
|
|
source: model.icon
|
|
|
|
Layout.preferredHeight: Kirigami.Units.iconSizes.smallMedium
|
|
|
|
Layout.preferredWidth: Kirigami.Units.iconSizes.smallMedium
|
|
|
|
Layout.alignment: Qt.AlignVCenter
|
|
|
|
}
|
|
|
|
QQC2.Label {
|
|
|
|
id: itemNameLabel
|
|
|
|
text: model.name
|
|
|
|
horizontalAlignment: Qt.AlignLeft
|
|
|
|
Layout.preferredWidth: implicitWidth
|
|
|
|
Layout.fillWidth: true
|
|
|
|
Layout.alignment: Qt.AlignVCenter
|
|
|
|
QQC2.ToolTip {
|
|
|
|
text: model.description
|
|
|
|
visible: hovered && (model.description != "")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
QQC2.Label {
|
|
|
|
id: suggestedLabel
|
|
|
|
text: formatValue(model.suggested, model.type, model.options)
|
|
|
|
horizontalAlignment: Text.AlignRight
|
|
|
|
elide: Text.ElideRight
|
|
|
|
opacity: 0.7
|
|
|
|
Layout.maximumWidth: propertyDelegate.width - itemNameLabel.implicitWidth - Kirigami.Units.gridUnit * 6
|
|
|
|
Layout.alignment: Qt.AlignVCenter
|
|
|
|
QQC2.ToolTip {
|
|
|
|
text: suggestedLabel.text
|
|
|
|
visible: hovered && suggestedLabel.truncated
|
|
|
|
}
|
|
|
|
}
|
|
|
|
QQC2.ToolButton {
|
|
|
|
icon.name: (model.enabled) ? "dialog-ok-apply" : "list-add-symbolic"
|
|
|
|
opacity: propertyDelegate.hovered ? 1 : 0
|
|
|
|
onClicked: propertyDelegate.clicked()
|
|
|
|
Layout.preferredWidth: implicitWidth
|
2020-05-04 20:00:44 +00:00
|
|
|
Layout.leftMargin: -Kirigami.Units.smallSpacing
|
|
|
|
Layout.rightMargin: -Kirigami.Units.smallSpacing
|
KWinRules KCM Redesign
Summary:
Replacement KCM to configure kwin rules, using a QML-based UI.
After some work on the task T12729, it is almost feature-par with the previous module, and adapted to the recent move to KConfigXT.
Test Plan:
{F8208046}
{F8208047}
Reviewers: #plasma, #kwin, #vdg, ngraham, davidedmundson, zzag
Reviewed By: #plasma, #kwin, #vdg, ngraham, davidedmundson, zzag
Subscribers: ngraham, davidedmundson, hchain, broulik, zzag, kwin
Tags: #kwin, #vdg
Differential Revision: https://phabricator.kde.org/D28152
2020-04-20 20:01:55 +00:00
|
|
|
Layout.alignment: Qt.AlignVCenter
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
onClicked: {
|
|
|
|
model.enabled = true;
|
|
|
|
if (model.suggested != null) {
|
|
|
|
model.value = model.suggested;
|
|
|
|
model.suggested = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
onSheetOpenChanged: {
|
|
|
|
searchField.text = "";
|
|
|
|
if (sheetOpen) {
|
2020-05-30 09:27:04 +00:00
|
|
|
overlayModel.ready = true;
|
KWinRules KCM Redesign
Summary:
Replacement KCM to configure kwin rules, using a QML-based UI.
After some work on the task T12729, it is almost feature-par with the previous module, and adapted to the recent move to KConfigXT.
Test Plan:
{F8208046}
{F8208047}
Reviewers: #plasma, #kwin, #vdg, ngraham, davidedmundson, zzag
Reviewed By: #plasma, #kwin, #vdg, ngraham, davidedmundson, zzag
Subscribers: ngraham, davidedmundson, hchain, broulik, zzag, kwin
Tags: #kwin, #vdg
Differential Revision: https://phabricator.kde.org/D28152
2020-04-20 20:01:55 +00:00
|
|
|
searchField.forceActiveFocus();
|
|
|
|
} else {
|
|
|
|
overlayModel.onlySuggestions = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function formatValue(value, type, options) {
|
|
|
|
if (value == null) {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
switch (type) {
|
|
|
|
case RuleItem.Boolean:
|
|
|
|
return value ? i18n("Yes") : i18n("No");
|
|
|
|
case RuleItem.Percentage:
|
|
|
|
return i18n("%1 %", value);
|
[kcm/kwinrules] Fix size properties not being stored
Summary:
Use `QSize`/`QPoint` to handle and store coordinate values (size and position)
Previously, the rules model stored the "coordinate" type properties as a
`QString` with format `x, y`.
This fails when setting the properties to the config schema, as it requires
a proper `QPoint` or `QSize` value, specially the latter which can't be
convert from such a string.
BUG: 421055
FIXED-IN: 5.19.0
Test Plan:
- Add a new rule and set its position and size properties
- Hitting apply stores the right values in `~\.config\kwinrulesrc`
- Close the kcm and reopen, the values are loaded
- Property detection still works for size and position
Please note that there is a pre-existing bug of some position/sizes not being
applied to the windows in some cases, when using `Apply Initially`.
Better try using the `Force` policy.
Reviewers: ngraham, #kwin, #plasma, zzag
Reviewed By: #kwin, #plasma, zzag
Subscribers: zzag, ltoscano, yurchor, kwin
Tags: #kwin
Differential Revision: https://phabricator.kde.org/D29764
2020-05-14 20:46:15 +00:00
|
|
|
case RuleItem.Point:
|
|
|
|
return i18nc("Coordinates (x, y)", "(%1, %2)", value.x, value.y);
|
|
|
|
case RuleItem.Size:
|
|
|
|
return i18nc("Size (width, height)", "(%1, %2)", value.width, value.height);
|
KWinRules KCM Redesign
Summary:
Replacement KCM to configure kwin rules, using a QML-based UI.
After some work on the task T12729, it is almost feature-par with the previous module, and adapted to the recent move to KConfigXT.
Test Plan:
{F8208046}
{F8208047}
Reviewers: #plasma, #kwin, #vdg, ngraham, davidedmundson, zzag
Reviewed By: #plasma, #kwin, #vdg, ngraham, davidedmundson, zzag
Subscribers: ngraham, davidedmundson, hchain, broulik, zzag, kwin
Tags: #kwin, #vdg
Differential Revision: https://phabricator.kde.org/D28152
2020-04-20 20:01:55 +00:00
|
|
|
case RuleItem.Option:
|
|
|
|
return options.textOfValue(value);
|
2020-06-19 18:56:12 +00:00
|
|
|
case RuleItem.NetTypes:
|
KWinRules KCM Redesign
Summary:
Replacement KCM to configure kwin rules, using a QML-based UI.
After some work on the task T12729, it is almost feature-par with the previous module, and adapted to the recent move to KConfigXT.
Test Plan:
{F8208046}
{F8208047}
Reviewers: #plasma, #kwin, #vdg, ngraham, davidedmundson, zzag
Reviewed By: #plasma, #kwin, #vdg, ngraham, davidedmundson, zzag
Subscribers: ngraham, davidedmundson, hchain, broulik, zzag, kwin
Tags: #kwin, #vdg
Differential Revision: https://phabricator.kde.org/D28152
2020-04-20 20:01:55 +00:00
|
|
|
var selectedValue = value.toString(2).length - 1;
|
|
|
|
return options.textOfValue(selectedValue);
|
|
|
|
}
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
KSortFilterProxyModel {
|
|
|
|
id: enabledRulesModel
|
|
|
|
sourceModel: rulesModel
|
|
|
|
filterRowCallback: (source_row, source_parent) => {
|
|
|
|
var index = sourceModel.index(source_row, 0, source_parent);
|
|
|
|
return sourceModel.data(index, RulesModel.EnabledRole);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KSortFilterProxyModel {
|
|
|
|
id: overlayModel
|
|
|
|
sourceModel: rulesModel
|
|
|
|
|
|
|
|
property bool onlySuggestions: false
|
|
|
|
onOnlySuggestionsChanged: {
|
|
|
|
invalidateFilter();
|
|
|
|
}
|
|
|
|
|
2020-05-30 09:27:04 +00:00
|
|
|
// Delay the model filtering until `ready` is set
|
|
|
|
// FIXME: Workaround https://bugs.kde.org/show_bug.cgi?id=422289
|
|
|
|
property bool ready: false
|
|
|
|
onReadyChanged: {
|
|
|
|
invalidateFilter();
|
|
|
|
}
|
|
|
|
|
KWinRules KCM Redesign
Summary:
Replacement KCM to configure kwin rules, using a QML-based UI.
After some work on the task T12729, it is almost feature-par with the previous module, and adapted to the recent move to KConfigXT.
Test Plan:
{F8208046}
{F8208047}
Reviewers: #plasma, #kwin, #vdg, ngraham, davidedmundson, zzag
Reviewed By: #plasma, #kwin, #vdg, ngraham, davidedmundson, zzag
Subscribers: ngraham, davidedmundson, hchain, broulik, zzag, kwin
Tags: #kwin, #vdg
Differential Revision: https://phabricator.kde.org/D28152
2020-04-20 20:01:55 +00:00
|
|
|
filterString: searchField.text.trim().toLowerCase()
|
|
|
|
filterRowCallback: (source_row, source_parent) => {
|
2020-05-30 09:27:04 +00:00
|
|
|
if (!ready) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
KWinRules KCM Redesign
Summary:
Replacement KCM to configure kwin rules, using a QML-based UI.
After some work on the task T12729, it is almost feature-par with the previous module, and adapted to the recent move to KConfigXT.
Test Plan:
{F8208046}
{F8208047}
Reviewers: #plasma, #kwin, #vdg, ngraham, davidedmundson, zzag
Reviewed By: #plasma, #kwin, #vdg, ngraham, davidedmundson, zzag
Subscribers: ngraham, davidedmundson, hchain, broulik, zzag, kwin
Tags: #kwin, #vdg
Differential Revision: https://phabricator.kde.org/D28152
2020-04-20 20:01:55 +00:00
|
|
|
var index = sourceModel.index(source_row, 0, source_parent);
|
|
|
|
|
|
|
|
var hasSuggestion = sourceModel.data(index, RulesModel.SuggestedValueRole) != null;
|
|
|
|
var isOptional = sourceModel.data(index, RulesModel.SelectableRole);
|
|
|
|
var isEnabled = sourceModel.data(index, RulesModel.EnabledRole);
|
|
|
|
|
|
|
|
var showItem = hasSuggestion || (!onlySuggestions && isOptional && !isEnabled);
|
|
|
|
|
|
|
|
if (!showItem) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (filterString != "") {
|
|
|
|
return sourceModel.data(index, RulesModel.NameRole).toLowerCase().includes(filterString)
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|