File indexing completed on 2024-11-10 04:56:48
0001 /* 0002 SPDX-FileCopyrightText: 2019 Valerio Pilo <vpilo@coldshock.net> 0003 SPDX-FileCopyrightText: 2019 Cyril Rossi <cyril.rossi@enioka.com> 0004 0005 SPDX-License-Identifier: LGPL-2.0-only 0006 */ 0007 #include "kcm.h" 0008 0009 #include <config-kwin.h> 0010 0011 #include "declarative-plugin/buttonsmodel.h" 0012 #include "decorationmodel.h" 0013 0014 #include <KConfigGroup> 0015 #include <KLocalizedString> 0016 #include <KPluginFactory> 0017 0018 #include <QDBusConnection> 0019 #include <QDBusMessage> 0020 #include <QDebug> 0021 #include <QQuickItem> 0022 #include <QQuickWindow> 0023 #include <QSortFilterProxyModel> 0024 0025 #include "kwindecorationdata.h" 0026 #include "kwindecorationsettings.h" 0027 #include "utils.h" 0028 0029 K_PLUGIN_FACTORY_WITH_JSON(KCMKWinDecorationFactory, "kcm_kwindecoration.json", registerPlugin<KCMKWinDecoration>(); registerPlugin<KWinDecorationData>();) 0030 0031 Q_DECLARE_METATYPE(KDecoration2::BorderSize) 0032 0033 namespace 0034 { 0035 const KDecoration2::BorderSize s_defaultRecommendedBorderSize = KDecoration2::BorderSize::Normal; 0036 } 0037 0038 KCMKWinDecoration::KCMKWinDecoration(QObject *parent, const KPluginMetaData &metaData) 0039 : KQuickManagedConfigModule(parent, metaData) 0040 , m_themesModel(new KDecoration2::Configuration::DecorationsModel(this)) 0041 , m_proxyThemesModel(new QSortFilterProxyModel(this)) 0042 , m_leftButtonsModel(new KDecoration2::Preview::ButtonsModel(DecorationButtonsList(), this)) 0043 , m_rightButtonsModel(new KDecoration2::Preview::ButtonsModel(DecorationButtonsList(), this)) 0044 , m_availableButtonsModel(new KDecoration2::Preview::ButtonsModel(this)) 0045 , m_data(new KWinDecorationData(this)) 0046 { 0047 setButtons(Apply | Default | Help); 0048 qmlRegisterAnonymousType<QAbstractListModel>("org.kde.kwin.KWinDecoration", 1); 0049 qmlRegisterAnonymousType<QSortFilterProxyModel>("org.kde.kwin.KWinDecoration", 1); 0050 qmlRegisterAnonymousType<KWinDecorationSettings>("org.kde.kwin.KWinDecoration", 1); 0051 m_proxyThemesModel->setSourceModel(m_themesModel); 0052 m_proxyThemesModel->setFilterCaseSensitivity(Qt::CaseInsensitive); 0053 m_proxyThemesModel->setSortCaseSensitivity(Qt::CaseInsensitive); 0054 m_proxyThemesModel->sort(0); 0055 0056 connect(m_proxyThemesModel, &QSortFilterProxyModel::rowsInserted, this, &KCMKWinDecoration::themeChanged); 0057 connect(m_proxyThemesModel, &QSortFilterProxyModel::rowsRemoved, this, &KCMKWinDecoration::themeChanged); 0058 connect(m_proxyThemesModel, &QSortFilterProxyModel::modelReset, this, &KCMKWinDecoration::themeChanged); 0059 0060 connect(m_data->settings(), &KWinDecorationSettings::themeChanged, this, &KCMKWinDecoration::themeChanged); 0061 connect(m_data->settings(), &KWinDecorationSettings::borderSizeChanged, this, &KCMKWinDecoration::borderSizeChanged); 0062 0063 connect(m_data->settings(), &KWinDecorationSettings::borderSizeAutoChanged, this, &KCMKWinDecoration::borderIndexChanged); 0064 connect(this, &KCMKWinDecoration::borderSizeChanged, this, &KCMKWinDecoration::borderIndexChanged); 0065 connect(this, &KCMKWinDecoration::themeChanged, this, &KCMKWinDecoration::borderIndexChanged); 0066 0067 connect(this, &KCMKWinDecoration::themeChanged, this, [this]() { 0068 if (m_data->settings()->borderSizeAuto()) { 0069 setBorderSize(recommendedBorderSize()); 0070 } 0071 }); 0072 0073 connect(m_leftButtonsModel, &QAbstractItemModel::rowsInserted, this, &KCMKWinDecoration::onLeftButtonsChanged); 0074 connect(m_leftButtonsModel, &QAbstractItemModel::rowsMoved, this, &KCMKWinDecoration::onLeftButtonsChanged); 0075 connect(m_leftButtonsModel, &QAbstractItemModel::rowsRemoved, this, &KCMKWinDecoration::onLeftButtonsChanged); 0076 connect(m_leftButtonsModel, &QAbstractItemModel::modelReset, this, &KCMKWinDecoration::onLeftButtonsChanged); 0077 0078 connect(m_rightButtonsModel, &QAbstractItemModel::rowsInserted, this, &KCMKWinDecoration::onRightButtonsChanged); 0079 connect(m_rightButtonsModel, &QAbstractItemModel::rowsMoved, this, &KCMKWinDecoration::onRightButtonsChanged); 0080 connect(m_rightButtonsModel, &QAbstractItemModel::rowsRemoved, this, &KCMKWinDecoration::onRightButtonsChanged); 0081 connect(m_rightButtonsModel, &QAbstractItemModel::modelReset, this, &KCMKWinDecoration::onRightButtonsChanged); 0082 0083 connect(this, &KCMKWinDecoration::borderSizeChanged, this, &KCMKWinDecoration::settingsChanged); 0084 0085 // Update the themes when the color scheme or a theme's settings change 0086 QDBusConnection::sessionBus() 0087 .connect(QString(), QStringLiteral("/KWin"), QStringLiteral("org.kde.KWin"), QStringLiteral("reloadConfig"), 0088 this, SLOT(reloadKWinSettings())); 0089 0090 QMetaObject::invokeMethod(m_themesModel, &KDecoration2::Configuration::DecorationsModel::init, Qt::QueuedConnection); 0091 } 0092 0093 KWinDecorationSettings *KCMKWinDecoration::settings() const 0094 { 0095 return m_data->settings(); 0096 } 0097 0098 void KCMKWinDecoration::reloadKWinSettings() 0099 { 0100 QMetaObject::invokeMethod(m_themesModel, &KDecoration2::Configuration::DecorationsModel::init, Qt::QueuedConnection); 0101 } 0102 0103 void KCMKWinDecoration::load() 0104 { 0105 KQuickManagedConfigModule::load(); 0106 0107 m_leftButtonsModel->replace(Utils::buttonsFromString(settings()->buttonsOnLeft())); 0108 m_rightButtonsModel->replace(Utils::buttonsFromString(settings()->buttonsOnRight())); 0109 0110 setBorderSize(borderSizeIndexFromString(settings()->borderSize())); 0111 0112 Q_EMIT themeChanged(); 0113 } 0114 0115 void KCMKWinDecoration::save() 0116 { 0117 if (!settings()->borderSizeAuto()) { 0118 settings()->setBorderSize(borderSizeIndexToString(m_borderSizeIndex)); 0119 } else { 0120 settings()->setBorderSize(settings()->defaultBorderSizeValue()); 0121 } 0122 0123 KQuickManagedConfigModule::save(); 0124 0125 // Send a signal to all kwin instances 0126 QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/KWin"), 0127 QStringLiteral("org.kde.KWin"), 0128 QStringLiteral("reloadConfig")); 0129 QDBusConnection::sessionBus().send(message); 0130 } 0131 0132 void KCMKWinDecoration::defaults() 0133 { 0134 KQuickManagedConfigModule::defaults(); 0135 0136 setBorderSize(recommendedBorderSize()); 0137 0138 m_leftButtonsModel->replace(Utils::buttonsFromString(settings()->buttonsOnLeft())); 0139 m_rightButtonsModel->replace(Utils::buttonsFromString(settings()->buttonsOnRight())); 0140 } 0141 0142 void KCMKWinDecoration::onLeftButtonsChanged() 0143 { 0144 settings()->setButtonsOnLeft(Utils::buttonsToString(m_leftButtonsModel->buttons())); 0145 } 0146 0147 void KCMKWinDecoration::onRightButtonsChanged() 0148 { 0149 settings()->setButtonsOnRight(Utils::buttonsToString(m_rightButtonsModel->buttons())); 0150 } 0151 0152 QSortFilterProxyModel *KCMKWinDecoration::themesModel() const 0153 { 0154 return m_proxyThemesModel; 0155 } 0156 0157 QAbstractListModel *KCMKWinDecoration::leftButtonsModel() 0158 { 0159 return m_leftButtonsModel; 0160 } 0161 0162 QAbstractListModel *KCMKWinDecoration::rightButtonsModel() 0163 { 0164 return m_rightButtonsModel; 0165 } 0166 0167 QAbstractListModel *KCMKWinDecoration::availableButtonsModel() const 0168 { 0169 return m_availableButtonsModel; 0170 } 0171 0172 QStringList KCMKWinDecoration::borderSizesModel() const 0173 { 0174 // Use index 0 for borderSizeAuto == true 0175 // The rest of indexes get offset by 1 0176 QStringList model = Utils::getBorderSizeNames().values(); 0177 model.insert(0, i18nc("%1 is the name of a border size", "Theme's default (%1)", model.at(recommendedBorderSize()))); 0178 return model; 0179 } 0180 0181 int KCMKWinDecoration::borderIndex() const 0182 { 0183 return settings()->borderSizeAuto() ? 0 : m_borderSizeIndex + 1; 0184 } 0185 0186 void KCMKWinDecoration::setBorderIndex(int index) 0187 { 0188 const bool borderAuto = (index == 0); 0189 settings()->setBorderSizeAuto(borderAuto); 0190 setBorderSize(borderAuto ? recommendedBorderSize() : index - 1); 0191 } 0192 0193 int KCMKWinDecoration::borderSize() const 0194 { 0195 return m_borderSizeIndex; 0196 } 0197 0198 int KCMKWinDecoration::recommendedBorderSize() const 0199 { 0200 typedef KDecoration2::Configuration::DecorationsModel::DecorationRole DecoRole; 0201 const QModelIndex proxyIndex = m_proxyThemesModel->index(theme(), 0); 0202 if (proxyIndex.isValid()) { 0203 const QModelIndex index = m_proxyThemesModel->mapToSource(proxyIndex); 0204 if (index.isValid()) { 0205 QVariant ret = m_themesModel->data(index, DecoRole::RecommendedBorderSizeRole); 0206 return Utils::getBorderSizeNames().keys().indexOf(Utils::stringToBorderSize(ret.toString())); 0207 } 0208 } 0209 return Utils::getBorderSizeNames().keys().indexOf(s_defaultRecommendedBorderSize); 0210 } 0211 0212 int KCMKWinDecoration::theme() const 0213 { 0214 return m_proxyThemesModel->mapFromSource(m_themesModel->findDecoration(settings()->pluginName(), settings()->theme())).row(); 0215 } 0216 0217 void KCMKWinDecoration::setBorderSize(int index) 0218 { 0219 if (m_borderSizeIndex != index) { 0220 m_borderSizeIndex = index; 0221 Q_EMIT borderSizeChanged(); 0222 } 0223 } 0224 0225 void KCMKWinDecoration::setBorderSize(KDecoration2::BorderSize size) 0226 { 0227 settings()->setBorderSize(Utils::borderSizeToString(size)); 0228 } 0229 0230 void KCMKWinDecoration::setTheme(int index) 0231 { 0232 QModelIndex dataIndex = m_proxyThemesModel->index(index, 0); 0233 if (dataIndex.isValid()) { 0234 settings()->setTheme(m_proxyThemesModel->data(dataIndex, KDecoration2::Configuration::DecorationsModel::ThemeNameRole).toString()); 0235 settings()->setPluginName(m_proxyThemesModel->data(dataIndex, KDecoration2::Configuration::DecorationsModel::PluginNameRole).toString()); 0236 Q_EMIT themeChanged(); 0237 } 0238 } 0239 0240 bool KCMKWinDecoration::isSaveNeeded() const 0241 { 0242 return !settings()->borderSizeAuto() && borderSizeIndexFromString(settings()->borderSize()) != m_borderSizeIndex; 0243 } 0244 0245 int KCMKWinDecoration::borderSizeIndexFromString(const QString &size) const 0246 { 0247 return Utils::getBorderSizeNames().keys().indexOf(Utils::stringToBorderSize(size)); 0248 } 0249 0250 QString KCMKWinDecoration::borderSizeIndexToString(int index) const 0251 { 0252 return Utils::borderSizeToString(Utils::getBorderSizeNames().keys().at(index)); 0253 } 0254 0255 #include "kcm.moc" 0256 #include "moc_kcm.cpp"