diff --git a/kcmkwin/kwincompositing/CMakeLists.txt b/kcmkwin/kwincompositing/CMakeLists.txt --- a/kcmkwin/kwincompositing/CMakeLists.txt +++ b/kcmkwin/kwincompositing/CMakeLists.txt @@ -10,7 +10,6 @@ set(kwincompositing_SRC main.cpp - compositing.cpp ) kconfig_add_kcfg_files(kwincompositing_SRC kwincompositing_setting.kcfgc GENERATE_MOC) diff --git a/kcmkwin/kwincompositing/compositing.h b/kcmkwin/kwincompositing/compositing.h deleted file mode 100644 --- a/kcmkwin/kwincompositing/compositing.h +++ /dev/null @@ -1,193 +0,0 @@ -/************************************************************************** - * KWin - the KDE window manager * - * This file is part of the KDE project. * - * * - * Copyright (C) 2013 Antonis Tsiapaliokas * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - **************************************************************************/ - - -#ifndef COMPOSITING_H -#define COMPOSITING_H - -#include -#include -#include - -class OrgKdeKwinCompositingInterface; - -class KWinCompositingSetting; - -namespace KWin { -namespace Compositing { - -class OpenGLPlatformInterfaceModel; - -class Compositing : public QObject -{ - - Q_OBJECT - Q_PROPERTY(int animationSpeed READ animationSpeed WRITE setAnimationSpeed NOTIFY animationSpeedChanged) - Q_PROPERTY(int windowThumbnail READ windowThumbnail WRITE setWindowThumbnail NOTIFY windowThumbnailChanged) - Q_PROPERTY(int glScaleFilter READ glScaleFilter WRITE setGlScaleFilter NOTIFY glScaleFilterChanged) - Q_PROPERTY(bool xrScaleFilter READ xrScaleFilter WRITE setXrScaleFilter NOTIFY xrScaleFilterChanged) - Q_PROPERTY(int glSwapStrategy READ glSwapStrategy WRITE setGlSwapStrategy NOTIFY glSwapStrategyChanged) - Q_PROPERTY(int compositingType READ compositingType WRITE setCompositingType NOTIFY compositingTypeChanged) - Q_PROPERTY(bool compositingEnabled READ compositingEnabled WRITE setCompositingEnabled NOTIFY compositingEnabledChanged) - Q_PROPERTY(KWin::Compositing::OpenGLPlatformInterfaceModel *openGLPlatformInterfaceModel READ openGLPlatformInterfaceModel CONSTANT) - Q_PROPERTY(int openGLPlatformInterface READ openGLPlatformInterface WRITE setOpenGLPlatformInterface NOTIFY openGLPlatformInterfaceChanged) - Q_PROPERTY(bool windowsBlockCompositing READ windowsBlockCompositing WRITE setWindowsBlockCompositing NOTIFY windowsBlockCompositingChanged) - Q_PROPERTY(bool compositingRequired READ compositingRequired CONSTANT) -public: - explicit Compositing(QObject *parent = nullptr); - - Q_INVOKABLE bool OpenGLIsUnsafe() const; - Q_INVOKABLE bool OpenGLIsBroken(); - Q_INVOKABLE void reenableOpenGLDetection(); - qreal animationSpeed() const; - int windowThumbnail() const; - int glScaleFilter() const; - bool xrScaleFilter() const; - int glSwapStrategy() const; - int compositingType() const; - bool compositingEnabled() const; - int openGLPlatformInterface() const; - bool windowsBlockCompositing() const; - bool compositingRequired() const; - - OpenGLPlatformInterfaceModel *openGLPlatformInterfaceModel() const; - - void setAnimationSpeed(qreal speed); - void setWindowThumbnail(int index); - void setGlScaleFilter(int index); - void setXrScaleFilter(bool filter); - void setGlSwapStrategy(int strategy); - void setCompositingType(int index); - void setCompositingEnabled(bool enalbed); - void setOpenGLPlatformInterface(int interface); - void setWindowsBlockCompositing(bool set); - - void save(); - - static bool isRunningPlasma(); - -public Q_SLOTS: - void load(); - void defaults(); - -Q_SIGNALS: - void changed(bool changed); - void defaulted(bool defaulted); - void animationSpeedChanged(qreal); - void windowThumbnailChanged(int); - void glScaleFilterChanged(int); - void xrScaleFilterChanged(int); - void glSwapStrategyChanged(int); - void compositingTypeChanged(int); - void compositingEnabledChanged(bool); - void openGLPlatformInterfaceChanged(int); - void windowsBlockCompositingChanged(bool); - -private Q_SLOTS: - void updateSettings(); - -private: - void applyValues(); - - qreal m_animationSpeed; - int m_windowThumbnail; - int m_glScaleFilter; - bool m_xrScaleFilter; - int m_glSwapStrategy; - int m_compositingType; - bool m_compositingEnabled; - OpenGLPlatformInterfaceModel *m_openGLPlatformInterfaceModel; - int m_openGLPlatformInterface; - bool m_windowsBlockCompositing; - bool m_windowsBlockingCompositing; - OrgKdeKwinCompositingInterface *m_compositingInterface; - KSharedConfigPtr m_config; - KWinCompositingSetting *m_settings; -}; - - -struct CompositingData; - -class CompositingType : public QAbstractItemModel -{ - - Q_OBJECT - Q_ENUMS(CompositingTypeIndex) - -public: - - enum CompositingTypeIndex { - OPENGL31_INDEX = 0, - OPENGL20_INDEX, - XRENDER_INDEX - }; - - enum CompositingTypeRoles { - NameRole = Qt::UserRole +1, - TypeRole = Qt::UserRole +2 - }; - - explicit CompositingType(QObject *parent = nullptr); - - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; - QModelIndex parent(const QModelIndex &child) const override; - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - - QHash< int, QByteArray > roleNames() const override; - - Q_INVOKABLE int compositingTypeForIndex(int row) const; - Q_INVOKABLE int indexForCompositingType(int type) const; - -private: - void generateCompositing(); - QList m_compositingList; - -}; - -struct CompositingData { - QString name; - CompositingType::CompositingTypeIndex type; -}; - -class OpenGLPlatformInterfaceModel : public QAbstractListModel -{ - Q_OBJECT -public: - explicit OpenGLPlatformInterfaceModel(QObject *parent = nullptr); - ~OpenGLPlatformInterfaceModel() override; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - - QModelIndex indexForKey(const QString &key) const; - - QHash< int, QByteArray > roleNames() const override; - -private: - QStringList m_keys; - QStringList m_names; -}; - -}//end namespace Compositing -}//end namespace KWin - -Q_DECLARE_METATYPE(KWin::Compositing::OpenGLPlatformInterfaceModel*) -#endif diff --git a/kcmkwin/kwincompositing/compositing.cpp b/kcmkwin/kwincompositing/compositing.cpp deleted file mode 100644 --- a/kcmkwin/kwincompositing/compositing.cpp +++ /dev/null @@ -1,514 +0,0 @@ -/************************************************************************** -* KWin - the KDE window manager * -* This file is part of the KDE project. * -* * -* Copyright (C) 2013 Antonis Tsiapaliokas * -* Copyright (C) 2013 Martin Gräßlin * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program 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 General Public License for more details. * -* * -* You should have received a copy of the GNU General Public License * -* along with this program. If not, see . * -**************************************************************************/ - -#include "compositing.h" -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "kwincompositing_setting.h" - -namespace KWin { -namespace Compositing { - -Compositing::Compositing(QObject *parent) - : QObject(parent) - , m_animationSpeed(1.0) - , m_windowThumbnail(0) - , m_glScaleFilter(0) - , m_xrScaleFilter(false) - , m_glSwapStrategy(0) - , m_compositingType(0) - , m_compositingEnabled(true) - , m_openGLPlatformInterfaceModel(new OpenGLPlatformInterfaceModel(this)) - , m_openGLPlatformInterface(0) - , m_windowsBlockCompositing(true) - , m_compositingInterface(new OrgKdeKwinCompositingInterface(QStringLiteral("org.kde.KWin"), QStringLiteral("/Compositor"), QDBusConnection::sessionBus(), this)) - , m_settings(new KWinCompositingSetting(this)) -{ - load(); - connect(this, &Compositing::animationSpeedChanged, this, &Compositing::updateSettings); - connect(this, &Compositing::windowThumbnailChanged, this, &Compositing::updateSettings); - connect(this, &Compositing::glScaleFilterChanged, this, &Compositing::updateSettings); - connect(this, &Compositing::xrScaleFilterChanged, this, &Compositing::updateSettings); - connect(this, &Compositing::glSwapStrategyChanged, this, &Compositing::updateSettings); - connect(this, &Compositing::compositingTypeChanged, this, &Compositing::updateSettings); - connect(this, &Compositing::compositingEnabledChanged, this, &Compositing::updateSettings); - connect(this, &Compositing::openGLPlatformInterfaceChanged, this, &Compositing::updateSettings); - connect(this, &Compositing::windowsBlockCompositingChanged, this, &Compositing::updateSettings); -} - -void Compositing::load() -{ - m_settings->load(); - - applyValues(); - - emit changed(false); - emit defaulted(m_settings->isDefaults()); -} - -void Compositing::applyValues() -{ - setAnimationSpeed(m_settings->animationDurationFactor()); - // from options.cpp Options::reloadCompositingSettings - // 4 - off, 5 - shown, 6 - always, other are old values - setWindowThumbnail(m_settings->hiddenPreviews() - 4); - setGlScaleFilter(m_settings->glTextureFilter()); - setXrScaleFilter(m_settings->xRenderSmoothScale()); - setCompositingEnabled(m_settings->enabled()); - setGlSwapStrategy(m_settings->glPreferBufferSwap()); - - const auto type = [this]{ - const int backend = m_settings->backend(); - const bool glCore = m_settings->glCore(); - - if (backend == KWinCompositingSetting::EnumBackend::OpenGL) { - if (glCore) { - return CompositingType::OPENGL31_INDEX; - } else { - return CompositingType::OPENGL20_INDEX; - } - } else { - return CompositingType::XRENDER_INDEX; - } - }; - setCompositingType(type()); - - const QModelIndex index = m_openGLPlatformInterfaceModel->indexForKey(m_settings->glPlatformInterface()); - setOpenGLPlatformInterface(index.isValid() ? index.row() : 0); - - setWindowsBlockCompositing(m_settings->windowsBlockCompositing()); -} - -void Compositing::defaults() -{ - m_settings->setDefaults(); - - applyValues(); - - emit changed(m_settings->isSaveNeeded()); - emit defaulted(m_settings->isDefaults()); -} - -bool Compositing::OpenGLIsUnsafe() const -{ - return m_settings->openGLIsUnsafe(); -} - -bool Compositing::OpenGLIsBroken() -{ - const int oldBackend = m_settings->backend(); - m_settings->setBackend(KWinCompositingSetting::EnumBackend::OpenGL); - m_settings->save(); - - if (m_compositingInterface->openGLIsBroken()) { - m_settings->setBackend(oldBackend); - m_settings->save(); - return true; - } - - m_settings->setOpenGLIsUnsafe(false); - m_settings->save(); - return false; -} - -void Compositing::reenableOpenGLDetection() -{ - m_settings->setOpenGLIsUnsafe(false); - m_settings->save(); -} - -qreal Compositing::animationSpeed() const -{ - return m_animationSpeed; -} - -int Compositing::windowThumbnail() const -{ - return m_windowThumbnail; -} - -int Compositing::glScaleFilter() const -{ - return m_glScaleFilter; -} - -bool Compositing::xrScaleFilter() const -{ - return m_xrScaleFilter; -} - -int Compositing::glSwapStrategy() const -{ - return m_glSwapStrategy; -} - -int Compositing::compositingType() const -{ - return m_compositingType; -} - -bool Compositing::compositingEnabled() const -{ - return m_compositingEnabled; -} - -void Compositing::setAnimationSpeed(qreal speed) -{ - if (speed == m_animationSpeed) { - return; - } - m_animationSpeed = speed; - emit animationSpeedChanged(speed); -} - -void Compositing::setGlScaleFilter(int index) -{ - if (index == m_glScaleFilter) { - return; - } - m_glScaleFilter = index; - emit glScaleFilterChanged(index); -} - -void Compositing::setGlSwapStrategy(int strategy) -{ - if (strategy == m_glSwapStrategy) { - return; - } - m_glSwapStrategy = strategy; - emit glSwapStrategyChanged(strategy); -} - -void Compositing::setWindowThumbnail(int index) -{ - if (index == m_windowThumbnail) { - return; - } - m_windowThumbnail = index; - emit windowThumbnailChanged(index); -} - -void Compositing::setXrScaleFilter(bool filter) -{ - if (filter == m_xrScaleFilter) { - return; - } - m_xrScaleFilter = filter; - emit xrScaleFilterChanged(filter); -} - -void Compositing::setCompositingType(int index) -{ - if (index == m_compositingType) { - return; - } - m_compositingType = index; - emit compositingTypeChanged(index); -} - -void Compositing::setCompositingEnabled(bool enabled) -{ - if (compositingRequired()) { - return; - } - if (enabled == m_compositingEnabled) { - return; - } - - m_compositingEnabled = enabled; - emit compositingEnabledChanged(enabled); -} - -void Compositing::updateSettings() -{ - // this writes to the KDE group of the kwinrc, when loading we rely on kconfig cascading to - // load a global value, or allow a kwin override - if (!isRunningPlasma()) { - m_settings->setAnimationDurationFactor(animationSpeed()); - } - - m_settings->setHiddenPreviews(windowThumbnail() + 4); - m_settings->setGlTextureFilter(glScaleFilter()); - m_settings->setXRenderSmoothScale(xrScaleFilter()); - if (!compositingRequired()) { - m_settings->setEnabled(compositingEnabled()); - } - m_settings->setGlPreferBufferSwap(glSwapStrategy()); - int backend = KWinCompositingSetting::EnumBackend::OpenGL; - bool glCore = false; - switch (compositingType()) { - case CompositingType::OPENGL31_INDEX: - backend = KWinCompositingSetting::EnumBackend::OpenGL; - glCore = true; - break; - case CompositingType::OPENGL20_INDEX: - backend = KWinCompositingSetting::EnumBackend::OpenGL; - glCore = false; - break; - case CompositingType::XRENDER_INDEX: - backend = KWinCompositingSetting::EnumBackend::XRender; - glCore = false; - break; - } - m_settings->setBackend(backend); - m_settings->setGlCore(glCore); - if (!compositingRequired()) { - m_settings->setWindowsBlockCompositing(windowsBlockCompositing()); - } - - emit changed(m_settings->isSaveNeeded()); - emit defaulted(m_settings->isDefaults()); -} - -void Compositing::save() -{ - if (m_settings->isSaveNeeded()) { - - m_settings->save(); - - // Send signal to all kwin instances - QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/Compositor"), - QStringLiteral("org.kde.kwin.Compositing"), - QStringLiteral("reinit")); - QDBusConnection::sessionBus().send(message); - } -} - -OpenGLPlatformInterfaceModel *Compositing::openGLPlatformInterfaceModel() const -{ - return m_openGLPlatformInterfaceModel; -} - -int Compositing::openGLPlatformInterface() const -{ - return m_openGLPlatformInterface; -} - -void Compositing::setOpenGLPlatformInterface(int interface) -{ - if (m_openGLPlatformInterface == interface) { - return; - } - m_openGLPlatformInterface = interface; - emit openGLPlatformInterfaceChanged(interface); -} - -bool Compositing::windowsBlockCompositing() const -{ - return m_windowsBlockCompositing; -} - -void Compositing::setWindowsBlockCompositing(bool set) -{ - if (compositingRequired()) { - return; - } - if (m_windowsBlockCompositing == set) { - return; - } - m_windowsBlockCompositing = set; - emit windowsBlockCompositingChanged(set); -} - -bool Compositing::compositingRequired() const -{ - return m_compositingInterface->platformRequiresCompositing(); -} - -bool Compositing::isRunningPlasma() -{ - return qgetenv("XDG_CURRENT_DESKTOP") == "KDE"; -} - -CompositingType::CompositingType(QObject *parent) - : QAbstractItemModel(parent) { - - generateCompositing(); -} - -void CompositingType::generateCompositing() -{ - QHash compositingTypes; - - compositingTypes[i18n("OpenGL 3.1")] = CompositingType::OPENGL31_INDEX; - compositingTypes[i18n("OpenGL 2.0")] = CompositingType::OPENGL20_INDEX; - compositingTypes[i18n("XRender")] = CompositingType::XRENDER_INDEX; - - CompositingData data; - beginResetModel(); - auto it = compositingTypes.begin(); - while (it != compositingTypes.end()) { - data.name = it.key(); - data.type = it.value(); - m_compositingList << data; - it++; - } - - std::sort(m_compositingList.begin(), m_compositingList.end(), [](const CompositingData &a, const CompositingData &b) { - return a.type < b.type; - }); - endResetModel(); -} - -QHash< int, QByteArray > CompositingType::roleNames() const -{ - QHash roleNames; - roleNames[NameRole] = "NameRole"; - roleNames[TypeRole] = QByteArrayLiteral("type"); - return roleNames; -} - -QModelIndex CompositingType::index(int row, int column, const QModelIndex &parent) const -{ - if (parent.isValid() || column > 0 || column < 0 || row < 0 || row >= m_compositingList.count()) { - return QModelIndex(); - } - - return createIndex(row, column); -} - -QModelIndex CompositingType::parent(const QModelIndex &child) const -{ - Q_UNUSED(child) - - return QModelIndex(); -} - -int CompositingType::columnCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent) - return 1; -} - -int CompositingType::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) { - return 0; - } - return m_compositingList.count(); -} - -QVariant CompositingType::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) { - return QVariant(); - } - - switch (role) { - case Qt::DisplayRole: - case NameRole: - return m_compositingList.at(index.row()).name; - case TypeRole: - return m_compositingList.at(index.row()).type; - default: - return QVariant(); - } -} - -int CompositingType::compositingTypeForIndex(int row) const -{ - return index(row, 0).data(TypeRole).toInt(); -} - -int CompositingType::indexForCompositingType(int type) const -{ - for (int i = 0; i < m_compositingList.count(); ++i) { - if (m_compositingList.at(i).type == type) { - return i; - } - } - return -1; -} - -OpenGLPlatformInterfaceModel::OpenGLPlatformInterfaceModel(QObject *parent) - : QAbstractListModel(parent) -{ - beginResetModel(); - OrgKdeKwinCompositingInterface interface(QStringLiteral("org.kde.KWin"), - QStringLiteral("/Compositor"), - QDBusConnection::sessionBus()); - m_keys << interface.supportedOpenGLPlatformInterfaces(); - for (const QString &key : m_keys) { - if (key == QStringLiteral("egl")) { - m_names << i18nc("OpenGL Platform Interface", "EGL"); - } else if (key == QStringLiteral("glx")) { - m_names << i18nc("OpenGL Platform Interface", "GLX"); - } else { - m_names << key; - } - } - endResetModel(); -} - -OpenGLPlatformInterfaceModel::~OpenGLPlatformInterfaceModel() = default; - -int OpenGLPlatformInterfaceModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) { - return 0; - } - return m_keys.count(); -} - -QHash< int, QByteArray > OpenGLPlatformInterfaceModel::roleNames() const -{ - return QHash({ - {Qt::DisplayRole, QByteArrayLiteral("display")}, - {Qt::UserRole, QByteArrayLiteral("openglPlatformInterface")} - }); -} - -QVariant OpenGLPlatformInterfaceModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid() || index.row() < 0 || index.row() >= m_keys.size() || index.column() != 0) { - return QVariant(); - } - switch (role) { - case Qt::DisplayRole: - return m_names.at(index.row()); - case Qt::UserRole: - return m_keys.at(index.row()); - default: - return QVariant(); - } -} - -QModelIndex OpenGLPlatformInterfaceModel::indexForKey(const QString &key) const -{ - const int keyIndex = m_keys.indexOf(key); - if (keyIndex < 0) { - return QModelIndex(); - } - return createIndex(keyIndex, 0); -} - -}//end namespace Compositing -}//end namespace KWin diff --git a/kcmkwin/kwincompositing/compositing.ui b/kcmkwin/kwincompositing/compositing.ui --- a/kcmkwin/kwincompositing/compositing.ui +++ b/kcmkwin/kwincompositing/compositing.ui @@ -74,59 +74,125 @@ - - + + - Animation speed: + Enable compositor on startup - - + + - Scale method: + Animation speed: - - - - - Crisp - - - - - Smooth - - - - - Accurate - - + + + + + 0 + 0 + + + + + + + 0 + + + 0 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 1 + + + + + + + + + Very slow + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Instant + + + + + + - - + + Scale method: - - + + - - Crisp - + + + + Crisp + + + + + Smooth (slower) + + + - - Smooth (slower) - + + + + Crisp + + + + + Smooth + + + + + Accurate + + + - + @@ -143,7 +209,7 @@ - + @@ -160,7 +226,7 @@ - + Never @@ -196,7 +262,7 @@ - + Never @@ -215,7 +281,7 @@ - + Applications can set a hint to block compositing when the window is open. This brings performance improvements for e.g. games. @@ -226,75 +292,6 @@ - - - - - 0 - 0 - - - - - - - 0 - - - 0 - - - Qt::Horizontal - - - QSlider::TicksBelow - - - 1 - - - - - - - - - Very slow - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Instant - - - - - - - - - - - - Enable compositor on startup - - - diff --git a/kcmkwin/kwincompositing/kwincompositing_setting.kcfg b/kcmkwin/kwincompositing/kwincompositing_setting.kcfg --- a/kcmkwin/kwincompositing/kwincompositing_setting.kcfg +++ b/kcmkwin/kwincompositing/kwincompositing_setting.kcfg @@ -13,16 +13,25 @@ - - 5 + + Shown + + + + + - 2 + 2 - - false + + Crisp + + + + @@ -34,13 +43,13 @@ - a + AutoSwapStrategy - - - - - + + + + + @@ -60,14 +69,6 @@ true - - glx - - - - - - diff --git a/kcmkwin/kwincompositing/main.cpp b/kcmkwin/kwincompositing/main.cpp --- a/kcmkwin/kwincompositing/main.cpp +++ b/kcmkwin/kwincompositing/main.cpp @@ -20,8 +20,9 @@ **************************************************************************/ -#include "compositing.h" #include "ui_compositing.h" +#include + #include #include #include @@ -32,81 +33,104 @@ #include #include +#include "kwincompositing_setting.h" + +static bool isRunningPlasma() +{ + return qgetenv("XDG_CURRENT_DESKTOP") == "KDE"; +} + class KWinCompositingKCM : public KCModule { Q_OBJECT public: + enum CompositingTypeIndex { + OPENGL31_INDEX = 0, + OPENGL20_INDEX, + XRENDER_INDEX + }; + explicit KWinCompositingKCM(QWidget *parent = nullptr, const QVariantList &args = QVariantList()); public Q_SLOTS: void load() override; void save() override; void defaults() override; +private Q_SLOTS: + void onBackendChanged(); + void reenableGl(); + private: void init(); - KWin::Compositing::Compositing *m_compositing; + void updateUnmanagedItemStatus(); + bool compositingRequired() const; + Ui_CompositingForm m_form; + + OrgKdeKwinCompositingInterface *m_compositingInterface; + KWinCompositingSetting *m_settings; + + // unmanaged states + int m_backend; + bool m_glCore; + double m_animationDurationFactor; }; static const QVector s_animationMultipliers = {8, 4, 2, 1, 0.5, 0.25, 0.125, 0}; +bool KWinCompositingKCM::compositingRequired() const +{ + return m_compositingInterface->platformRequiresCompositing(); +} + KWinCompositingKCM::KWinCompositingKCM(QWidget *parent, const QVariantList &args) : KCModule(parent, args) - , m_compositing(new KWin::Compositing::Compositing(this)) + , m_compositingInterface(new OrgKdeKwinCompositingInterface(QStringLiteral("org.kde.KWin"), QStringLiteral("/Compositor"), QDBusConnection::sessionBus(), this)) + , m_settings(new KWinCompositingSetting(this)) { m_form.setupUi(this); + addConfig(m_settings, this); + m_form.glCrashedWarning->setIcon(QIcon::fromTheme(QStringLiteral("dialog-warning"))); - QAction *reenableGLAction = new QAction(i18n("Re-enable OpenGL detection"), this); - connect(reenableGLAction, &QAction::triggered, m_compositing, &KWin::Compositing::Compositing::reenableOpenGLDetection); - connect(reenableGLAction, &QAction::triggered, m_form.glCrashedWarning, &KMessageWidget::animatedHide); - m_form.glCrashedWarning->addAction(reenableGLAction); + QAction *reenableGlAction = new QAction(i18n("Re-enable OpenGL detection"), this); + connect(reenableGlAction, &QAction::triggered, this, &KWinCompositingKCM::reenableGl); + connect(reenableGlAction, &QAction::triggered, m_form.glCrashedWarning, &KMessageWidget::animatedHide); + m_form.glCrashedWarning->addAction(reenableGlAction); m_form.scaleWarning->setIcon(QIcon::fromTheme(QStringLiteral("dialog-warning"))); m_form.tearingWarning->setIcon(QIcon::fromTheme(QStringLiteral("dialog-warning"))); m_form.windowThumbnailWarning->setIcon(QIcon::fromTheme(QStringLiteral("dialog-warning"))); - m_form.compositingEnabled->setVisible(!m_compositing->compositingRequired()); - m_form.windowsBlockCompositing->setVisible(!m_compositing->compositingRequired()); + m_form.kcfg_Enabled->setVisible(!compositingRequired()); + m_form.kcfg_WindowsBlockCompositing->setVisible(!compositingRequired()); init(); } +void KWinCompositingKCM::reenableGl() +{ + m_settings->setOpenGLIsUnsafe(false); + m_settings->save(); +} + void KWinCompositingKCM::init() { - using namespace KWin::Compositing; auto currentIndexChangedSignal = static_cast(&QComboBox::currentIndexChanged); - connect(m_compositing, &Compositing::changed, this, qOverload(&KCModule::changed)); - connect(m_compositing, &Compositing::defaulted, this, qOverload(&KCModule::defaulted)); - - // enabled check box - m_form.compositingEnabled->setChecked(m_compositing->compositingEnabled()); - connect(m_compositing, &Compositing::compositingEnabledChanged, m_form.compositingEnabled, &QCheckBox::setChecked); - connect(m_form.compositingEnabled, &QCheckBox::toggled, m_compositing, &Compositing::setCompositingEnabled); - // animation speed - m_form.animationSpeed->setMaximum(s_animationMultipliers.size() - 1); - auto setSpeed = [this](const qreal multiplier) { - auto const it = std::lower_bound(s_animationMultipliers.begin(), s_animationMultipliers.end(), multiplier, std::greater()); - const int index = std::distance(s_animationMultipliers.begin(), it); - m_form.animationSpeed->setValue(index); - }; - setSpeed(m_compositing->animationSpeed()); - connect(m_compositing, &Compositing::animationSpeedChanged, m_form.animationSpeed, setSpeed); - connect(m_form.animationSpeed, &QSlider::valueChanged, m_compositing, [this](int index) { - m_compositing->setAnimationSpeed(s_animationMultipliers[index]); + m_form.animationDurationFactor->setMaximum(s_animationMultipliers.size() - 1); + connect(m_form.animationDurationFactor, &QSlider::valueChanged, this, [this]() { + m_settings->setAnimationDurationFactor(s_animationMultipliers[m_form.animationDurationFactor->value()]); + updateUnmanagedItemStatus(); }); - if (Compositing::isRunningPlasma()) { + if (isRunningPlasma()) { m_form.animationSpeedLabel->hide(); m_form.animationSpeedControls->hide(); } // gl scale filter - m_form.glScaleFilter->setCurrentIndex(m_compositing->glScaleFilter()); - connect(m_compositing, &Compositing::glScaleFilterChanged, m_form.glScaleFilter, &QComboBox::setCurrentIndex); - connect(m_form.glScaleFilter, currentIndexChangedSignal, m_compositing, &Compositing::setGlScaleFilter); - connect(m_form.glScaleFilter, currentIndexChangedSignal, + connect(m_form.kcfg_glTextureFilter, currentIndexChangedSignal, this, [this](int index) { if (index == 2) { m_form.scaleWarning->animatedShow(); @@ -116,23 +140,8 @@ } ); - // xrender scale filter - m_form.xrScaleFilter->setCurrentIndex(m_compositing->xrScaleFilter()); - connect(m_compositing, &Compositing::xrScaleFilterChanged, m_form.xrScaleFilter, &QComboBox::setCurrentIndex); - connect(m_form.xrScaleFilter, currentIndexChangedSignal, - [this](int index) { - if (index == 0) { - m_compositing->setXrScaleFilter(false); - } else { - m_compositing->setXrScaleFilter(true); - } - }); - // tearing prevention - m_form.tearingPrevention->setCurrentIndex(m_compositing->glSwapStrategy()); - connect(m_compositing, &Compositing::glSwapStrategyChanged, m_form.tearingPrevention, &QComboBox::setCurrentIndex); - connect(m_form.tearingPrevention, currentIndexChangedSignal, m_compositing, &Compositing::setGlSwapStrategy); - connect(m_form.tearingPrevention, currentIndexChangedSignal, + connect(m_form.kcfg_glPreferBufferSwap, currentIndexChangedSignal, this, [this](int index) { if (index == 2) { // only when cheap - tearing @@ -153,10 +162,7 @@ ); // windowThumbnail - m_form.windowThumbnail->setCurrentIndex(m_compositing->windowThumbnail()); - connect(m_compositing, &Compositing::windowThumbnailChanged, m_form.windowThumbnail, &QComboBox::setCurrentIndex); - connect(m_form.windowThumbnail, currentIndexChangedSignal, m_compositing, &Compositing::setWindowThumbnail); - connect(m_form.windowThumbnail, currentIndexChangedSignal, + connect(m_form.kcfg_HiddenPreviews, currentIndexChangedSignal, this, [this](int index) { if (index == 2) { m_form.windowThumbnailWarning->animatedShow(); @@ -166,59 +172,136 @@ } ); - // windows blocking compositing - m_form.windowsBlockCompositing->setChecked(m_compositing->windowsBlockCompositing()); - connect(m_compositing, &Compositing::windowsBlockCompositingChanged, m_form.windowsBlockCompositing, &QCheckBox::setChecked); - connect(m_form.windowsBlockCompositing, &QCheckBox::toggled, m_compositing, &Compositing::setWindowsBlockCompositing); - // compositing type - CompositingType *type = new CompositingType(this); - m_form.type->setModel(type); - auto updateCompositingType = [this, type]() { - m_form.type->setCurrentIndex(type->indexForCompositingType(m_compositing->compositingType())); - }; - updateCompositingType(); - connect(m_compositing, &Compositing::compositingTypeChanged, - [updateCompositingType]() { - updateCompositingType(); - } - ); - auto showHideBasedOnType = [this, type]() { - const int currentType = type->compositingTypeForIndex(m_form.type->currentIndex()); - m_form.glScaleFilter->setVisible(currentType != CompositingType::XRENDER_INDEX); - m_form.glScaleFilterLabel->setVisible(currentType != CompositingType::XRENDER_INDEX); - m_form.xrScaleFilter->setVisible(currentType == CompositingType::XRENDER_INDEX); - m_form.xrScaleFilterLabel->setVisible(currentType == CompositingType::XRENDER_INDEX); - }; - showHideBasedOnType(); - connect(m_form.type, currentIndexChangedSignal, - [this, type, showHideBasedOnType]() { - m_compositing->setCompositingType(type->compositingTypeForIndex(m_form.type->currentIndex())); - showHideBasedOnType(); - } - ); + m_form.backend->addItem(i18n("OpenGL 3.1"), CompositingTypeIndex::OPENGL31_INDEX); + m_form.backend->addItem(i18n("OpenGL 2.0"), CompositingTypeIndex::OPENGL20_INDEX); + m_form.backend->addItem(i18n("XRender"), CompositingTypeIndex::XRENDER_INDEX); + + connect(m_form.backend, currentIndexChangedSignal, this, &KWinCompositingKCM::onBackendChanged); - if (m_compositing->OpenGLIsUnsafe()) { + if (m_settings->openGLIsUnsafe()) { m_form.glCrashedWarning->animatedShow(); } } +void KWinCompositingKCM::onBackendChanged() +{ + const int currentType = m_form.backend->currentData().toInt(); + + m_form.kcfg_glTextureFilter->setVisible(currentType != CompositingTypeIndex::XRENDER_INDEX); + m_form.kcfg_XRenderSmoothScale->setVisible(currentType == CompositingTypeIndex::XRENDER_INDEX); + + updateUnmanagedItemStatus(); +} + +void KWinCompositingKCM::updateUnmanagedItemStatus() +{ + int backend = KWinCompositingSetting::EnumBackend::OpenGL; + bool glCore = true; + const int currentType = m_form.backend->currentData().toInt(); + switch (currentType) { + case CompositingTypeIndex::OPENGL31_INDEX: + // default already set + break; + case CompositingTypeIndex::OPENGL20_INDEX: + glCore = false; + break; + case CompositingTypeIndex::XRENDER_INDEX: + backend = KWinCompositingSetting::EnumBackend::XRender; + glCore = false; + break; + } + const auto animationDuration = s_animationMultipliers[m_form.animationDurationFactor->value()]; + + const bool inPlasma = isRunningPlasma(); + + bool changed = glCore != m_glCore; + changed |= backend != m_backend; + if (!inPlasma) { + changed |= (animationDuration != m_animationDurationFactor); + } + unmanagedWidgetChangeState(changed); + + bool defaulted = glCore == m_settings->defaultGlCoreValue(); + defaulted &= backend == m_settings->defaultBackendValue(); + if (!inPlasma) { + defaulted &= animationDuration == m_settings->defaultAnimationDurationFactorValue(); + } + unmanagedWidgetDefaultState(defaulted); +} + void KWinCompositingKCM::load() { KCModule::load(); - m_compositing->load(); + + // unmanaged items + m_settings->findItem("AnimationDurationFactor")->readConfig(m_settings->config()); + const double multiplier = m_settings->animationDurationFactor(); + auto const it = std::lower_bound(s_animationMultipliers.begin(), s_animationMultipliers.end(), multiplier, std::greater()); + const int index = static_cast(std::distance(s_animationMultipliers.begin(), it)); + m_form.animationDurationFactor->setValue(index); + m_form.animationDurationFactor->setDisabled(m_settings->isAnimationDurationFactorImmutable()); + + m_settings->findItem("Backend")->readConfig(m_settings->config()); + m_settings->findItem("glCore")->readConfig(m_settings->config()); + m_backend = m_settings->backend(); + m_glCore = m_settings->glCore(); + if (m_backend == KWinCompositingSetting::EnumBackend::OpenGL) { + if (m_glCore) { + m_form.backend->setCurrentIndex(CompositingTypeIndex::OPENGL31_INDEX); + } else { + m_form.backend->setCurrentIndex(CompositingTypeIndex::OPENGL20_INDEX); + } + } else { + m_form.backend->setCurrentIndex(CompositingTypeIndex::XRENDER_INDEX); + } + m_form.backend->setDisabled(m_settings->isBackendImmutable()); + + onBackendChanged(); } void KWinCompositingKCM::defaults() { KCModule::defaults(); - m_compositing->defaults(); + + // unmanaged widgets + m_form.backend->setCurrentIndex(CompositingTypeIndex::OPENGL20_INDEX); + // corresponds to 1.0 seconds in s_animationMultipliers + m_form.animationDurationFactor->setValue(3); } void KWinCompositingKCM::save() { + int backend = KWinCompositingSetting::EnumBackend::OpenGL; + bool glCore = true; + const int currentType = m_form.backend->currentData().toInt(); + switch (currentType) { + case CompositingTypeIndex::OPENGL31_INDEX: + // default already set + break; + case CompositingTypeIndex::OPENGL20_INDEX: + backend = KWinCompositingSetting::EnumBackend::OpenGL; + glCore = false; + break; + case CompositingTypeIndex::XRENDER_INDEX: + backend = KWinCompositingSetting::EnumBackend::XRender; + glCore = false; + break; + } + m_settings->setBackend(backend); + m_settings->setGlCore(glCore); + + const auto animationDuration = s_animationMultipliers[m_form.animationDurationFactor->value()]; + m_settings->setAnimationDurationFactor(animationDuration); + m_settings->save(); + KCModule::save(); - m_compositing->save(); + + // Send signal to all kwin instances + QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/Compositor"), + QStringLiteral("org.kde.kwin.Compositing"), + QStringLiteral("reinit")); + QDBusConnection::sessionBus().send(message); } K_PLUGIN_FACTORY(KWinCompositingConfigFactory,