/***************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2007 Rivo Laks You can Freely distribute this program under the GNU General Public License. See the file "COPYING" for the exact licensing terms. ******************************************************************/ #include "main.h" #include "advanced.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include K_PLUGIN_FACTORY(KWinCompositingConfigFactory, registerPlugin(); ) K_EXPORT_PLUGIN(KWinCompositingConfigFactory("kcmkwincompositing")) namespace KWin { ConfirmDialog::ConfirmDialog() : KDialog() { setCaption( i18n( "Compositing settings changed" )); setButtons( KDialog::Yes | KDialog::No | KDialog::Cancel ); setDefaultButton(KDialog::No); setButtonFocus(KDialog::No); setEscapeButton(KDialog::Cancel); mTextLabel = new QLabel(this); setMainWidget(mTextLabel); mSecondsToLive = 10+1; advanceTimer(); } void ConfirmDialog::advanceTimer() { mSecondsToLive--; if(mSecondsToLive > 0) { QString text = i18n("Compositing settings have changed.\n" "Do you want to keep the new settings?\n" "They will be automatically reverted in %1 seconds", mSecondsToLive); mTextLabel->setText(text); QTimer::singleShot(1000, this, SLOT(advanceTimer())); } else { slotButtonClicked(KDialog::No); } } KWinCompositingConfig::KWinCompositingConfig(QWidget *parent, const QVariantList &) : KCModule( KWinCompositingConfigFactory::componentData(), parent), mKWinConfig(KSharedConfig::openConfig("kwinrc")) { ui.setupUi(this); ui.tabWidget->setCurrentIndex(0); // Driver-specific config detection mDefaultPrefs.detect(); connect(ui.advancedOptions, SIGNAL(clicked()), this, SLOT(showAdvancedOptions())); connect(ui.useCompositing, SIGNAL(toggled(bool)), this, SLOT(compositingEnabled(bool))); connect(ui.useCompositing, SIGNAL(toggled(bool)), this, SLOT(changed())); connect(ui.effectWinManagement, SIGNAL(toggled(bool)), this, SLOT(changed())); connect(ui.effectShadows, SIGNAL(toggled(bool)), this, SLOT(changed())); connect(ui.effectAnimations, SIGNAL(toggled(bool)), this, SLOT(changed())); connect(ui.effectSelector, SIGNAL(changed(bool)), this, SLOT(changed())); connect(ui.effectSelector, SIGNAL(configCommitted(const QByteArray&)), this, SLOT(reparseConfiguration(const QByteArray&))); initEffectSelector(); // Load config load(); KAboutData *about = new KAboutData(I18N_NOOP("kcmkwincompositing"), 0, ki18n("KWin Desktop Effects Configuration Module"), 0, KLocalizedString(), KAboutData::License_GPL, ki18n("(c) 2007 Rivo Laks")); about->addAuthor(ki18n("Rivo Laks"), KLocalizedString(), "rivolaks@hot.ee"); setAboutData(about); } KWinCompositingConfig::~KWinCompositingConfig() { } void KWinCompositingConfig::reparseConfiguration(const QByteArray&conf) { KSettings::Dispatcher::reparseConfiguration(conf); } void KWinCompositingConfig::compositingEnabled(bool enabled) { ui.compositingOptionsContainer->setEnabled(enabled); ui.tabWidget->setTabEnabled(1, enabled); } void KWinCompositingConfig::showAdvancedOptions() { KWinAdvancedCompositingOptions* dialog = new KWinAdvancedCompositingOptions(this, mKWinConfig, &mDefaultPrefs); dialog->show(); connect(dialog, SIGNAL(configSaved()), this, SLOT(configChanged())); } void KWinCompositingConfig::showConfirmDialog() { ConfirmDialog confirm; int result = confirm.exec(); kDebug() << "result:" << result; if(result != KDialog::Yes) { // Revert settings KConfigGroup config(mKWinConfig, "Compositing"); config.deleteGroup(); QMap::const_iterator i = mPreviousConfig.constBegin(); while (i != mPreviousConfig.constEnd()) { config.writeEntry(i.key(), i.value()); ++i; } config.sync(); load(); } } void KWinCompositingConfig::initEffectSelector() { // Find all .desktop files of the effects KService::List offers = KServiceTypeTrader::self()->query("KWin/Effect"); QList effectinfos = KPluginInfo::fromServices(offers); // Add them to the plugin selector ui.effectSelector->addPlugins(effectinfos, KPluginSelector::ReadConfigFile, i18n("Appearance"), "Appearance", mKWinConfig); ui.effectSelector->addPlugins(effectinfos, KPluginSelector::ReadConfigFile, i18n("Accessibility"), "Accessibility", mKWinConfig); ui.effectSelector->addPlugins(effectinfos, KPluginSelector::ReadConfigFile, i18n("Window Management"), "Window Management", mKWinConfig); ui.effectSelector->addPlugins(effectinfos, KPluginSelector::ReadConfigFile, i18n("Demos"), "Demos", mKWinConfig); ui.effectSelector->addPlugins(effectinfos, KPluginSelector::ReadConfigFile, i18n("Tests"), "Tests", mKWinConfig); ui.effectSelector->addPlugins(effectinfos, KPluginSelector::ReadConfigFile, i18n("Misc"), "Misc", mKWinConfig); } void KWinCompositingConfig::load() { kDebug() ; mKWinConfig->reparseConfiguration(); KConfigGroup config(mKWinConfig, "Compositing"); ui.useCompositing->setChecked(config.readEntry("Enabled", mDefaultPrefs.enableCompositing())); // Load effect settings config.changeGroup("Plugins"); #define LOAD_EFFECT_CONFIG(effectname) config.readEntry("kwin4_effect_" effectname "Enabled", true) bool winManagementEnabled = LOAD_EFFECT_CONFIG("presentwindows"); winManagementEnabled &= LOAD_EFFECT_CONFIG("boxswitch"); winManagementEnabled &= LOAD_EFFECT_CONFIG("desktopgrid"); winManagementEnabled &= LOAD_EFFECT_CONFIG("dialogparent"); ui.effectWinManagement->setChecked(winManagementEnabled); ui.effectShadows->setChecked(LOAD_EFFECT_CONFIG("shadow")); ui.effectAnimations->setChecked(LOAD_EFFECT_CONFIG("minimizeanimation")); ui.effectSelector->load(); emit changed( false ); } void KWinCompositingConfig::save() { kDebug() ; KConfigGroup config(mKWinConfig, "Compositing"); // Save current config. We'll use this for restoring in case something // goes wrong. mPreviousConfig = config.entryMap(); // Check if any critical settings that need confirmation have changed bool confirm = false; confirm |= (ui.useCompositing->isChecked() != config.readEntry("Enabled", mDefaultPrefs.enableCompositing())); config.writeEntry("Enabled", ui.useCompositing->isChecked()); // Save effects config.changeGroup("Plugins"); #define WRITE_EFFECT_CONFIG(effectname, widget) config.writeEntry("kwin4_effect_" effectname "Enabled", widget->isChecked()) WRITE_EFFECT_CONFIG("presentwindows", ui.effectWinManagement); WRITE_EFFECT_CONFIG("boxswitch", ui.effectWinManagement); WRITE_EFFECT_CONFIG("desktopgrid", ui.effectWinManagement); WRITE_EFFECT_CONFIG("dialogparent", ui.effectWinManagement); WRITE_EFFECT_CONFIG("shadow", ui.effectShadows); // TODO: maybe also do some effect-specific configuration here, e.g. // enable/disable desktopgrid's animation according to this setting WRITE_EFFECT_CONFIG("minimizeanimation", ui.effectAnimations); #undef WRITE_EFFECT_CONFIG ui.effectSelector->save(); emit changed( false ); configChanged(); if(confirm) { showConfirmDialog(); } } void KWinCompositingConfig::configChanged() { // Send signal to kwin mKWinConfig->sync(); // Send signal to all kwin instances QDBusMessage message = QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig"); QDBusConnection::sessionBus().send(message); } void KWinCompositingConfig::defaults() { kDebug() ; ui.useCompositing->setChecked(mDefaultPrefs.enableCompositing()); ui.effectWinManagement->setChecked(true); ui.effectShadows->setChecked(true); ui.effectAnimations->setChecked(true); ui.effectSelector->defaults(); } QString KWinCompositingConfig::quickHelp() const { kDebug() ; return i18n("

Desktop Effects

"); } } // namespace #include "main.moc"