File indexing completed on 2024-05-05 05:35:17

0001 /*
0002     SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
0003     SPDX-FileCopyrightText: 2015 David Edmundson <davidedmundson@kde.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0006 */
0007 
0008 #include "oxygensettingsprovider.h"
0009 
0010 #include "oxygendecohelper.h"
0011 #include "oxygenshadowcache.h"
0012 
0013 #include "oxygenexceptionlist.h"
0014 
0015 #include <KWindowInfo>
0016 
0017 #include <QRegularExpression>
0018 #include <QTextStream>
0019 
0020 namespace Oxygen
0021 {
0022 SettingsProvider *SettingsProvider::s_self = nullptr;
0023 
0024 //__________________________________________________________________
0025 SettingsProvider::SettingsProvider()
0026     : m_config(KSharedConfig::openConfig(QStringLiteral("oxygenrc")))
0027     , m_decoHelper(new DecoHelper())
0028     , m_shadowCache(new ShadowCache(*m_decoHelper))
0029 {
0030     reconfigure();
0031 }
0032 
0033 //__________________________________________________________________
0034 SettingsProvider::~SettingsProvider()
0035 {
0036     s_self = nullptr;
0037     delete m_shadowCache;
0038     delete m_decoHelper;
0039 }
0040 
0041 //__________________________________________________________________
0042 SettingsProvider *SettingsProvider::self()
0043 {
0044     // TODO: this is not thread safe!
0045     if (!s_self) {
0046         s_self = new SettingsProvider();
0047     }
0048 
0049     return s_self;
0050 }
0051 
0052 //__________________________________________________________________
0053 void SettingsProvider::reconfigure(void)
0054 {
0055     if (!m_defaultSettings) {
0056         m_defaultSettings = InternalSettingsPtr(new InternalSettings());
0057         m_defaultSettings->setCurrentGroup(QStringLiteral("Windeco"));
0058     }
0059 
0060     m_decoHelper->invalidateCaches();
0061     m_decoHelper->loadConfig();
0062 
0063     m_shadowCache->readConfig();
0064     m_defaultSettings->load();
0065 
0066     ExceptionList exceptions;
0067     exceptions.readConfig(m_config);
0068     m_exceptions = exceptions.get();
0069 }
0070 
0071 //__________________________________________________________________
0072 InternalSettingsPtr SettingsProvider::internalSettings(const Decoration *decoration) const
0073 {
0074     QString windowTitle;
0075     QString className;
0076 
0077     // get the client
0078     const auto clientPtr = decoration->client();
0079 
0080     for (auto currentInternalSettings : std::as_const(m_exceptions)) {
0081         // discard disabled exceptions
0082         if (!currentInternalSettings->enabled())
0083             continue;
0084 
0085         // discard exceptions with empty exception pattern
0086         if (currentInternalSettings->exceptionPattern().isEmpty())
0087             continue;
0088 
0089         /*
0090         decide which value is to be compared
0091         to the regular expression, based on exception type
0092         */
0093         QString value;
0094         switch (currentInternalSettings->exceptionType()) {
0095         case InternalSettings::ExceptionWindowTitle: {
0096             value = windowTitle.isEmpty() ? (windowTitle = clientPtr->caption()) : windowTitle;
0097             break;
0098         }
0099 
0100         default:
0101         case InternalSettings::ExceptionWindowClassName: {
0102             if (className.isEmpty()) {
0103                 // retrieve class name
0104                 KWindowInfo info(clientPtr->windowId(), {}, NET::WM2WindowClass);
0105                 QString window_className(QString::fromUtf8(info.windowClassName()));
0106                 QString window_class(QString::fromUtf8(info.windowClassClass()));
0107                 className = window_className + QStringLiteral(" ") + window_class;
0108             }
0109 
0110             value = className;
0111             break;
0112         }
0113         }
0114 
0115         // check matching
0116         if (value.contains(QRegularExpression(currentInternalSettings->exceptionPattern()))) {
0117             return currentInternalSettings;
0118         }
0119     }
0120 
0121     return m_defaultSettings;
0122 }
0123 }