82b3e2a63a
Summary: In KDE 4, there was a very handy option to disable decoration tooltips. Decoration tooltips were lost in transition to KDE Plasma 5, and so the option. Given that decoration tooltips were brought back to KDE Plasma 5, "Show decoration button tooltips" option can be still useful for people(like me) who may wish to disable them because of personal preference. Reviewers: #kwin, broulik, mart Reviewed By: #kwin, mart Subscribers: ngraham, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D19152
336 lines
13 KiB
C++
336 lines
13 KiB
C++
/*
|
|
* Copyright (c) 2019 Valerio Pilo <vpilo@coldshock.net>
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Library General Public
|
|
* License version 2 as published by the Free Software Foundation.
|
|
*
|
|
* This library 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
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public License
|
|
* along with this library; see the file COPYING.LIB. If not, write to
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "kcm.h"
|
|
#include "decorationmodel.h"
|
|
#include "declarative-plugin/buttonsmodel.h"
|
|
#include <config-kwin.h>
|
|
|
|
#include <KAboutData>
|
|
#include <KConfigGroup>
|
|
#include <KLocalizedString>
|
|
#include <KPluginFactory>
|
|
#include <KNSCore/Engine>
|
|
|
|
#include <QDBusConnection>
|
|
#include <QDBusMessage>
|
|
#include <QDebug>
|
|
#include <QQuickItem>
|
|
#include <QQuickWindow>
|
|
#include <QSortFilterProxyModel>
|
|
|
|
#include <KNewStuff3/KNS3/DownloadDialog>
|
|
|
|
|
|
K_PLUGIN_FACTORY_WITH_JSON(KCMKWinDecorationFactory, "kwindecoration.json", registerPlugin<KCMKWinDecoration>();)
|
|
|
|
Q_DECLARE_METATYPE(KDecoration2::BorderSize)
|
|
|
|
|
|
namespace
|
|
{
|
|
const QString s_configFile { QStringLiteral("kwinrc") };
|
|
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_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 bool s_defaultCloseOnDoubleClickOnMenu = false;
|
|
const bool s_defaultShowToolTips = true;
|
|
|
|
const DecorationButtonsList s_defaultDecoButtonsOnLeft {
|
|
KDecoration2::DecorationButtonType::Menu,
|
|
KDecoration2::DecorationButtonType::OnAllDesktops
|
|
};
|
|
const DecorationButtonsList s_defaultDecoButtonsOnRight {
|
|
KDecoration2::DecorationButtonType::ContextHelp,
|
|
KDecoration2::DecorationButtonType::Minimize,
|
|
KDecoration2::DecorationButtonType::Maximize,
|
|
KDecoration2::DecorationButtonType::Close
|
|
};
|
|
|
|
#if HAVE_BREEZE_DECO
|
|
const QString s_defaultPlugin { QStringLiteral(BREEZE_KDECORATION_PLUGIN_ID) };
|
|
const QString s_defaultTheme { QStringLiteral("Breeze") };
|
|
#else
|
|
const QString s_defaultPlugin { QStringLiteral("org.kde.kwin.aurorae") };
|
|
const QString s_defaultTheme { QStringLiteral("kwin4_decoration_qml_plastik") };
|
|
#endif
|
|
}
|
|
|
|
KCMKWinDecoration::KCMKWinDecoration(QObject *parent, const QVariantList &arguments)
|
|
: KQuickAddons::ConfigModule(parent, arguments)
|
|
, m_themesModel(new KDecoration2::Configuration::DecorationsModel(this))
|
|
, m_proxyThemesModel(new QSortFilterProxyModel(this))
|
|
, 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_currentSettings(m_savedSettings)
|
|
{
|
|
auto about = new KAboutData(QStringLiteral("kcm_kwindecoration"),
|
|
i18n("Window Decorations"),
|
|
QStringLiteral("1.0"),
|
|
QString(),
|
|
KAboutLicense::GPL);
|
|
about->addAuthor(i18n("Valerio Pilo"),
|
|
i18n("Author"),
|
|
QStringLiteral("vpilo@coldshock.net"));
|
|
setAboutData(about);
|
|
|
|
qmlRegisterType<QAbstractListModel>();
|
|
qmlRegisterType<QSortFilterProxyModel>();
|
|
|
|
m_proxyThemesModel->setSourceModel(m_themesModel);
|
|
m_proxyThemesModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
|
m_proxyThemesModel->setSortCaseSensitivity(Qt::CaseInsensitive);
|
|
m_proxyThemesModel->sort(0);
|
|
|
|
connect(m_leftButtonsModel, &QAbstractItemModel::rowsInserted, this, &KCMKWinDecoration::updateNeedsSave);
|
|
connect(m_leftButtonsModel, &QAbstractItemModel::rowsMoved, this, &KCMKWinDecoration::updateNeedsSave);
|
|
connect(m_leftButtonsModel, &QAbstractItemModel::rowsRemoved, this, &KCMKWinDecoration::updateNeedsSave);
|
|
connect(m_leftButtonsModel, &QAbstractItemModel::modelReset, this, &KCMKWinDecoration::updateNeedsSave);
|
|
connect(m_rightButtonsModel, &QAbstractItemModel::rowsInserted, this, &KCMKWinDecoration::updateNeedsSave);
|
|
connect(m_rightButtonsModel, &QAbstractItemModel::rowsMoved, this, &KCMKWinDecoration::updateNeedsSave);
|
|
connect(m_rightButtonsModel, &QAbstractItemModel::rowsRemoved, this, &KCMKWinDecoration::updateNeedsSave);
|
|
connect(m_rightButtonsModel, &QAbstractItemModel::modelReset, this, &KCMKWinDecoration::updateNeedsSave);
|
|
|
|
// Update the themes when the color scheme or a theme's settings change
|
|
QDBusConnection::sessionBus()
|
|
.connect(QString(), QStringLiteral("/KWin"), QStringLiteral("org.kde.KWin"), QStringLiteral("reloadConfig"),
|
|
this, SLOT(reloadKWinSettings()));
|
|
|
|
QMetaObject::invokeMethod(m_themesModel, "init", Qt::QueuedConnection);
|
|
}
|
|
|
|
void KCMKWinDecoration::reloadKWinSettings()
|
|
{
|
|
QMetaObject::invokeMethod(m_themesModel, "init", Qt::QueuedConnection);
|
|
}
|
|
|
|
void KCMKWinDecoration::getNewStuff(QQuickItem *context)
|
|
{
|
|
if (!m_newStuffDialog) {
|
|
m_newStuffDialog = new KNS3::DownloadDialog(QStringLiteral("window-decorations.knsrc"));
|
|
m_newStuffDialog->setWindowTitle(i18n("Download New Window Decorations"));
|
|
m_newStuffDialog->setWindowModality(Qt::WindowModal);
|
|
connect(m_newStuffDialog, &KNS3::DownloadDialog::accepted, this, &KCMKWinDecoration::load);
|
|
}
|
|
|
|
if (context && context->window()) {
|
|
m_newStuffDialog->winId(); // so it creates the windowHandle()
|
|
m_newStuffDialog->windowHandle()->setTransientParent(context->window());
|
|
}
|
|
|
|
connect(m_newStuffDialog, &QDialog::finished, this, &KCMKWinDecoration::reloadKWinSettings);
|
|
|
|
m_newStuffDialog->show();
|
|
}
|
|
|
|
void KCMKWinDecoration::load()
|
|
{
|
|
const KConfigGroup config = KSharedConfig::openConfig(s_configFile)->group(s_configGroup);
|
|
|
|
const QString plugin = config.readEntry(s_configPlugin, s_defaultPlugin);
|
|
const QString theme = config.readEntry(s_configTheme, s_defaultTheme);
|
|
int themeIndex = m_proxyThemesModel->mapFromSource(m_themesModel->findDecoration(plugin, theme)).row();
|
|
if (themeIndex < 0) {
|
|
qWarning() << "Plugin" << plugin << "and theme" << theme << "not found";
|
|
} else {
|
|
qDebug() << "Current theme: plugin" << plugin << "and theme" << theme;
|
|
}
|
|
setTheme(themeIndex);
|
|
|
|
setCloseOnDoubleClickOnMenu(config.readEntry(s_configCloseOnDoubleClickOnMenu, s_defaultCloseOnDoubleClickOnMenu));
|
|
setShowToolTips(config.readEntry(s_configShowToolTips, s_defaultShowToolTips));
|
|
|
|
const QString defaultSizeName = Utils::borderSizeToString(s_defaultBorderSize);
|
|
setBorderSize(Utils::stringToBorderSize(config.readEntry(s_configBorderSize, defaultSizeName)));
|
|
|
|
m_leftButtonsModel->replace(Utils::readDecorationButtons(config, s_configDecoButtonsOnLeft, s_defaultDecoButtonsOnLeft));
|
|
m_rightButtonsModel->replace(Utils::readDecorationButtons(config, s_configDecoButtonsOnRight, s_defaultDecoButtonsOnRight));
|
|
m_currentSettings.buttonsOnLeft = m_leftButtonsModel->buttons();
|
|
m_currentSettings.buttonsOnRight = m_rightButtonsModel->buttons();
|
|
|
|
m_savedSettings = m_currentSettings;
|
|
|
|
updateNeedsSave();
|
|
}
|
|
|
|
void KCMKWinDecoration::save()
|
|
{
|
|
KConfigGroup config = KSharedConfig::openConfig(s_configFile)->group(s_configGroup);
|
|
|
|
if (m_currentSettings.themeIndex >= 0) {
|
|
const QModelIndex index = m_proxyThemesModel->index(m_currentSettings.themeIndex, 0);
|
|
if (index.isValid()) {
|
|
const QString plugin = index.data(KDecoration2::Configuration::DecorationsModel::PluginNameRole).toString();
|
|
const QString theme = index.data(KDecoration2::Configuration::DecorationsModel::ThemeNameRole).toString();
|
|
config.writeEntry(s_configPlugin, plugin);
|
|
config.writeEntry(s_configTheme, theme);
|
|
qDebug() << "Saved theme: plugin" << plugin << "and theme" << theme;
|
|
} else {
|
|
qWarning() << "Cannot match theme index" << m_currentSettings.themeIndex << "in model";
|
|
}
|
|
}
|
|
|
|
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_configDecoButtonsOnLeft, Utils::buttonsToString(m_currentSettings.buttonsOnLeft));
|
|
config.writeEntry(s_configDecoButtonsOnRight, Utils::buttonsToString(m_currentSettings.buttonsOnRight));
|
|
config.sync();
|
|
|
|
m_savedSettings = m_currentSettings;
|
|
|
|
// Send a signal to all kwin instances
|
|
QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/KWin"),
|
|
QStringLiteral("org.kde.KWin"),
|
|
QStringLiteral("reloadConfig"));
|
|
QDBusConnection::sessionBus().send(message);
|
|
|
|
updateNeedsSave();
|
|
}
|
|
|
|
void KCMKWinDecoration::defaults()
|
|
{
|
|
int themeIndex = m_proxyThemesModel->mapFromSource(m_themesModel->findDecoration(s_defaultPlugin, s_defaultTheme)).row();
|
|
if (themeIndex < 0) {
|
|
qWarning() << "Default plugin" << s_defaultPlugin << "and theme" << s_defaultTheme << "not found";
|
|
}
|
|
setTheme(themeIndex);
|
|
setBorderSize(s_defaultBorderSize);
|
|
setCloseOnDoubleClickOnMenu(s_defaultCloseOnDoubleClickOnMenu);
|
|
setShowToolTips(s_defaultShowToolTips);
|
|
|
|
m_leftButtonsModel->replace(s_defaultDecoButtonsOnLeft);
|
|
m_rightButtonsModel->replace(s_defaultDecoButtonsOnRight);
|
|
|
|
updateNeedsSave();
|
|
}
|
|
|
|
void KCMKWinDecoration::updateNeedsSave()
|
|
{
|
|
m_currentSettings.buttonsOnLeft = m_leftButtonsModel->buttons();
|
|
m_currentSettings.buttonsOnRight = m_rightButtonsModel->buttons();
|
|
|
|
setNeedsSave(m_savedSettings.closeOnDoubleClickOnMenu != m_currentSettings.closeOnDoubleClickOnMenu
|
|
|| m_savedSettings.showToolTips != m_currentSettings.showToolTips
|
|
|| m_savedSettings.borderSize != m_currentSettings.borderSize
|
|
|| m_savedSettings.themeIndex != m_currentSettings.themeIndex
|
|
|| m_savedSettings.buttonsOnLeft != m_currentSettings.buttonsOnLeft
|
|
|| m_savedSettings.buttonsOnRight != m_currentSettings.buttonsOnRight);
|
|
}
|
|
|
|
QSortFilterProxyModel *KCMKWinDecoration::themesModel() const
|
|
{
|
|
return m_proxyThemesModel;
|
|
}
|
|
|
|
QAbstractListModel *KCMKWinDecoration::leftButtonsModel()
|
|
{
|
|
return m_leftButtonsModel;
|
|
}
|
|
|
|
QAbstractListModel *KCMKWinDecoration::rightButtonsModel()
|
|
{
|
|
return m_rightButtonsModel;
|
|
}
|
|
|
|
QAbstractListModel *KCMKWinDecoration::availableButtonsModel() const
|
|
{
|
|
return m_availableButtonsModel;
|
|
}
|
|
|
|
QStringList KCMKWinDecoration::borderSizesModel() const
|
|
{
|
|
return Utils::getBorderSizeNames().values();
|
|
}
|
|
|
|
int KCMKWinDecoration::borderSize() const
|
|
{
|
|
return Utils::getBorderSizeNames().keys().indexOf(m_currentSettings.borderSize);
|
|
}
|
|
|
|
int KCMKWinDecoration::theme() const
|
|
{
|
|
return m_currentSettings.themeIndex;
|
|
}
|
|
|
|
bool KCMKWinDecoration::closeOnDoubleClickOnMenu() const
|
|
{
|
|
return m_currentSettings.closeOnDoubleClickOnMenu;
|
|
}
|
|
|
|
bool KCMKWinDecoration::showToolTips() const
|
|
{
|
|
return m_currentSettings.showToolTips;
|
|
}
|
|
|
|
void KCMKWinDecoration::setBorderSize(int index)
|
|
{
|
|
setBorderSize(Utils::getBorderSizeNames().keys().at(index));
|
|
}
|
|
|
|
void KCMKWinDecoration::setBorderSize(KDecoration2::BorderSize size)
|
|
{
|
|
if (m_currentSettings.borderSize == size) {
|
|
return;
|
|
}
|
|
m_currentSettings.borderSize = size;
|
|
emit borderSizeChanged();
|
|
updateNeedsSave();
|
|
}
|
|
|
|
void KCMKWinDecoration::setTheme(int index)
|
|
{
|
|
// The initial themeIndex is set to -2 to always initially apply a theme, any theme
|
|
if (m_currentSettings.themeIndex == index) {
|
|
return;
|
|
}
|
|
m_currentSettings.themeIndex = index;
|
|
emit themeChanged();
|
|
updateNeedsSave();
|
|
}
|
|
|
|
void KCMKWinDecoration::setCloseOnDoubleClickOnMenu(bool enable)
|
|
{
|
|
if (m_currentSettings.closeOnDoubleClickOnMenu == enable) {
|
|
return;
|
|
}
|
|
m_currentSettings.closeOnDoubleClickOnMenu = enable;
|
|
emit closeOnDoubleClickOnMenuChanged();
|
|
updateNeedsSave();
|
|
}
|
|
|
|
void KCMKWinDecoration::setShowToolTips(bool show)
|
|
{
|
|
if (m_currentSettings.showToolTips == show) {
|
|
return;
|
|
}
|
|
m_currentSettings.showToolTips = show;
|
|
emit showToolTipsChanged();
|
|
updateNeedsSave();
|
|
}
|
|
|
|
#include "kcm.moc"
|