[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
This commit is contained in:
Roman Gilg 2019-05-04 16:48:44 +02:00
parent 82b9d3b59e
commit d51b8dc093
9 changed files with 110 additions and 12 deletions

View file

@ -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; i<metaOptions->propertyCount(); ++i) {

View file

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

View file

@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#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);

View file

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

View file

@ -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));
}

View file

@ -20,6 +20,8 @@
#ifndef KDECORATION_DECORATION_MODEL_H
#define KDECORATION_DECORATION_MODEL_H
#include "utils.h"
#include <QAbstractListModel>
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<Data> m_plugins;
QStringList m_knsProviders;

View file

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

View file

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

View file

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