File indexing completed on 2024-11-10 04:56:46
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2013 Antonis Tsiapaliokas <kok3rs@gmail.com> 0006 SPDX-FileCopyrightText: 2013 Martin Gräßlin <mgraesslin@kde.org> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 0011 #include "ui_compositing.h" 0012 #include <kwin_compositing_interface.h> 0013 0014 #include <QAction> 0015 #include <QApplication> 0016 #include <QLayout> 0017 0018 #include <KCModule> 0019 #include <KPluginFactory> 0020 #include <KWindowSystem> 0021 0022 #include <algorithm> 0023 #include <functional> 0024 0025 #include "kwincompositing_setting.h" 0026 #include "kwincompositingdata.h" 0027 0028 static bool isRunningPlasma() 0029 { 0030 return qgetenv("XDG_CURRENT_DESKTOP") == "KDE"; 0031 } 0032 0033 class KWinCompositingKCM : public KCModule 0034 { 0035 Q_OBJECT 0036 public: 0037 explicit KWinCompositingKCM(QObject *parent, const KPluginMetaData &data); 0038 0039 public Q_SLOTS: 0040 void load() override; 0041 void save() override; 0042 void defaults() override; 0043 0044 private Q_SLOTS: 0045 void reenableGl(); 0046 0047 private: 0048 void init(); 0049 void updateUnmanagedItemStatus(); 0050 bool compositingRequired() const; 0051 0052 Ui_CompositingForm m_form; 0053 0054 OrgKdeKwinCompositingInterface *m_compositingInterface; 0055 KWinCompositingSetting *m_settings; 0056 }; 0057 0058 static const QList<qreal> s_animationMultipliers = {8, 4, 2, 1, 0.5, 0.25, 0.125, 0}; 0059 0060 bool KWinCompositingKCM::compositingRequired() const 0061 { 0062 return m_compositingInterface->platformRequiresCompositing(); 0063 } 0064 0065 KWinCompositingKCM::KWinCompositingKCM(QObject *parent, const KPluginMetaData &data) 0066 : KCModule(parent, data) 0067 , m_compositingInterface(new OrgKdeKwinCompositingInterface(QStringLiteral("org.kde.KWin"), QStringLiteral("/Compositor"), QDBusConnection::sessionBus(), this)) 0068 , m_settings(new KWinCompositingSetting(this)) 0069 { 0070 m_form.setupUi(widget()); 0071 0072 // AnimationDurationFactor should be written to the same place as the lnf to avoid conflicts 0073 m_settings->findItem("AnimationDurationFactor")->setWriteFlags(KConfigBase::Global | KConfigBase::Notify); 0074 0075 addConfig(m_settings, widget()); 0076 0077 m_form.glCrashedWarning->setIcon(QIcon::fromTheme(QStringLiteral("dialog-warning"))); 0078 QAction *reenableGlAction = new QAction(i18n("Re-enable OpenGL detection"), this); 0079 connect(reenableGlAction, &QAction::triggered, this, &KWinCompositingKCM::reenableGl); 0080 connect(reenableGlAction, &QAction::triggered, m_form.glCrashedWarning, &KMessageWidget::animatedHide); 0081 m_form.glCrashedWarning->addAction(reenableGlAction); 0082 m_form.windowThumbnailWarning->setIcon(QIcon::fromTheme(QStringLiteral("dialog-warning"))); 0083 0084 m_form.kcfg_Enabled->setVisible(!compositingRequired()); 0085 m_form.kcfg_WindowsBlockCompositing->setVisible(!compositingRequired()); 0086 m_form.compositingLabel->setVisible(!compositingRequired()); 0087 0088 connect(this, &KWinCompositingKCM::defaultsIndicatorsVisibleChanged, this, &KWinCompositingKCM::updateUnmanagedItemStatus); 0089 0090 if (KWindowSystem::isPlatformWayland()) { 0091 m_form.kcfg_HiddenPreviews->setVisible(false); 0092 m_form.label_HiddenPreviews->setVisible(false); 0093 } 0094 init(); 0095 } 0096 0097 void KWinCompositingKCM::reenableGl() 0098 { 0099 m_settings->setLastFailureTimestamp(0); 0100 m_settings->save(); 0101 } 0102 0103 void KWinCompositingKCM::init() 0104 { 0105 auto currentIndexChangedSignal = static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged); 0106 0107 // animation speed 0108 m_form.animationDurationFactor->setMaximum(s_animationMultipliers.size() - 1); 0109 connect(m_form.animationDurationFactor, &QSlider::valueChanged, this, [this]() { 0110 updateUnmanagedItemStatus(); 0111 m_settings->setAnimationDurationFactor(s_animationMultipliers[m_form.animationDurationFactor->value()]); 0112 }); 0113 0114 if (isRunningPlasma()) { 0115 m_form.animationSpeedLabel->hide(); 0116 m_form.animationSpeedControls->hide(); 0117 } 0118 0119 // windowThumbnail 0120 connect(m_form.kcfg_HiddenPreviews, currentIndexChangedSignal, this, [this](int index) { 0121 if (index == 2) { 0122 m_form.windowThumbnailWarning->animatedShow(); 0123 } else { 0124 m_form.windowThumbnailWarning->animatedHide(); 0125 } 0126 }); 0127 0128 if (m_settings->lastFailureTimestamp() > 0) { 0129 m_form.glCrashedWarning->animatedShow(); 0130 } 0131 } 0132 0133 void KWinCompositingKCM::updateUnmanagedItemStatus() 0134 { 0135 const auto animationDuration = s_animationMultipliers[m_form.animationDurationFactor->value()]; 0136 0137 const bool inPlasma = isRunningPlasma(); 0138 0139 bool changed = false; 0140 if (!inPlasma) { 0141 changed |= (animationDuration != m_settings->animationDurationFactor()); 0142 } 0143 unmanagedWidgetChangeState(changed); 0144 0145 bool defaulted = true; 0146 if (!inPlasma) { 0147 defaulted &= animationDuration == m_settings->defaultAnimationDurationFactorValue(); 0148 } 0149 0150 unmanagedWidgetDefaultState(defaulted); 0151 } 0152 0153 void KWinCompositingKCM::load() 0154 { 0155 KCModule::load(); 0156 0157 // unmanaged items 0158 m_settings->findItem("AnimationDurationFactor")->readConfig(m_settings->config()); 0159 const double multiplier = m_settings->animationDurationFactor(); 0160 auto const it = std::lower_bound(s_animationMultipliers.begin(), s_animationMultipliers.end(), multiplier, std::greater<qreal>()); 0161 const int index = static_cast<int>(std::distance(s_animationMultipliers.begin(), it)); 0162 m_form.animationDurationFactor->setValue(index); 0163 m_form.animationDurationFactor->setDisabled(m_settings->isAnimationDurationFactorImmutable()); 0164 } 0165 0166 void KWinCompositingKCM::defaults() 0167 { 0168 KCModule::defaults(); 0169 0170 // unmanaged widgets 0171 if (!isRunningPlasma()) { 0172 // corresponds to 1.0 seconds in s_animationMultipliers 0173 m_form.animationDurationFactor->setValue(3); 0174 } 0175 } 0176 0177 void KWinCompositingKCM::save() 0178 { 0179 if (!isRunningPlasma()) { 0180 const auto animationDuration = s_animationMultipliers[m_form.animationDurationFactor->value()]; 0181 m_settings->setAnimationDurationFactor(animationDuration); 0182 } 0183 m_settings->save(); 0184 0185 KCModule::save(); 0186 0187 // This clears up old entries that are now migrated to kdeglobals 0188 KConfig("kwinrc", KConfig::NoGlobals).group(QStringLiteral("KDE")).revertToDefault("AnimationDurationFactor"); 0189 0190 // Send signal to all kwin instances 0191 QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/Compositor"), 0192 QStringLiteral("org.kde.kwin.Compositing"), 0193 QStringLiteral("reinit")); 0194 QDBusConnection::sessionBus().send(message); 0195 } 0196 0197 K_PLUGIN_FACTORY_WITH_JSON(KWinCompositingConfigFactory, "kwincompositing.json", 0198 registerPlugin<KWinCompositingKCM>(); 0199 registerPlugin<KWinCompositingData>();) 0200 0201 #include "main.moc"