diff --git a/kcmkwin/kwincompositing/main.cpp b/kcmkwin/kwincompositing/main.cpp
index 622e4c2e5f..c8ac20f80c 100644
--- a/kcmkwin/kwincompositing/main.cpp
+++ b/kcmkwin/kwincompositing/main.cpp
@@ -25,7 +25,6 @@ along with this program. If not, see .
#include
#include
#include
-#include
#include
#include
#include
@@ -35,7 +34,6 @@ along with this program. If not, see .
#include
#include
-#include
#include
#include
#include
@@ -69,8 +67,9 @@ ConfirmDialog::ConfirmDialog() :
KWinCompositingConfig::KWinCompositingConfig(QWidget *parent, const QVariantList &)
- : KCModule( KWinCompositingConfigFactory::componentData(), parent),
- mNewConfig( KSharedConfig::openConfig( "kwinrc" ) )
+ : KCModule( KWinCompositingConfigFactory::componentData(), parent )
+ , mKWinConfig(KSharedConfig::openConfig( "kwinrc" ))
+ , m_showConfirmDialog( false )
{
KGlobal::locale()->insertCatalog( "kwin_effects" );
ui.setupUi(this);
@@ -88,6 +87,8 @@ KWinCompositingConfig::KWinCompositingConfig(QWidget *parent, const QVariantList
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&)));
connect(ui.windowSwitchingCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(changed()));
connect(ui.desktopSwitchingCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(changed()));
@@ -96,6 +97,7 @@ KWinCompositingConfig::KWinCompositingConfig(QWidget *parent, const QVariantList
connect(ui.edges_monitor, SIGNAL(changed()), this, SLOT(changed()));
connect(ui.edges_monitor, SIGNAL(edgeSelectionChanged(int,int)), this, SLOT(electricBorderSelectionChanged(int,int)));
+ connect(ui.compositingType, SIGNAL(currentIndexChanged(int)), this, SLOT(compositingModeChanged()));
connect(ui.compositingType, SIGNAL(currentIndexChanged(int)), this, SLOT(changed()));
connect(ui.windowThumbnails, SIGNAL(activated(int)), this, SLOT(changed()));
connect(ui.disableChecks, SIGNAL(toggled(bool)), this, SLOT(changed()));
@@ -105,20 +107,12 @@ KWinCompositingConfig::KWinCompositingConfig(QWidget *parent, const QVariantList
connect(ui.glVSync, SIGNAL(toggled(bool)), this, SLOT(changed()));
connect(ui.xrenderSmoothScale, SIGNAL(toggled(bool)), this, SLOT(changed()));
- // TODO: Apparently nobody can tell why this slot should be needed. Could possibly be removed.
- connect( ui.effectSelector, SIGNAL( configCommitted( const QByteArray& ) ),
- this, SLOT( reparseConfiguration( const QByteArray& ) ) );
-
- // Create the backup config. It will be used as a means to revert the config if
- // the X server crashes and to determine if a confirmation dialog should be shown.
- // After the new settings have been confirmed to be stable, it is updated with the new
- // config. It will be written to disk before a new config is loaded and is deleted after
- // the user has confirmed the new settings.
- mBackupConfig = new KConfig( mNewConfig->name() + '~', KConfig::SimpleConfig );
- updateBackupWithNewConfig();
- // If the backup file already exists, it is a residue we want to clean up; it would
- // probably be in an invalid state anyway.
- deleteBackupConfigFile();
+ // Open the temporary config file
+ // Temporary conf file is used to synchronize effect checkboxes with effect
+ // selector by loading/saving effects from/to temp config when active tab
+ // changes.
+ mTmpConfigFile.open();
+ mTmpConfig = KSharedConfig::openConfig(mTmpConfigFile.fileName());
if( CompositingPrefs::compositingPossible() )
{
@@ -187,9 +181,6 @@ KWinCompositingConfig::KWinCompositingConfig(QWidget *parent, const QVariantList
KWinCompositingConfig::~KWinCompositingConfig()
{
- // Make sure that the backup config is not written to disk.
- mBackupConfig->markAsClean();
- delete mBackupConfig;
}
void KWinCompositingConfig::reparseConfiguration( const QByteArray& conf )
@@ -197,7 +188,7 @@ void KWinCompositingConfig::reparseConfiguration( const QByteArray& conf )
KSettings::Dispatcher::reparseConfiguration( conf );
}
-void KWinCompositingConfig::compositingEnabled(bool enabled)
+void KWinCompositingConfig::compositingEnabled( bool enabled )
{
// Enable the other configuration tabs only when compositing is enabled.
ui.compositingOptionsContainer->setEnabled(enabled);
@@ -206,6 +197,45 @@ void KWinCompositingConfig::compositingEnabled(bool enabled)
ui.tabWidget->setTabEnabled(3, enabled);
}
+void KWinCompositingConfig::showConfirmDialog( bool reinitCompositing )
+ {
+ bool revert = false;
+ // Feel free to extend this to support several kwin instances (multihead) if you
+ // think it makes sense.
+ OrgKdeKWinInterface kwin("org.kde.kwin", "/KWin", QDBusConnection::sessionBus());
+ if( reinitCompositing ? !kwin.compositingActive().value() : !kwin.waitForCompositingSetup().value() )
+ {
+ KMessageBox::sorry( this, i18n(
+ "Failed to activate desktop effects using the given "
+ "configuration options. Settings will be reverted to their previous values.\n\n"
+ "Check your X configuration. You may also consider changing advanced options, "
+ "especially changing the compositing type." ));
+ revert = true;
+ }
+ else
+ {
+ ConfirmDialog confirm;
+ if( !confirm.exec())
+ revert = true;
+ }
+ if( revert )
+ {
+ // Revert settings
+ KConfigGroup config(mKWinConfig, "Compositing");
+ config.deleteGroup();
+ QMap::const_iterator it = mPreviousConfig.constBegin();
+ for(; it != mPreviousConfig.constEnd(); ++it)
+ {
+ if (it.value().isEmpty())
+ continue;
+ config.writeEntry(it.key(), it.value());
+ }
+ // Sync with KWin and reload
+ configChanged(reinitCompositing);
+ load();
+ }
+ }
+
void KWinCompositingConfig::initEffectSelector()
{
// Find all .desktop files of the effects
@@ -213,14 +243,14 @@ void KWinCompositingConfig::initEffectSelector()
QList effectinfos = KPluginInfo::fromServices(offers);
// Add them to the plugin selector
- ui.effectSelector->addPlugins(effectinfos, KPluginSelector::ReadConfigFile, i18n("Appearance"), "Appearance", mNewConfig);
- ui.effectSelector->addPlugins(effectinfos, KPluginSelector::ReadConfigFile, i18n("Accessibility"), "Accessibility", mNewConfig);
- ui.effectSelector->addPlugins(effectinfos, KPluginSelector::ReadConfigFile, i18n("Focus"), "Focus", mNewConfig);
- ui.effectSelector->addPlugins(effectinfos, KPluginSelector::ReadConfigFile, i18n("Window Management"), "Window Management", mNewConfig);
- ui.effectSelector->addPlugins(effectinfos, KPluginSelector::ReadConfigFile, i18n("Candy"), "Candy", mNewConfig);
- ui.effectSelector->addPlugins(effectinfos, KPluginSelector::ReadConfigFile, i18n("Demos"), "Demos", mNewConfig);
- ui.effectSelector->addPlugins(effectinfos, KPluginSelector::ReadConfigFile, i18n("Tests"), "Tests", mNewConfig);
- ui.effectSelector->addPlugins(effectinfos, KPluginSelector::ReadConfigFile, i18n("Tools"), "Tools", mNewConfig);
+ ui.effectSelector->addPlugins(effectinfos, KPluginSelector::ReadConfigFile, i18n("Appearance"), "Appearance", mTmpConfig);
+ ui.effectSelector->addPlugins(effectinfos, KPluginSelector::ReadConfigFile, i18n("Accessibility"), "Accessibility", mTmpConfig);
+ ui.effectSelector->addPlugins(effectinfos, KPluginSelector::ReadConfigFile, i18n("Focus"), "Focus", mTmpConfig);
+ ui.effectSelector->addPlugins(effectinfos, KPluginSelector::ReadConfigFile, i18n("Window Management"), "Window Management", mTmpConfig);
+ ui.effectSelector->addPlugins(effectinfos, KPluginSelector::ReadConfigFile, i18n("Candy"), "Candy", mTmpConfig);
+ ui.effectSelector->addPlugins(effectinfos, KPluginSelector::ReadConfigFile, i18n("Demos"), "Demos", mTmpConfig);
+ ui.effectSelector->addPlugins(effectinfos, KPluginSelector::ReadConfigFile, i18n("Tests"), "Tests", mTmpConfig);
+ ui.effectSelector->addPlugins(effectinfos, KPluginSelector::ReadConfigFile, i18n("Tools"), "Tools", mTmpConfig);
}
void KWinCompositingConfig::currentTabChanged(int tab)
@@ -249,12 +279,12 @@ void KWinCompositingConfig::currentTabChanged(int tab)
void KWinCompositingConfig::loadGeneralTab()
{
- KConfigGroup config(mNewConfig, "Compositing");
+ KConfigGroup config(mKWinConfig, "Compositing");
ui.useCompositing->setChecked(config.readEntry("Enabled", mDefaultPrefs.enableCompositing()));
ui.animationSpeedCombo->setCurrentIndex(config.readEntry("AnimationSpeed", 3 ));
// Load effect settings
- KConfigGroup effectconfig(mNewConfig, "Plugins");
+ KConfigGroup effectconfig(mTmpConfig, "Plugins");
#define LOAD_EFFECT_CONFIG(effectname) effectconfig.readEntry("kwin4_effect_" effectname "Enabled", true)
int winManagementEnabled = LOAD_EFFECT_CONFIG("presentwindows")
+ LOAD_EFFECT_CONFIG("desktopgrid")
@@ -279,7 +309,7 @@ void KWinCompositingConfig::loadGeneralTab()
ui.windowSwitchingCombo->setCurrentIndex( 3 );
if( effectEnabled( "flipswitch", effectconfig ))
ui.windowSwitchingCombo->setCurrentIndex( 4 );
- KConfigGroup presentwindowsconfig(mNewConfig, "Effect-PresentWindows");
+ KConfigGroup presentwindowsconfig(mKWinConfig, "Effect-PresentWindows");
if( effectEnabled( "presentwindows", effectconfig ) && presentwindowsconfig.readEntry("TabBox", false) )
ui.windowSwitchingCombo->setCurrentIndex( 2 );
@@ -288,9 +318,11 @@ void KWinCompositingConfig::loadGeneralTab()
ui.desktopSwitchingCombo->setCurrentIndex( 0 );
if( effectEnabled( "slide", effectconfig ))
ui.desktopSwitchingCombo->setCurrentIndex( 1 );
- KConfigGroup cubeconfig(mNewConfig, "Effect-Cube");
+ KConfigGroup cubeconfig(mKWinConfig, "Effect-Cube");
if( effectEnabled( "cube", effectconfig ) && cubeconfig.readEntry("AnimateDesktopChange", false))
ui.desktopSwitchingCombo->setCurrentIndex( 2 );
+
+ loadElectricBorders();
}
bool KWinCompositingConfig::effectEnabled( const QString& effect, const KConfigGroup& cfg ) const
@@ -310,7 +342,7 @@ void KWinCompositingConfig::loadEffectsTab()
void KWinCompositingConfig::loadAdvancedTab()
{
- KConfigGroup config(mNewConfig, "Compositing");
+ KConfigGroup config(mKWinConfig, "Compositing");
QString backend = config.readEntry("Backend", "OpenGL");
ui.compositingType->setCurrentIndex((backend == "XRender") ? 1 : 0);
// 4 - off, 5 - shown, 6 - always, other are old values
@@ -334,11 +366,17 @@ void KWinCompositingConfig::loadAdvancedTab()
void KWinCompositingConfig::load()
{
- // Discard any unsaved changes.
- resetNewToBackupConfig();
+ mKWinConfig->reparseConfiguration();
+
+ // Copy Plugins group to temp config file
+ QMap entries = mKWinConfig->entryMap("Plugins");
+ QMap::const_iterator it = entries.constBegin();
+ KConfigGroup tmpconfig(mTmpConfig, "Plugins");
+ tmpconfig.deleteGroup();
+ for(; it != entries.constEnd(); ++it)
+ tmpconfig.writeEntry(it.key(), it.value());
loadGeneralTab();
- loadElectricBorders();
loadEffectsTab();
loadAdvancedTab();
@@ -347,13 +385,17 @@ void KWinCompositingConfig::load()
void KWinCompositingConfig::saveGeneralTab()
{
- KConfigGroup config(mNewConfig, "Compositing");
+ KConfigGroup config(mKWinConfig, "Compositing");
+ // Check if any critical settings that need confirmation have changed
+ if(ui.useCompositing->isChecked() &&
+ ui.useCompositing->isChecked() != config.readEntry("Enabled", mDefaultPrefs.enableCompositing()))
+ m_showConfirmDialog = true;
config.writeEntry("Enabled", ui.useCompositing->isChecked());
config.writeEntry("AnimationSpeed", ui.animationSpeedCombo->currentIndex());
// Save effects
- KConfigGroup effectconfig( mNewConfig, "Plugins" );
+ KConfigGroup effectconfig(mTmpConfig, "Plugins");
#define WRITE_EFFECT_CONFIG(effectname, widget) effectconfig.writeEntry("kwin4_effect_" effectname "Enabled", widget->isChecked())
if (ui.effectWinManagement->checkState() != Qt::PartiallyChecked)
{
@@ -404,7 +446,7 @@ void KWinCompositingConfig::saveGeneralTab()
effectconfig.writeEntry("kwin4_effect_flipswitchEnabled", true);
break;
}
- KConfigGroup presentwindowsconfig(mNewConfig, "Effect-PresentWindows");
+ KConfigGroup presentwindowsconfig(mKWinConfig, "Effect-PresentWindows");
presentwindowsconfig.writeEntry("TabBox", presentWindowSwitching);
int desktopSwitcher = ui.desktopSwitchingCombo->currentIndex();
@@ -426,8 +468,10 @@ void KWinCompositingConfig::saveGeneralTab()
effectconfig.writeEntry("kwin4_effect_cubeEnabled", true);
break;
}
- KConfigGroup cubeconfig(mNewConfig, "Effect-Cube");
+ KConfigGroup cubeconfig(mKWinConfig, "Effect-Cube");
cubeconfig.writeEntry("AnimateDesktopChange", cubeDesktopSwitching);
+
+ saveElectricBorders();
}
void KWinCompositingConfig::saveEffectsTab()
@@ -435,13 +479,29 @@ void KWinCompositingConfig::saveEffectsTab()
ui.effectSelector->save();
}
-void KWinCompositingConfig::saveAdvancedTab()
+bool KWinCompositingConfig::saveAdvancedTab()
{
+ bool advancedChanged = false;
static const int hps[] = { 6 /*always*/, 5 /*shown*/, 4 /*never*/ };
- KConfigGroup config(mNewConfig, "Compositing");
+ KConfigGroup config(mKWinConfig, "Compositing");
QString glModes[] = { "TFP", "SHM", "Fallback" };
+ if( config.readEntry("Backend", "OpenGL")
+ != ((ui.compositingType->currentIndex() == 0) ? "OpenGL" : "XRender")
+ || config.readEntry("GLMode", "TFP") != glModes[ui.glMode->currentIndex()]
+ || config.readEntry("GLDirect", mDefaultPrefs.enableDirectRendering())
+ != ui.glDirect->isChecked()
+ || config.readEntry("GLVSync", mDefaultPrefs.enableVSync()) != ui.glVSync->isChecked()
+ || config.readEntry("DisableChecks", false ) != ui.disableChecks->isChecked())
+ {
+ m_showConfirmDialog = true;
+ advancedChanged = true;
+ }
+ else if( config.readEntry("HiddenPreviews", 5) != hps[ ui.windowThumbnails->currentIndex() ]
+ || config.readEntry("XRenderSmoothScale", false ) != ui.xrenderSmoothScale->isChecked() )
+ advancedChanged = true;
+
config.writeEntry("Backend", (ui.compositingType->currentIndex() == 0) ? "OpenGL" : "XRender");
config.writeEntry("HiddenPreviews", hps[ ui.windowThumbnails->currentIndex() ] );
config.writeEntry("DisableChecks", ui.disableChecks->isChecked());
@@ -452,10 +512,16 @@ void KWinCompositingConfig::saveAdvancedTab()
config.writeEntry("GLVSync", ui.glVSync->isChecked());
config.writeEntry("XRenderSmoothScale", ui.xrenderSmoothScale->isChecked());
+
+ return advancedChanged;
}
void KWinCompositingConfig::save()
{
+ // Save current config. We'll use this for restoring in case something goes wrong.
+ KConfigGroup config(mKWinConfig, "Compositing");
+ mPreviousConfig = config.entryMap();
+
// bah; tab content being dependent on the other is really bad; and
// deprecated in the HIG for a reason. Its confusing!
// Make sure we only call save on each tab once; as they are stateful due to the revert concept
@@ -471,15 +537,38 @@ void KWinCompositingConfig::save()
loadGeneralTab();
saveGeneralTab();
}
+ bool advancedChanged = saveAdvancedTab();
- saveElectricBorders();
- saveAdvancedTab();
+ // Copy Plugins group from temp config to real config
+ QMap entries = mTmpConfig->entryMap("Plugins");
+ QMap::const_iterator it = entries.constBegin();
+ KConfigGroup realconfig(mKWinConfig, "Plugins");
+ realconfig.deleteGroup();
+ for(; it != entries.constEnd(); ++it)
+ realconfig.writeEntry(it.key(), it.value());
emit changed( false );
- activateNewConfig();
+ configChanged(advancedChanged);
+
+ if(m_showConfirmDialog)
+ {
+ m_showConfirmDialog = false;
+ showConfirmDialog(advancedChanged);
+ }
}
+void KWinCompositingConfig::configChanged(bool reinitCompositing)
+ {
+ // Send signal to kwin
+ mKWinConfig->sync();
+ // Send signal to all kwin instances
+ QDBusMessage message = QDBusMessage::createSignal("/KWin", "org.kde.KWin",
+ reinitCompositing ? "reinitCompositing" : "reloadConfig");
+ QDBusConnection::sessionBus().send(message);
+ }
+
+
void KWinCompositingConfig::defaults()
{
ui.tabWidget->setCurrentIndex(0);
@@ -518,7 +607,6 @@ QString KWinCompositingConfig::quickHelp() const
return i18n("Desktop Effects
");
}
-
void KWinCompositingConfig::setupElectricBorders()
{
addItemToEdgesMonitor( i18n("No Effect"));
@@ -534,32 +622,22 @@ void KWinCompositingConfig::setupElectricBorders()
}
services = trader->query("KWin/Effect", "[X-KDE-PluginInfo-Name] == 'kwin4_effect_desktopgrid'");
if( !services.isEmpty() )
- {
addItemToEdgesMonitor( services.first()->name());
- }
services = trader->query("KWin/Effect", "[X-KDE-PluginInfo-Name] == 'kwin4_effect_cube'");
if( !services.isEmpty() )
- {
addItemToEdgesMonitor( services.first()->name());
- }
services = trader->query("KWin/Effect", "[X-KDE-PluginInfo-Name] == 'kwin4_effect_cylinder'");
if( !services.isEmpty() )
- {
addItemToEdgesMonitor( services.first()->name());
- }
services = trader->query("KWin/Effect", "[X-KDE-PluginInfo-Name] == 'kwin4_effect_sphere'");
if( !services.isEmpty() )
- {
addItemToEdgesMonitor( services.first()->name());
- }
}
void KWinCompositingConfig::addItemToEdgesMonitor(const QString& item)
{
for( int i=0; i<8; i++ )
- {
ui.edges_monitor->addEdgeItem( i, item );
- }
}
void KWinCompositingConfig::electricBorderSelectionChanged(int edge, int index)
@@ -579,25 +657,25 @@ void KWinCompositingConfig::electricBorderSelectionChanged(int edge, int index)
void KWinCompositingConfig::loadElectricBorders()
{
// Present Windows
- KConfigGroup presentwindowsconfig(mNewConfig, "Effect-PresentWindows");
+ KConfigGroup presentwindowsconfig(mKWinConfig, "Effect-PresentWindows");
changeElectricBorder( (ElectricBorder)presentwindowsconfig.readEntry( "BorderActivateAll",
int( ElectricTopLeft )), (int)PresentWindowsAll );
changeElectricBorder( (ElectricBorder)presentwindowsconfig.readEntry( "BorderActivate",
int( ElectricNone )), (int)PresentWindowsCurrent );
// Desktop Grid
- KConfigGroup gridconfig(mNewConfig, "Effect-DesktopGrid");
+ KConfigGroup gridconfig(mKWinConfig, "Effect-DesktopGrid");
changeElectricBorder( (ElectricBorder)gridconfig.readEntry( "BorderActivate",
int( ElectricNone )), (int)DesktopGrid );
// Desktop Cube
- KConfigGroup cubeconfig(mNewConfig, "Effect-Cube");
+ KConfigGroup cubeconfig(mKWinConfig, "Effect-Cube");
changeElectricBorder( (ElectricBorder)cubeconfig.readEntry( "BorderActivate",
int( ElectricNone )), (int)Cube );
// Desktop Cylinder
- KConfigGroup cylinderconfig(mNewConfig, "Effect-Cylinder");
+ KConfigGroup cylinderconfig(mKWinConfig, "Effect-Cylinder");
changeElectricBorder( (ElectricBorder)cylinderconfig.readEntry( "BorderActivate",
int( ElectricNone )), (int)Cylinder );
// Desktop Grid
- KConfigGroup sphereconfig(mNewConfig, "Effect-Sphere");
+ KConfigGroup sphereconfig(mKWinConfig, "Effect-Sphere");
changeElectricBorder( (ElectricBorder)sphereconfig.readEntry( "BorderActivate",
int( ElectricNone )), (int)Sphere );
}
@@ -639,213 +717,42 @@ void KWinCompositingConfig::changeElectricBorder( ElectricBorder border, int ind
ElectricBorder KWinCompositingConfig::checkEffectHasElectricBorder( int index )
{
if( ui.edges_monitor->selectedEdgeItem( (int)Monitor::Top ) == index )
- {
return ElectricTop;
- }
if( ui.edges_monitor->selectedEdgeItem( (int)Monitor::TopRight ) == index )
- {
return ElectricTopRight;
- }
if( ui.edges_monitor->selectedEdgeItem( (int)Monitor::Right ) == index )
- {
return ElectricRight;
- }
if( ui.edges_monitor->selectedEdgeItem( (int)Monitor::BottomRight ) == index )
- {
return ElectricBottomRight;
- }
if( ui.edges_monitor->selectedEdgeItem( (int)Monitor::Bottom ) == index )
- {
return ElectricBottom;
- }
if( ui.edges_monitor->selectedEdgeItem( (int)Monitor::BottomLeft ) == index )
- {
return ElectricBottomLeft;
- }
if( ui.edges_monitor->selectedEdgeItem( (int)Monitor::Left ) == index )
- {
return ElectricLeft;
- }
if( ui.edges_monitor->selectedEdgeItem( (int)Monitor::TopLeft ) == index )
- {
return ElectricTopLeft;
- }
return ElectricNone;
}
void KWinCompositingConfig::saveElectricBorders()
- {
- KConfigGroup presentwindowsconfig(mNewConfig, "Effect-PresentWindows");
+{
+ KConfigGroup presentwindowsconfig(mKWinConfig, "Effect-PresentWindows");
presentwindowsconfig.writeEntry( "BorderActivateAll", (int)checkEffectHasElectricBorder( (int)PresentWindowsAll ));
presentwindowsconfig.writeEntry( "BorderActivate", (int)checkEffectHasElectricBorder( (int)PresentWindowsCurrent ));
- KConfigGroup gridconfig(mNewConfig, "Effect-DesktopGrid");
+ KConfigGroup gridconfig(mKWinConfig, "Effect-DesktopGrid");
gridconfig.writeEntry( "BorderActivate", (int)checkEffectHasElectricBorder( (int)DesktopGrid ));
- KConfigGroup cubeconfig(mNewConfig, "Effect-Cube");
+ KConfigGroup cubeconfig(mKWinConfig, "Effect-Cube");
cubeconfig.writeEntry( "BorderActivate", (int)checkEffectHasElectricBorder( (int)Cube ));
- KConfigGroup cylinderconfig(mNewConfig, "Effect-Cylinder");
+ KConfigGroup cylinderconfig(mKWinConfig, "Effect-Cylinder");
cylinderconfig.writeEntry( "BorderActivate", (int)checkEffectHasElectricBorder( (int)Cylinder ));
- KConfigGroup sphereconfig(mNewConfig, "Effect-Sphere");
+ KConfigGroup sphereconfig(mKWinConfig, "Effect-Sphere");
sphereconfig.writeEntry( "BorderActivate", (int)checkEffectHasElectricBorder( (int)Sphere ));
- }
-
-void KWinCompositingConfig::activateNewConfig()
- {
- // Write the backup file to disk so it can be used on the next KWin start
- // if KWin or the X server should crash while testing the new config.
- mBackupConfig->sync();
-
- bool configOk = true;
-
- // Tell KWin to load the new configuration.
- bool couldReload = sendKWinReloadSignal();
- // If it was not successfull, show an error message to the user.
- if ( !couldReload )
- {
- KMessageBox::sorry( this, i18n(
- "Failed to activate desktop effects using the given "
- "configuration options. Settings will be reverted to their previous values.\n\n"
- "Check your X configuration. You may also consider changing advanced options, "
- "especially changing the compositing type." ) );
- configOk = false;
- }
- else
- {
- // If the confirmation dialog should be shown, wait for its result.
- if ( isConfirmationNeeded() )
- {
- ConfirmDialog confirm;
- configOk = confirm.exec();
- }
- }
-
- if ( configOk )
- {
- // The new config is stable and was accepted.
- // Update our internal backup copy of the config.
- updateBackupWithNewConfig();
- }
- else
- {
- // Copy back the old config and load it into the ui.
- load();
- // Tell KWin to reload the (old) config.
- sendKWinReloadSignal();
- }
-
- // Remove the backup file from disk because it is the same as the main config
- // anyway and would only confuse the startup code if KWin is restarted while
- // this module is still opened, (e.g. by calling "kwin --replace").
- deleteBackupConfigFile();
- }
-
-bool KWinCompositingConfig::isConfirmationNeeded() const
- {
- // Compare new config with the backup and see if any potentially dangerous
- // values have been changed.
- KConfigGroup newGroup( mNewConfig, "Compositing" );
- KConfigGroup backupGroup( mBackupConfig, "Compositing" );
-
- // Manually enabling compositing is potentially dangerous, but disabling is never.
- bool newEnabled = newGroup.readEntry( "Enabled", mDefaultPrefs.enableCompositing() );
- bool backupEnabled = backupGroup.readEntry( "Enabled", mDefaultPrefs.enableCompositing() );
- if ( newEnabled && !backupEnabled )
- {
- return true;
- }
-
- // All potentially dangerous options along with their (usually safe) default values.
- QHash confirm;
- confirm[ "Backend" ] = "OpenGL";
- confirm[ "GLMode" ] = "TFP";
- confirm[ "GLDirect" ] = mDefaultPrefs.enableDirectRendering();
- confirm[ "GLVSync" ] = mDefaultPrefs.enableVSync();
- confirm[ "DisableChecks" ] = false;
-
- QHash::const_iterator i = confirm.constBegin();
- for( ; i != confirm.constEnd(); ++i )
- {
- if ( newGroup.readEntry( i.key(), i.value() ) !=
- backupGroup.readEntry( i.key(), i.value() ) )
- {
- return true;
- }
- }
-
- // If we have not returned yet, no critical settings have been changed.
- return false;
- }
-
-bool KWinCompositingConfig::sendKWinReloadSignal()
- {
- // Save the new config to the file system, thus allowing KWin to read it.
- mNewConfig->sync();
-
- // Send signal to all kwin instances.
- QDBusMessage message = QDBusMessage::createSignal( "/KWin", "org.kde.KWin", "reloadCompositingConfig" );
- QDBusConnection::sessionBus().send(message);
-
- //-------------
- // If we added or removed shadows we need to reload decorations as well
- // We have to do this separately so the settings are in sync
- // HACK: This should really just reload decorations, not do a full reconfigure
-
- KConfigGroup effectConfig;
-
- effectConfig = KConfigGroup( mBackupConfig, "Compositing" );
- bool enabledBefore = effectConfig.readEntry( "Enabled", mDefaultPrefs.enableCompositing() );
- effectConfig = KConfigGroup( mNewConfig, "Compositing" );
- bool enabledAfter = effectConfig.readEntry( "Enabled", mDefaultPrefs.enableCompositing() );
-
- effectConfig = KConfigGroup( mBackupConfig, "Plugins" );
- bool shadowBefore = effectEnabled( "shadow", effectConfig );
- effectConfig = KConfigGroup( mNewConfig, "Plugins" );
- bool shadowAfter = effectEnabled( "shadow", effectConfig );
-
- if( enabledBefore != enabledAfter || shadowBefore != shadowAfter )
- {
- message = QDBusMessage::createMethodCall( "org.kde.kwin", "/KWin", "org.kde.KWin", "reconfigure" );
- QDBusConnection::sessionBus().send( message );
- }
-
- //-------------
-
- // If compositing is enabled, check if it could be started.
- KConfigGroup newGroup( mNewConfig, "Compositing" );
- bool enabled = newGroup.readEntry( "Enabled", mDefaultPrefs.enableCompositing() );
-
- if ( !enabled )
- {
- return true;
- }
- else
- {
- // Feel free to extend this to support several kwin instances (multihead) if you
- // think it makes sense.
- OrgKdeKWinInterface kwin( "org.kde.kwin", "/KWin", QDBusConnection::sessionBus() );
- return kwin.compositingActive().value();
- }
- }
-
-void KWinCompositingConfig::updateBackupWithNewConfig()
- {
- mNewConfig->copyTo( mBackupConfig->name(), mBackupConfig );
- }
-
-void KWinCompositingConfig::resetNewToBackupConfig()
- {
- mBackupConfig->copyTo( mNewConfig->name(), mNewConfig.data() );
- }
-
-void KWinCompositingConfig::deleteBackupConfigFile()
- {
- QString backupFileName = KStandardDirs::locate( "config", mBackupConfig->name() );
- // If the file does not exist, QFile::remove() just fails silently.
- QFile::remove( backupFileName );
- }
+}
} // namespace
diff --git a/kcmkwin/kwincompositing/main.h b/kcmkwin/kwincompositing/main.h
index d24e2e4048..6e9c0dfe87 100644
--- a/kcmkwin/kwincompositing/main.h
+++ b/kcmkwin/kwincompositing/main.h
@@ -53,48 +53,43 @@ class KWinCompositingConfig : public KCModule
virtual QString quickHelp() const;
public slots:
+ virtual void compositingEnabled(bool enabled);
+ virtual void showConfirmDialog(bool reinitCompositing);
+ void currentTabChanged(int tab);
+
virtual void load();
virtual void save();
virtual void defaults();
+ void reparseConfiguration(const QByteArray& conf);
- private slots:
- void reparseConfiguration( const QByteArray& conf );
- void compositingEnabled(bool enabled);
- void currentTabChanged(int tab);
- void electricBorderSelectionChanged(int edge, int index);
-
- private:
void loadGeneralTab();
void loadEffectsTab();
void loadAdvancedTab();
void loadElectricBorders();
void saveGeneralTab();
void saveEffectsTab();
- void saveAdvancedTab();
+ bool saveAdvancedTab();
+ void electricBorderSelectionChanged(int edge, int index);
+ void configChanged(bool reinitCompositing);
void initEffectSelector();
+ private:
bool effectEnabled( const QString& effect, const KConfigGroup& cfg ) const;
-
void setupElectricBorders();
void addItemToEdgesMonitor(const QString& item);
void changeElectricBorder( ElectricBorder border, int index );
ElectricBorder checkEffectHasElectricBorder( int index );
void saveElectricBorders();
- void activateNewConfig();
- bool isConfirmationNeeded() const;
- bool sendKWinReloadSignal();
-
- void updateBackupWithNewConfig();
- void resetNewToBackupConfig();
- void deleteBackupConfigFile();
-
+ KSharedConfigPtr mKWinConfig;
Ui::KWinCompositingConfig ui;
CompositingPrefs mDefaultPrefs;
- KSharedConfigPtr mNewConfig;
- KConfig* mBackupConfig;
+ QMap mPreviousConfig;
+ KTemporaryFile mTmpConfigFile;
+ KSharedConfigPtr mTmpConfig;
+ bool m_showConfirmDialog;
enum ElectricBorderEffects
{
diff --git a/options.cpp b/options.cpp
index a7ceb5aef3..b3151d381b 100644
--- a/options.cpp
+++ b/options.cpp
@@ -23,12 +23,10 @@ along with this program. If not, see .
#ifndef KCMRULES
-#include
#include
#include
#include
#include
-#include
#include
#include
@@ -47,14 +45,9 @@ namespace KWin
#ifndef KCMRULES
Options::Options()
+ : electric_borders( 0 )
+ , electric_border_delay( 0 )
{
- // If there is any contents in the backup file, it means that KWin crashed
- // while testing a new config. Revert the config.
- // TODO: Notify the user?
- if( importBackup() )
- kWarning( 1212 ) << "The new settings have most likely caused the X server "
- "to crash. The configuration options have been reverted to their old values.";
-
updateSettings();
}
@@ -62,44 +55,13 @@ Options::~Options()
{
}
-
unsigned long Options::updateSettings()
{
- return loadSettings( KGlobal::config() );
- }
-
-bool Options::importBackup()
- {
- QString configFileName = KStandardDirs::locate( "config", KGlobal::config()->name() );
- QString backupFileName = configFileName + '~';
-
- if ( !QFile::exists( backupFileName ) )
- {
- return false;
- }
-
- QFile::remove( configFileName );
- QFile::rename( backupFileName, configFileName );
-
- KGlobal::config()->reparseConfiguration();
- return true;
- }
-
-unsigned long Options::loadSettings( KSharedConfigPtr configFile )
- {
+ KSharedConfig::Ptr _config = KGlobal::config();
unsigned long changed = 0;
- changed |= KDecorationOptions::updateSettings( configFile.data() ); // read decoration settings
+ changed |= KDecorationOptions::updateSettings( _config.data() ); // read decoration settings
- loadWindowSettings( configFile );
- loadMouseBindings( configFile );
- loadCompositingSettings( configFile );
-
- return changed;
- }
-
-void Options::loadWindowSettings( KSharedConfigPtr configFile )
- {
- KConfigGroup config( configFile, "Windows" );
+ KConfigGroup config( _config, "Windows" );
moveMode = stringToMoveResizeMode( config.readEntry("MoveMode", "Opaque" ));
resizeMode = stringToMoveResizeMode( config.readEntry("ResizeMode", "Opaque" ));
show_geometry_tip = config.readEntry("GeometryTip", false);
@@ -132,7 +94,6 @@ void Options::loadWindowSettings( KSharedConfigPtr configFile )
if( !focusPolicyIsReasonable()) // #48786, comments #7 and later
focusStealingPreventionLevel = 0;
- // This was once loaded from kdeglobals.
xineramaEnabled = config.readEntry ("XineramaEnabled", true);
xineramaPlacementEnabled = config.readEntry ("XineramaPlacementEnabled", true);
xineramaMovementEnabled = config.readEntry ("XineramaMovementEnabled", true);
@@ -193,29 +154,8 @@ void Options::loadWindowSettings( KSharedConfigPtr configFile )
hideUtilityWindowsForInactive = config.readEntry( "HideUtilityWindowsForInactive", true);
showDesktopIsMinimizeAll = config.readEntry( "ShowDesktopIsMinimizeAll", false );
- // Read button tooltip animation effect from kdeglobals
- // Since we want to allow users to enable window decoration tooltips
- // and not kstyle tooltips and vise-versa, we don't read the
- // "EffectNoTooltip" setting from kdeglobals.
-
-#if 0
- FIXME: we have no mac style menu implementation in kwin anymore, so this just breaks
- things for people!
- KConfig _globalConfig("kdeglobals");
- KConfigGroup globalConfig(&_globalConfig, "KDE");
- topmenus = globalConfig.readEntry("macStyle", false);
-#else
- topmenus = false;
-#endif
-
- // QToolTip::setGloballyEnabled( d->show_tooltips );
- // KDE4 this probably needs to be done manually in clients
- }
-
-void Options::loadMouseBindings( KSharedConfigPtr configFile )
- {
// Mouse bindings
- KConfigGroup config( configFile, "MouseBindings" );
+ config = KConfigGroup( _config, "MouseBindings" );
CmdActiveTitlebar1 = mouseCommand(config.readEntry("CommandActiveTitlebar1","Raise"), true );
CmdActiveTitlebar2 = mouseCommand(config.readEntry("CommandActiveTitlebar2","Lower"), true );
CmdActiveTitlebar3 = mouseCommand(config.readEntry("CommandActiveTitlebar3","Operations menu"), true );
@@ -231,19 +171,42 @@ void Options::loadMouseBindings( KSharedConfigPtr configFile )
CmdAll2 = mouseCommand(config.readEntry("CommandAll2","Toggle raise and lower"), false );
CmdAll3 = mouseCommand(config.readEntry("CommandAll3","Resize"), false );
CmdAllWheel = mouseWheelCommand(config.readEntry("CommandAllWheel","Nothing"));
- }
-void Options::loadCompositingSettings( KSharedConfigPtr configFile )
- {
+ config=KConfigGroup(_config,"Compositing");
+ refreshRate = config.readEntry( "RefreshRate", 0 );
+
+ // Read button tooltip animation effect from kdeglobals
+ // Since we want to allow users to enable window decoration tooltips
+ // and not kstyle tooltips and vise-versa, we don't read the
+ // "EffectNoTooltip" setting from kdeglobals.
+
+#if 0
+ FIXME: we have no mac style menu implementation in kwin anymore, so this just breaks
+ things for people!
+ KConfig _globalConfig("kdeglobals");
+ KConfigGroup globalConfig(&_globalConfig, "KDE");
+ topmenus = globalConfig.readEntry("macStyle", false);
+#else
+ topmenus = false;
+#endif
+
+// QToolTip::setGloballyEnabled( d->show_tooltips );
+// KDE4 this probably needs to be done manually in clients
+
// Driver-specific config detection
CompositingPrefs prefs;
prefs.detect();
+ reloadCompositingSettings( prefs );
+
+ return changed;
+ }
+
+void Options::reloadCompositingSettings(const CompositingPrefs& prefs)
+ {
+ KSharedConfig::Ptr _config = KGlobal::config();
+ KConfigGroup config(_config, "Compositing");
// Compositing settings
- KConfigGroup config( configFile, "Compositing");
-
- refreshRate = config.readEntry( "RefreshRate", 0 );
-
useCompositing = config.readEntry("Enabled", prefs.enableCompositing());
QString compositingBackend = config.readEntry("Backend", "OpenGL");
if( compositingBackend == "XRender" )
diff --git a/options.h b/options.h
index 45b9c6e21c..015a3d6260 100644
--- a/options.h
+++ b/options.h
@@ -44,7 +44,6 @@ class Options : public KDecorationOptions
~Options();
virtual unsigned long updateSettings();
- bool importBackup();
/*!
Different focus policies:
@@ -314,12 +313,6 @@ class Options : public KDecorationOptions
double animationTimeFactor() const;
private:
- unsigned long loadSettings( KSharedConfigPtr configFile );
- void loadWindowSettings( KSharedConfigPtr configFile );
- void loadMouseBindings( KSharedConfigPtr configFile );
- void loadCompositingSettings( KSharedConfigPtr configFile );
-
-
WindowOperation OpTitlebarDblClick;
// mouse bindings
@@ -349,6 +342,7 @@ class Options : public KDecorationOptions
int animationSpeed; // 0 - instant, 5 - very slow
MouseCommand wheelToMouseCommand( MouseWheelCommand com, int delta );
+ void reloadCompositingSettings(const CompositingPrefs& prefs);
};
extern Options* options;
diff --git a/org.kde.KWin.xml b/org.kde.KWin.xml
index ddc0605260..5b58242897 100644
--- a/org.kde.KWin.xml
+++ b/org.kde.KWin.xml
@@ -34,7 +34,7 @@
-
+
@@ -56,6 +56,9 @@
+
+
+
diff --git a/workspace.cpp b/workspace.cpp
index d6037ee3ad..409cb18375 100644
--- a/workspace.cpp
+++ b/workspace.cpp
@@ -147,7 +147,7 @@ Workspace::Workspace( bool restore )
QDBusConnection dbus = QDBusConnection::sessionBus();
dbus.registerObject("/KWin", this);
dbus.connect(QString(), "/KWin", "org.kde.KWin", "reloadConfig", this, SLOT(slotReloadConfig()));
- dbus.connect(QString(), "/KWin", "org.kde.KWin", "reloadCompositingConfig", this, SLOT(slotReloadCompositingConfig()));
+ dbus.connect(QString(), "/KWin", "org.kde.KWin", "reinitCompositing", this, SLOT(slotReinitCompositing()));
_self = this;
mgr = new PluginMgr;
QX11Info info;
@@ -972,6 +972,19 @@ void Workspace::reconfigure()
reconfigureTimer.start( 200 );
}
+// This DBUS call is used by the compositing kcm. Since the reconfigure()
+// DBUS call delays the actual reconfiguring, it is not possible to immediately
+// call compositingActive(). Therefore the kcm will instead call this to ensure
+// the reconfiguring has already happened.
+bool Workspace::waitForCompositingSetup()
+ {
+ if( !reconfigureTimer.isActive())
+ return false;
+ reconfigureTimer.stop();
+ slotReconfigure();
+ return compositingActive();
+ }
+
void Workspace::slotSettingsChanged(int category)
{
kDebug(1212) << "Workspace::slotSettingsChanged()";
@@ -1053,6 +1066,7 @@ void Workspace::slotReconfigure()
setupCompositing();
if( effects ) // setupCompositing() may fail
effects->reconfigure();
+ addRepaintFull();
}
else
finishCompositing();
@@ -1068,17 +1082,18 @@ void Workspace::slotReconfigure()
}
}
-void Workspace::slotReloadCompositingConfig()
+void Workspace::slotReinitCompositing()
{
- // Load the compositing settings from the test config.
+ // Reparse config. Config options will be reloaded by setupCompositing()
KGlobal::config()->reparseConfiguration();
options->updateSettings();
// Update any settings that can be set in the compositing kcm.
updateElectricBorders();
- // Reinitialize compositing.
+ // Stop any current compositing
finishCompositing();
+ // And start new one
setupCompositing();
if( effects ) // setupCompositing() may fail
effects->reconfigure();
diff --git a/workspace.h b/workspace.h
index 4bc78ff59b..32a928ddff 100644
--- a/workspace.h
+++ b/workspace.h
@@ -262,7 +262,8 @@ class Workspace : public QObject, public KDecorationDefines
void previousDesktop();
void circulateDesktopApplications();
bool compositingActive();
-
+ bool waitForCompositingSetup();
+
void setCurrentScreen( int new_screen );
QString desktopName( int desk ) const;
@@ -468,6 +469,7 @@ class Workspace : public QObject, public KDecorationDefines
void reconfigure();
void slotReconfigure();
+ void slotReinitCompositing();
void slotKillWindow();
@@ -498,7 +500,6 @@ class Workspace : public QObject, public KDecorationDefines
void writeWindowRules();
void slotBlockShortcuts(int data);
void slotReloadConfig();
- void slotReloadCompositingConfig();
void setPopupClientOpacity( QAction* action );
void setupCompositing();
void performCompositing();