From d51b8dc09393cccd6929b4c3d458055dbd59036f Mon Sep 17 00:00:00 2001 From: Roman Gilg Date: Sat, 4 May 2019 16:48:44 +0200 Subject: [PATCH] [decorations] Let KDecoration plugins recommend a border size per default Summary: This is an alternative solution to T8707 and in comparision to D13276 a less drastic change to KWin's default behavior. Instead of changing the border size default for all KDecoration plugins by switching the default from border size Normal to None introduce new functionality, which allows a KDecoration plugin to recommend a border size in its metadata. By default KWin listens for these recommendations and sets the border size accordingly. If there is no metadata recommending a border size, KWin falls back to the current setting of Normal sized borders. A user is able to override the recommendations from the KCM, which has been extended accordingly. Test Plan: Manually with adjusted metadata of Breeze. Reviewers: #kwin, #plasma, #vdg, ngraham Reviewed By: #vdg, ngraham Subscribers: hpereiradacosta, filipf, anemeth, davidedmundson, abetts, graesslin, ngraham, zzag, kwin Tags: #kwin Maniphest Tasks: T8707 Differential Revision: https://phabricator.kde.org/D13284 --- decorations/decorationbridge.cpp | 8 ++++ decorations/decorationbridge.h | 7 ++++ decorations/settings.cpp | 10 ++++- decorations/settings.h | 1 + kcmkwin/kwindecoration/decorationmodel.cpp | 21 +++++++--- kcmkwin/kwindecoration/decorationmodel.h | 4 ++ kcmkwin/kwindecoration/kcm.cpp | 38 ++++++++++++++++++- kcmkwin/kwindecoration/kcm.h | 7 ++++ .../package/contents/ui/main.qml | 26 ++++++++++--- 9 files changed, 110 insertions(+), 12 deletions(-) diff --git a/decorations/decorationbridge.cpp b/decorations/decorationbridge.cpp index 3bf2c4ca38..c257cf1d5e 100644 --- a/decorations/decorationbridge.cpp +++ b/decorations/decorationbridge.cpp @@ -212,6 +212,7 @@ void DecorationBridge::loadMetaData(const QJsonObject &object) { // reset all settings m_blur = false; + m_recommendedBorderSize = QString(); m_theme = QString(); m_defaultTheme = QString(); @@ -226,7 +227,13 @@ void DecorationBridge::loadMetaData(const QJsonObject &object) if (blurIt != decoSettingsMap.end()) { m_blur = blurIt.value().toBool(); } + auto recBorderSizeIt = decoSettingsMap.find(QStringLiteral("recommendedBorderSize")); + if (recBorderSizeIt != decoSettingsMap.end()) { + m_recommendedBorderSize = recBorderSizeIt.value().toString(); + } findTheme(decoSettingsMap); + + Q_EMIT metaDataLoaded(); } void DecorationBridge::findTheme(const QVariantMap &map) @@ -306,6 +313,7 @@ QString DecorationBridge::supportInformation() const QString b; b.append(QStringLiteral("Plugin: %1\n").arg(m_plugin)); b.append(QStringLiteral("Theme: %1\n").arg(m_theme)); + b.append(QStringLiteral("Plugin recommends border size: %1\n").arg(m_recommendedBorderSize.isNull() ? "No" : m_recommendedBorderSize)); b.append(QStringLiteral("Blur: %1\n").arg(m_blur)); const QMetaObject *metaOptions = m_settings->metaObject(); for (int i=0; ipropertyCount(); ++i) { diff --git a/decorations/decorationbridge.h b/decorations/decorationbridge.h index 0dce293dfc..7ab70d8309 100644 --- a/decorations/decorationbridge.h +++ b/decorations/decorationbridge.h @@ -60,6 +60,9 @@ public: bool needsBlur() const { return m_blur; } + QString recommendedBorderSize() const { + return m_recommendedBorderSize; + } bool showToolTips() const { return m_showToolTips; @@ -73,6 +76,9 @@ public: QString supportInformation() const; +Q_SIGNALS: + void metaDataLoaded(); + private: QString readPlugin(); void loadMetaData(const QJsonObject &object); @@ -84,6 +90,7 @@ private: KSharedConfig::Ptr m_lnfConfig; bool m_blur; bool m_showToolTips; + QString m_recommendedBorderSize; QString m_plugin; QString m_defaultTheme; QString m_theme; diff --git a/decorations/settings.cpp b/decorations/settings.cpp index e604fada21..f229b069a9 100644 --- a/decorations/settings.cpp +++ b/decorations/settings.cpp @@ -19,6 +19,7 @@ along with this program. If not, see . *********************************************************************/ #include "settings.h" // KWin +#include "decorationbridge.h" #include "composite.h" #include "virtualdesktops.h" #include "workspace.h" @@ -60,6 +61,7 @@ SettingsImpl::SettingsImpl(KDecoration2::DecorationSettings *parent) } ); connect(Workspace::self(), &Workspace::configChanged, this, &SettingsImpl::readSettings); + connect(DecorationBridge::self(), &DecorationBridge::metaDataLoaded, this, &SettingsImpl::readSettings); } SettingsImpl::~SettingsImpl() = default; @@ -180,7 +182,13 @@ void SettingsImpl::readSettings() m_closeDoubleClickMenu = close; emit decorationSettings()->closeOnDoubleClickOnMenuChanged(m_closeDoubleClickMenu); } - const auto size = stringToSize(config.readEntry("BorderSize", QStringLiteral("Normal"))); + m_autoBorderSize = config.readEntry("BorderSizeAuto", true); + + auto size = stringToSize(config.readEntry("BorderSize", QStringLiteral("Normal"))); + if (m_autoBorderSize) { + /* Falls back to Normal border size, if the plugin does not provide a valid recommendation. */ + size = stringToSize(DecorationBridge::self()->recommendedBorderSize()); + } if (size != m_borderSize) { m_borderSize = size; emit decorationSettings()->borderSizeChanged(m_borderSize); diff --git a/decorations/settings.h b/decorations/settings.h index a35be06efa..f722328c35 100644 --- a/decorations/settings.h +++ b/decorations/settings.h @@ -61,6 +61,7 @@ private: QVector< KDecoration2::DecorationButtonType > m_leftButtons; QVector< KDecoration2::DecorationButtonType > m_rightButtons; KDecoration2::BorderSize m_borderSize; + bool m_autoBorderSize = true; bool m_closeDoubleClickMenu = false; QFont m_font; }; diff --git a/kcmkwin/kwindecoration/decorationmodel.cpp b/kcmkwin/kwindecoration/decorationmodel.cpp index 7568bdd367..9e16821582 100644 --- a/kcmkwin/kwindecoration/decorationmodel.cpp +++ b/kcmkwin/kwindecoration/decorationmodel.cpp @@ -66,6 +66,8 @@ QVariant DecorationsModel::data(const QModelIndex &index, int role) const return d.themeName; case ConfigurationRole: return d.configuration; + case RecommendedBorderSizeRole: + return Utils::borderSizeToString(d.recommendedBorderSize); } return QVariant(); } @@ -76,7 +78,8 @@ QHash< int, QByteArray > DecorationsModel::roleNames() const {Qt::DisplayRole, QByteArrayLiteral("display")}, {PluginNameRole, QByteArrayLiteral("plugin")}, {ThemeNameRole, QByteArrayLiteral("theme")}, - {ConfigurationRole, QByteArrayLiteral("configureable")} + {ConfigurationRole, QByteArrayLiteral("configureable")}, + {RecommendedBorderSizeRole, QByteArrayLiteral("recommendedbordersize")} }); return roles; } @@ -99,6 +102,15 @@ static bool isConfigureable(const QVariantMap &decoSettingsMap) return it.value().toBool(); } +static KDecoration2::BorderSize recommendedBorderSize(const QVariantMap &decoSettingsMap) +{ + auto it = decoSettingsMap.find(QStringLiteral("recommendedBorderSize")); + if (it == decoSettingsMap.end()) { + return KDecoration2::BorderSize::Normal; + } + return Utils::stringToBorderSize(it.value().toString()); +} + static QString themeListKeyword(const QVariantMap &decoSettingsMap) { auto it = decoSettingsMap.find(QStringLiteral("themeListKeyword")); @@ -129,7 +141,7 @@ void DecorationsModel::init() continue; } auto metadata = loader.metaData().value(QStringLiteral("MetaData")).toObject().value(s_pluginName); - bool config = false; + Data data; if (!metadata.isUndefined()) { const auto decoSettingsMap = metadata.toObject().toVariantMap(); const QString &kns = findKNewStuff(decoSettingsMap); @@ -165,13 +177,12 @@ void DecorationsModel::init() // it's a theme engine, we don't want to show this entry continue; } - config = isConfigureable(decoSettingsMap); + data.configuration = isConfigureable(decoSettingsMap); + data.recommendedBorderSize = recommendedBorderSize(decoSettingsMap); } - Data data; data.pluginName = info.pluginName(); data.visibleName = info.name().isEmpty() ? info.pluginName() : info.name(); data.themeName = data.visibleName; - data.configuration = config; m_plugins.emplace_back(std::move(data)); } diff --git a/kcmkwin/kwindecoration/decorationmodel.h b/kcmkwin/kwindecoration/decorationmodel.h index bd68fdf693..54826a48bb 100644 --- a/kcmkwin/kwindecoration/decorationmodel.h +++ b/kcmkwin/kwindecoration/decorationmodel.h @@ -20,6 +20,8 @@ #ifndef KDECORATION_DECORATION_MODEL_H #define KDECORATION_DECORATION_MODEL_H +#include "utils.h" + #include namespace KDecoration2 @@ -36,6 +38,7 @@ public: PluginNameRole = Qt::UserRole + 1, ThemeNameRole, ConfigurationRole, + RecommendedBorderSizeRole, }; public: @@ -61,6 +64,7 @@ private: QString themeName; QString visibleName; bool configuration = false; + KDecoration2::BorderSize recommendedBorderSize = KDecoration2::BorderSize::Normal; }; std::vector m_plugins; QStringList m_knsProviders; diff --git a/kcmkwin/kwindecoration/kcm.cpp b/kcmkwin/kwindecoration/kcm.cpp index b25929ed7f..3a68c866e9 100644 --- a/kcmkwin/kwindecoration/kcm.cpp +++ b/kcmkwin/kwindecoration/kcm.cpp @@ -49,12 +49,15 @@ const QString s_configGroup { QStringLiteral("org.kde.kdecoration2") }; const QString s_configPlugin { QStringLiteral("library") }; const QString s_configTheme { QStringLiteral("theme") }; const QString s_configBorderSize { QStringLiteral("BorderSize") }; +const QString s_configBorderSizeAuto { QStringLiteral("BorderSizeAuto") }; const QString s_configCloseOnDoubleClickOnMenu { QStringLiteral("CloseOnDoubleClickOnMenu") }; const QString s_configShowToolTips { QStringLiteral("ShowToolTips") }; const QString s_configDecoButtonsOnLeft { QStringLiteral("ButtonsOnLeft") }; const QString s_configDecoButtonsOnRight { QStringLiteral("ButtonsOnRight") }; const KDecoration2::BorderSize s_defaultBorderSize = KDecoration2::BorderSize::Normal; +const KDecoration2::BorderSize s_defaultRecommendedBorderSize = KDecoration2::BorderSize::Normal; +const bool s_defaultBorderSizeAuto = true; const bool s_defaultCloseOnDoubleClickOnMenu = false; const bool s_defaultShowToolTips = true; @@ -85,7 +88,7 @@ KCMKWinDecoration::KCMKWinDecoration(QObject *parent, const QVariantList &argume , m_leftButtonsModel(new KDecoration2::Preview::ButtonsModel(DecorationButtonsList(), this)) , m_rightButtonsModel(new KDecoration2::Preview::ButtonsModel(DecorationButtonsList(), this)) , m_availableButtonsModel(new KDecoration2::Preview::ButtonsModel(this)) - , m_savedSettings{ s_defaultBorderSize, -2 /* for setTheme() */, false, s_defaultShowToolTips, s_defaultDecoButtonsOnLeft, s_defaultDecoButtonsOnRight } + , m_savedSettings{ s_defaultBorderSize, s_defaultBorderSizeAuto, -2 /* for setTheme() */, false, s_defaultShowToolTips, s_defaultDecoButtonsOnLeft, s_defaultDecoButtonsOnRight } , m_currentSettings(m_savedSettings) { auto about = new KAboutData(QStringLiteral("kcm_kwindecoration"), @@ -166,6 +169,7 @@ void KCMKWinDecoration::load() const QString defaultSizeName = Utils::borderSizeToString(s_defaultBorderSize); setBorderSize(Utils::stringToBorderSize(config.readEntry(s_configBorderSize, defaultSizeName))); + setBorderSizeAuto(config.readEntry(s_configBorderSizeAuto, s_defaultBorderSizeAuto)); m_leftButtonsModel->replace(Utils::readDecorationButtons(config, s_configDecoButtonsOnLeft, s_defaultDecoButtonsOnLeft)); m_rightButtonsModel->replace(Utils::readDecorationButtons(config, s_configDecoButtonsOnRight, s_defaultDecoButtonsOnRight)); @@ -197,6 +201,7 @@ void KCMKWinDecoration::save() config.writeEntry(s_configCloseOnDoubleClickOnMenu, m_currentSettings.closeOnDoubleClickOnMenu); config.writeEntry(s_configShowToolTips, m_currentSettings.showToolTips); config.writeEntry(s_configBorderSize, Utils::borderSizeToString(m_currentSettings.borderSize)); + config.writeEntry(s_configBorderSizeAuto, m_currentSettings.borderSizeAuto); config.writeEntry(s_configDecoButtonsOnLeft, Utils::buttonsToString(m_currentSettings.buttonsOnLeft)); config.writeEntry(s_configDecoButtonsOnRight, Utils::buttonsToString(m_currentSettings.buttonsOnRight)); config.sync(); @@ -220,6 +225,7 @@ void KCMKWinDecoration::defaults() } setTheme(themeIndex); setBorderSize(s_defaultBorderSize); + setBorderSizeAuto(s_defaultBorderSizeAuto); setCloseOnDoubleClickOnMenu(s_defaultCloseOnDoubleClickOnMenu); setShowToolTips(s_defaultShowToolTips); @@ -237,6 +243,7 @@ void KCMKWinDecoration::updateNeedsSave() setNeedsSave(m_savedSettings.closeOnDoubleClickOnMenu != m_currentSettings.closeOnDoubleClickOnMenu || m_savedSettings.showToolTips != m_currentSettings.showToolTips || m_savedSettings.borderSize != m_currentSettings.borderSize + || m_savedSettings.borderSizeAuto != m_currentSettings.borderSizeAuto || m_savedSettings.themeIndex != m_currentSettings.themeIndex || m_savedSettings.buttonsOnLeft != m_currentSettings.buttonsOnLeft || m_savedSettings.buttonsOnRight != m_currentSettings.buttonsOnRight); @@ -272,6 +279,25 @@ int KCMKWinDecoration::borderSize() const return Utils::getBorderSizeNames().keys().indexOf(m_currentSettings.borderSize); } +int KCMKWinDecoration::recommendedBorderSize() const +{ + typedef KDecoration2::Configuration::DecorationsModel::DecorationRole DecoRole; + const QModelIndex proxyIndex = m_proxyThemesModel->index(m_currentSettings.themeIndex, 0); + if (proxyIndex.isValid()) { + const QModelIndex index = m_proxyThemesModel->mapToSource(proxyIndex); + if (index.isValid()) { + QVariant ret = m_themesModel->data(index, DecoRole::RecommendedBorderSizeRole); + return Utils::getBorderSizeNames().keys().indexOf(Utils::stringToBorderSize(ret.toString())); + } + } + return Utils::getBorderSizeNames().keys().indexOf(s_defaultRecommendedBorderSize); +} + +bool KCMKWinDecoration::borderSizeAuto() const +{ + return m_currentSettings.borderSizeAuto; +} + int KCMKWinDecoration::theme() const { return m_currentSettings.themeIndex; @@ -302,6 +328,16 @@ void KCMKWinDecoration::setBorderSize(KDecoration2::BorderSize size) updateNeedsSave(); } +void KCMKWinDecoration::setBorderSizeAuto(bool set) +{ + if (m_currentSettings.borderSizeAuto == set) { + return; + } + m_currentSettings.borderSizeAuto = set; + emit borderSizeAutoChanged(); + updateNeedsSave(); +} + void KCMKWinDecoration::setTheme(int index) { // The initial themeIndex is set to -2 to always initially apply a theme, any theme diff --git a/kcmkwin/kwindecoration/kcm.h b/kcmkwin/kwindecoration/kcm.h index 648e7de315..ba0534f783 100644 --- a/kcmkwin/kwindecoration/kcm.h +++ b/kcmkwin/kwindecoration/kcm.h @@ -52,6 +52,8 @@ class KCMKWinDecoration : public KQuickAddons::ConfigModule Q_PROPERTY(QSortFilterProxyModel *themesModel READ themesModel CONSTANT) Q_PROPERTY(QStringList borderSizesModel READ borderSizesModel CONSTANT) Q_PROPERTY(int borderSize READ borderSize WRITE setBorderSize NOTIFY borderSizeChanged) + Q_PROPERTY(int recommendedBorderSize READ recommendedBorderSize CONSTANT) + Q_PROPERTY(bool borderSizeAuto READ borderSizeAuto WRITE setBorderSizeAuto NOTIFY borderSizeAutoChanged) Q_PROPERTY(int theme READ theme WRITE setTheme NOTIFY themeChanged) Q_PROPERTY(QAbstractListModel *leftButtonsModel READ leftButtonsModel NOTIFY buttonsChanged) Q_PROPERTY(QAbstractListModel *rightButtonsModel READ rightButtonsModel NOTIFY buttonsChanged) @@ -68,12 +70,15 @@ public: QAbstractListModel *availableButtonsModel() const; QStringList borderSizesModel() const; int borderSize() const; + int recommendedBorderSize() const; + bool borderSizeAuto() const; int theme() const; bool closeOnDoubleClickOnMenu() const; bool showToolTips() const; void setBorderSize(int index); void setBorderSize(KDecoration2::BorderSize size); + void setBorderSizeAuto(bool set); void setTheme(int index); void setCloseOnDoubleClickOnMenu(bool enable); void setShowToolTips(bool show); @@ -84,6 +89,7 @@ Q_SIGNALS: void themeChanged(); void buttonsChanged(); void borderSizeChanged(); + void borderSizeAutoChanged(); void closeOnDoubleClickOnMenuChanged(); void showToolTipsChanged(); @@ -109,6 +115,7 @@ private: struct Settings { KDecoration2::BorderSize borderSize; + bool borderSizeAuto; int themeIndex; bool closeOnDoubleClickOnMenu; bool showToolTips; diff --git a/kcmkwin/kwindecoration/package/contents/ui/main.qml b/kcmkwin/kwindecoration/package/contents/ui/main.qml index 3d918acf2d..2afb3647b0 100644 --- a/kcmkwin/kwindecoration/package/contents/ui/main.qml +++ b/kcmkwin/kwindecoration/package/contents/ui/main.qml @@ -74,18 +74,34 @@ Kirigami.Page { } RowLayout { - Controls.Label { - Layout.alignment: Qt.AlignRight - text: i18nc("combobox label", "Window border size:") + Controls.CheckBox { + id: borderSizeAutoCheckbox + text: i18nc("checkbox label", "Use theme's default window border size") + checked: kcm.borderSizeAuto + onCheckedChanged: { + kcm.borderSizeAuto = checked; + borderSizeComboBox.autoBorderUpdate() + } } - Controls.ComboBox { id: borderSizeComboBox + enabled: !borderSizeAutoCheckbox.checked model: kcm.borderSizesModel - currentIndex: kcm.borderSize onActivated: { kcm.borderSize = currentIndex } + function autoBorderUpdate() { + if (borderSizeAutoCheckbox.checked) { + currentIndex = kcm.recommendedBorderSize + } else { + currentIndex = kcm.borderSize + } + } + + Connections { + target: kcm + onThemeChanged: borderSizeComboBox.autoBorderUpdate() + } } Item { Layout.fillWidth: true