1 /********************************************************************
2 KWin - the KDE window manager
3 This file is part of the KDE project.
5 Copyright (C) 2007 Rivo Laks <rivolaks@hot.ee>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *********************************************************************/
23 #include "kwin_interface.h"
25 #include <kaboutdata.h>
27 #include <kconfiggroup.h>
29 #include <kmessagebox.h>
30 #include <ksettings/dispatcher.h>
31 #include <kpluginselector.h>
32 #include <kservicetypetrader.h>
33 #include <kplugininfo.h>
35 #include <ktitlewidget.h>
37 #include <QtDBus/QtDBus>
40 #include <KPluginFactory>
41 #include <KPluginLoader>
44 K_PLUGIN_FACTORY(KWinCompositingConfigFactory
,
45 registerPlugin
<KWin::KWinCompositingConfig
>();
47 K_EXPORT_PLUGIN(KWinCompositingConfigFactory("kcmkwincompositing"))
53 ConfirmDialog::ConfirmDialog() :
54 KTimerDialog(10000, KTimerDialog::CountDown
, 0,
55 i18n("Confirm Desktop Effects Change"), KTimerDialog::Ok
|KTimerDialog::Cancel
,
58 setObjectName( "mainKTimerDialog" );
59 setButtonGuiItem( KDialog::Ok
, KGuiItem( i18n( "&Accept Configuration" ), "dialog-ok" ));
60 setButtonGuiItem( KDialog::Cancel
, KGuiItem( i18n( "&Return to Previous Configuration" ), "dialog-cancel" ));
62 QLabel
*label
= new QLabel( i18n( "Desktop effects settings have changed.\n"
63 "Do you want to keep the new settings?\n"
64 "They will be automatically reverted in 10 seconds." ), this );
65 label
->setWordWrap( true );
66 setMainWidget( label
);
68 setWindowIcon(KIcon("preferences-desktop-effect"));
72 KWinCompositingConfig::KWinCompositingConfig(QWidget
*parent
, const QVariantList
&)
73 : KCModule( KWinCompositingConfigFactory::componentData(), parent
)
74 , mKWinConfig(KSharedConfig::openConfig( "kwinrc" ))
75 , m_showConfirmDialog( false )
77 KGlobal::locale()->insertCatalog( "kwin_effects" );
79 layout()->setMargin(0);
80 ui
.tabWidget
->setCurrentIndex(0);
81 ui
.statusTitleWidget
->hide();
82 setupElectricBorders();
84 #define OPENGL_INDEX 0
85 #define XRENDER_INDEX 1
86 #ifndef KWIN_HAVE_OPENGL_COMPOSITING
87 ui
.compositingType
->removeItem( OPENGL_INDEX
);
88 ui
.glGroup
->setEnabled( false );
89 #define OPENGL_INDEX -1
90 #define XRENDER_INDEX 0
92 #ifndef KWIN_HAVE_XRENDER_COMPOSITING
93 ui
.compositingType
->removeItem( XRENDER_INDEX
);
94 ui
.xrenderGroup
->setEnabled( false );
95 #define XRENDER_INDEX -1
98 connect(ui
.useCompositing
, SIGNAL(toggled(bool)), this, SLOT(compositingEnabled(bool)));
99 connect(ui
.tabWidget
, SIGNAL(currentChanged(int)), this, SLOT(currentTabChanged(int)));
101 connect(ui
.useCompositing
, SIGNAL(toggled(bool)), this, SLOT(changed()));
102 connect(ui
.effectWinManagement
, SIGNAL(toggled(bool)), this, SLOT(changed()));
103 connect(ui
.effectShadows
, SIGNAL(toggled(bool)), this, SLOT(changed()));
104 connect(ui
.effectAnimations
, SIGNAL(toggled(bool)), this, SLOT(changed()));
106 connect(ui
.effectSelector
, SIGNAL(changed(bool)), this, SLOT(changed()));
107 connect(ui
.effectSelector
, SIGNAL(configCommitted(const QByteArray
&)),
108 this, SLOT(reparseConfiguration(const QByteArray
&)));
110 connect(ui
.windowSwitchingCombo
, SIGNAL(currentIndexChanged(int)), this, SLOT(changed()));
111 connect(ui
.desktopSwitchingCombo
, SIGNAL(currentIndexChanged(int)), this, SLOT(changed()));
112 connect(ui
.animationSpeedCombo
, SIGNAL(currentIndexChanged(int)), this, SLOT(changed()));
114 connect(ui
.edges_monitor
, SIGNAL(changed()), this, SLOT(changed()));
115 connect(ui
.edges_monitor
, SIGNAL(edgeSelectionChanged(int,int)), this, SLOT(electricBorderSelectionChanged(int,int)));
117 connect(ui
.compositingType
, SIGNAL(currentIndexChanged(int)), this, SLOT(compositingModeChanged()));
118 connect(ui
.compositingType
, SIGNAL(currentIndexChanged(int)), this, SLOT(changed()));
119 connect(ui
.windowThumbnails
, SIGNAL(activated(int)), this, SLOT(changed()));
120 connect(ui
.disableChecks
, SIGNAL(toggled(bool)), this, SLOT(changed()));
121 connect(ui
.glMode
, SIGNAL(currentIndexChanged(int)), this, SLOT(changed()));
122 connect(ui
.glTextureFilter
, SIGNAL(currentIndexChanged(int)), this, SLOT(changed()));
123 connect(ui
.glDirect
, SIGNAL(toggled(bool)), this, SLOT(changed()));
124 connect(ui
.glVSync
, SIGNAL(toggled(bool)), this, SLOT(changed()));
125 connect(ui
.xrenderSmoothScale
, SIGNAL(toggled(bool)), this, SLOT(changed()));
127 // Open the temporary config file
128 // Temporary conf file is used to synchronize effect checkboxes with effect
129 // selector by loading/saving effects from/to temp config when active tab
131 mTmpConfigFile
.open();
132 mTmpConfig
= KSharedConfig::openConfig(mTmpConfigFile
.fileName());
134 if( CompositingPrefs::compositingPossible() )
136 // Driver-specific config detection
137 mDefaultPrefs
.detect();
138 initEffectSelector();
140 // Initialize the user interface with the config loaded from kwinrc.
145 ui
.useCompositing
->setEnabled(false);
146 ui
.useCompositing
->setChecked(false);
147 compositingEnabled(false);
149 QString text
= i18n("Compositing is not supported on your system.");
151 text
+= CompositingPrefs::compositingNotPossibleReason();
152 ui
.statusTitleWidget
->setText(text
);
153 ui
.statusTitleWidget
->setPixmap(KTitleWidget::InfoMessage
, KTitleWidget::ImageLeft
);
154 ui
.statusTitleWidget
->show();
157 KAboutData
*about
= new KAboutData(I18N_NOOP("kcmkwincompositing"), 0,
158 ki18n("KWin Desktop Effects Configuration Module"),
159 0, KLocalizedString(), KAboutData::License_GPL
, ki18n("(c) 2007 Rivo Laks"));
160 about
->addAuthor(ki18n("Rivo Laks"), KLocalizedString(), "rivolaks@hot.ee");
163 // search the effect names
164 KServiceTypeTrader
* trader
= KServiceTypeTrader::self();
165 KService::List services
;
166 QString boxswitch
, presentwindows
, coverswitch
, flipswitch
, slide
, cube
, fadedesktop
;
168 services
= trader
->query("KWin/Effect", "[X-KDE-PluginInfo-Name] == 'kwin4_effect_boxswitch'");
169 if( !services
.isEmpty() )
170 boxswitch
= services
.first()->name();
171 services
= trader
->query("KWin/Effect", "[X-KDE-PluginInfo-Name] == 'kwin4_effect_presentwindows'");
172 if( !services
.isEmpty() )
173 presentwindows
= services
.first()->name();
174 services
= trader
->query("KWin/Effect", "[X-KDE-PluginInfo-Name] == 'kwin4_effect_coverswitch'");
175 if( !services
.isEmpty() )
176 coverswitch
= services
.first()->name();
177 services
= trader
->query("KWin/Effect", "[X-KDE-PluginInfo-Name] == 'kwin4_effect_flipswitch'");
178 if( !services
.isEmpty() )
179 flipswitch
= services
.first()->name();
181 services
= trader
->query("KWin/Effect", "[X-KDE-PluginInfo-Name] == 'kwin4_effect_slide'");
182 if( !services
.isEmpty() )
183 slide
= services
.first()->name();
184 services
= trader
->query("KWin/Effect", "[X-KDE-PluginInfo-Name] == 'kwin4_effect_cube'");
185 if( !services
.isEmpty() )
186 cube
= services
.first()->name();
187 services
= trader
->query("KWin/Effect", "[X-KDE-PluginInfo-Name] == 'kwin4_effect_fadedesktop'");
188 if( !services
.isEmpty() )
189 fadedesktop
= services
.first()->name();
190 // init the combo boxes
191 ui
.windowSwitchingCombo
->addItem(i18n("No Effect"));
192 ui
.windowSwitchingCombo
->addItem(boxswitch
);
193 ui
.windowSwitchingCombo
->addItem(presentwindows
);
194 ui
.windowSwitchingCombo
->addItem(coverswitch
);
195 ui
.windowSwitchingCombo
->addItem(flipswitch
);
197 ui
.desktopSwitchingCombo
->addItem(i18n("No Effect"));
198 ui
.desktopSwitchingCombo
->addItem(slide
);
199 ui
.desktopSwitchingCombo
->addItem(cube
);
200 ui
.desktopSwitchingCombo
->addItem(fadedesktop
);
203 KWinCompositingConfig::~KWinCompositingConfig()
207 void KWinCompositingConfig::reparseConfiguration( const QByteArray
& conf
)
209 KSettings::Dispatcher::reparseConfiguration( conf
);
212 void KWinCompositingConfig::compositingEnabled( bool enabled
)
214 // Enable the other configuration tabs only when compositing is enabled.
215 ui
.compositingOptionsContainer
->setEnabled(enabled
);
216 ui
.tabWidget
->setTabEnabled(1, enabled
);
217 ui
.tabWidget
->setTabEnabled(2, enabled
);
218 ui
.tabWidget
->setTabEnabled(3, enabled
);
221 void KWinCompositingConfig::showConfirmDialog( bool reinitCompositing
)
224 // Feel free to extend this to support several kwin instances (multihead) if you
225 // think it makes sense.
226 OrgKdeKWinInterface
kwin("org.kde.kwin", "/KWin", QDBusConnection::sessionBus());
227 if( reinitCompositing
? !kwin
.compositingActive().value() : !kwin
.waitForCompositingSetup().value() )
229 KMessageBox::sorry( this, i18n(
230 "Failed to activate desktop effects using the given "
231 "configuration options. Settings will be reverted to their previous values.\n\n"
232 "Check your X configuration. You may also consider changing advanced options, "
233 "especially changing the compositing type." ));
238 ConfirmDialog confirm
;
245 KConfigGroup
config(mKWinConfig
, "Compositing");
246 config
.deleteGroup();
247 QMap
<QString
, QString
>::const_iterator it
= mPreviousConfig
.constBegin();
248 for(; it
!= mPreviousConfig
.constEnd(); ++it
)
250 if (it
.value().isEmpty())
252 config
.writeEntry(it
.key(), it
.value());
254 // Sync with KWin and reload
255 configChanged(reinitCompositing
);
260 void KWinCompositingConfig::initEffectSelector()
262 // Find all .desktop files of the effects
263 KService::List offers
= KServiceTypeTrader::self()->query("KWin/Effect");
264 QList
<KPluginInfo
> effectinfos
= KPluginInfo::fromServices(offers
);
266 // Add them to the plugin selector
267 ui
.effectSelector
->addPlugins(effectinfos
, KPluginSelector::ReadConfigFile
, i18n("Appearance"), "Appearance", mTmpConfig
);
268 ui
.effectSelector
->addPlugins(effectinfos
, KPluginSelector::ReadConfigFile
, i18n("Accessibility"), "Accessibility", mTmpConfig
);
269 ui
.effectSelector
->addPlugins(effectinfos
, KPluginSelector::ReadConfigFile
, i18n("Focus"), "Focus", mTmpConfig
);
270 ui
.effectSelector
->addPlugins(effectinfos
, KPluginSelector::ReadConfigFile
, i18n("Window Management"), "Window Management", mTmpConfig
);
271 ui
.effectSelector
->addPlugins(effectinfos
, KPluginSelector::ReadConfigFile
, i18n("Candy"), "Candy", mTmpConfig
);
272 ui
.effectSelector
->addPlugins(effectinfos
, KPluginSelector::ReadConfigFile
, i18n("Demos"), "Demos", mTmpConfig
);
273 ui
.effectSelector
->addPlugins(effectinfos
, KPluginSelector::ReadConfigFile
, i18n("Tests"), "Tests", mTmpConfig
);
274 ui
.effectSelector
->addPlugins(effectinfos
, KPluginSelector::ReadConfigFile
, i18n("Tools"), "Tools", mTmpConfig
);
277 void KWinCompositingConfig::currentTabChanged(int tab
)
279 // block signals to don't emit the changed()-signal by just switching the current tab
282 // write possible changes done to synchronize effect checkboxes and selector
283 // TODO: This segment is prone to fail when the UI is changed;
284 // you'll most likely not think of the hard coded numbers here when just changing the order of the tabs.
287 // General tab was activated
293 // Effects tab was activated
301 void KWinCompositingConfig::loadGeneralTab()
303 KConfigGroup
config(mKWinConfig
, "Compositing");
304 ui
.useCompositing
->setChecked(config
.readEntry("Enabled", mDefaultPrefs
.enableCompositing()));
305 ui
.animationSpeedCombo
->setCurrentIndex(config
.readEntry("AnimationSpeed", 3 ));
307 // Load effect settings
308 KConfigGroup
effectconfig(mTmpConfig
, "Plugins");
309 #define LOAD_EFFECT_CONFIG(effectname) effectconfig.readEntry("kwin4_effect_" effectname "Enabled", true)
310 int winManagementEnabled
= LOAD_EFFECT_CONFIG("presentwindows")
311 + LOAD_EFFECT_CONFIG("desktopgrid")
312 + LOAD_EFFECT_CONFIG("dialogparent");
313 if (winManagementEnabled
> 0 && winManagementEnabled
< 3)
315 ui
.effectWinManagement
->setTristate(true);
316 ui
.effectWinManagement
->setCheckState(Qt::PartiallyChecked
);
319 ui
.effectWinManagement
->setChecked(winManagementEnabled
);
320 ui
.effectShadows
->setChecked(LOAD_EFFECT_CONFIG("shadow"));
321 ui
.effectAnimations
->setChecked(LOAD_EFFECT_CONFIG("minimizeanimation"));
322 #undef LOAD_EFFECT_CONFIG
325 // Set current option to "none" if no plugin is activated.
326 ui
.windowSwitchingCombo
->setCurrentIndex( 0 );
327 if( effectEnabled( "boxswitch", effectconfig
))
328 ui
.windowSwitchingCombo
->setCurrentIndex( 1 );
329 if( effectEnabled( "coverswitch", effectconfig
))
330 ui
.windowSwitchingCombo
->setCurrentIndex( 3 );
331 if( effectEnabled( "flipswitch", effectconfig
))
332 ui
.windowSwitchingCombo
->setCurrentIndex( 4 );
333 KConfigGroup
presentwindowsconfig(mKWinConfig
, "Effect-PresentWindows");
334 if( effectEnabled( "presentwindows", effectconfig
) && presentwindowsconfig
.readEntry("TabBox", false) )
335 ui
.windowSwitchingCombo
->setCurrentIndex( 2 );
338 // Set current option to "none" if no plugin is activated.
339 ui
.desktopSwitchingCombo
->setCurrentIndex( 0 );
340 if( effectEnabled( "slide", effectconfig
))
341 ui
.desktopSwitchingCombo
->setCurrentIndex( 1 );
342 KConfigGroup
cubeconfig(mKWinConfig
, "Effect-Cube");
343 if( effectEnabled( "cube", effectconfig
) && cubeconfig
.readEntry("AnimateDesktopChange", false))
344 ui
.desktopSwitchingCombo
->setCurrentIndex( 2 );
345 if( effectEnabled( "fadedesktop", effectconfig
))
346 ui
.desktopSwitchingCombo
->setCurrentIndex( 3 );
349 bool KWinCompositingConfig::effectEnabled( const QString
& effect
, const KConfigGroup
& cfg
) const
351 KService::List services
= KServiceTypeTrader::self()->query(
352 "KWin/Effect", "[X-KDE-PluginInfo-Name] == 'kwin4_effect_" + effect
+ "'");
353 if( services
.isEmpty())
355 QVariant v
= services
.first()->property("X-KDE-PluginInfo-EnabledByDefault");
356 return cfg
.readEntry("kwin4_effect_" + effect
+ "Enabled", v
.toBool());
359 void KWinCompositingConfig::loadEffectsTab()
361 ui
.effectSelector
->load();
364 void KWinCompositingConfig::loadAdvancedTab()
366 KConfigGroup
config(mKWinConfig
, "Compositing");
367 QString backend
= config
.readEntry("Backend", "OpenGL");
368 ui
.compositingType
->setCurrentIndex((backend
== "XRender") ? XRENDER_INDEX
: 0);
369 // 4 - off, 5 - shown, 6 - always, other are old values
370 int hps
= config
.readEntry("HiddenPreviews", 5);
371 if( hps
== 6 ) // always
372 ui
.windowThumbnails
->setCurrentIndex( 0 );
373 else if( hps
== 4 ) // never
374 ui
.windowThumbnails
->setCurrentIndex( 2 );
375 else // shown, or default
376 ui
.windowThumbnails
->setCurrentIndex( 1 );
377 ui
.disableChecks
->setChecked( config
.readEntry( "DisableChecks", false ));
379 QString glMode
= config
.readEntry("GLMode", "TFP");
380 ui
.glMode
->setCurrentIndex((glMode
== "TFP") ? 0 : ((glMode
== "SHM") ? 1 : 2));
381 ui
.glTextureFilter
->setCurrentIndex(config
.readEntry("GLTextureFilter", 1));
382 ui
.glDirect
->setChecked(config
.readEntry("GLDirect", mDefaultPrefs
.enableDirectRendering()));
383 ui
.glVSync
->setChecked(config
.readEntry("GLVSync", mDefaultPrefs
.enableVSync()));
385 ui
.xrenderSmoothScale
->setChecked(config
.readEntry("XRenderSmoothScale", false));
388 void KWinCompositingConfig::load()
390 mKWinConfig
->reparseConfiguration();
392 // Copy Plugins group to temp config file
393 QMap
<QString
, QString
> entries
= mKWinConfig
->entryMap("Plugins");
394 QMap
<QString
, QString
>::const_iterator it
= entries
.constBegin();
395 KConfigGroup
tmpconfig(mTmpConfig
, "Plugins");
396 tmpconfig
.deleteGroup();
397 for(; it
!= entries
.constEnd(); ++it
)
398 tmpconfig
.writeEntry(it
.key(), it
.value());
401 loadElectricBorders();
405 emit
changed( false );
408 void KWinCompositingConfig::saveGeneralTab()
410 KConfigGroup
config(mKWinConfig
, "Compositing");
411 // Check if any critical settings that need confirmation have changed
412 if(ui
.useCompositing
->isChecked() &&
413 ui
.useCompositing
->isChecked() != config
.readEntry("Enabled", mDefaultPrefs
.enableCompositing()))
414 m_showConfirmDialog
= true;
416 config
.writeEntry("Enabled", ui
.useCompositing
->isChecked());
417 config
.writeEntry("AnimationSpeed", ui
.animationSpeedCombo
->currentIndex());
420 KConfigGroup
effectconfig(mTmpConfig
, "Plugins");
421 #define WRITE_EFFECT_CONFIG(effectname, widget) effectconfig.writeEntry("kwin4_effect_" effectname "Enabled", widget->isChecked())
422 if (ui
.effectWinManagement
->checkState() != Qt::PartiallyChecked
)
424 WRITE_EFFECT_CONFIG("presentwindows", ui
.effectWinManagement
);
425 WRITE_EFFECT_CONFIG("desktopgrid", ui
.effectWinManagement
);
426 WRITE_EFFECT_CONFIG("dialogparent", ui
.effectWinManagement
);
428 WRITE_EFFECT_CONFIG("shadow", ui
.effectShadows
);
429 // TODO: maybe also do some effect-specific configuration here, e.g.
430 // enable/disable desktopgrid's animation according to this setting
431 WRITE_EFFECT_CONFIG("minimizeanimation", ui
.effectAnimations
);
432 #undef WRITE_EFFECT_CONFIG
434 int windowSwitcher
= ui
.windowSwitchingCombo
->currentIndex();
435 bool presentWindowSwitching
= false;
436 switch( windowSwitcher
)
440 effectconfig
.writeEntry("kwin4_effect_boxswitchEnabled", false);
441 effectconfig
.writeEntry("kwin4_effect_coverswitchEnabled", false);
442 effectconfig
.writeEntry("kwin4_effect_flipswitchEnabled", false);
446 effectconfig
.writeEntry("kwin4_effect_boxswitchEnabled", true);
447 effectconfig
.writeEntry("kwin4_effect_coverswitchEnabled", false);
448 effectconfig
.writeEntry("kwin4_effect_flipswitchEnabled", false);
452 presentWindowSwitching
= true;
453 effectconfig
.writeEntry("kwin4_effect_presentwindowsEnabled", true);
454 effectconfig
.writeEntry("kwin4_effect_boxswitchEnabled", false);
455 effectconfig
.writeEntry("kwin4_effect_coverswitchEnabled", false);
456 effectconfig
.writeEntry("kwin4_effect_flipswitchEnabled", false);
460 effectconfig
.writeEntry("kwin4_effect_boxswitchEnabled", false);
461 effectconfig
.writeEntry("kwin4_effect_coverswitchEnabled", true);
462 effectconfig
.writeEntry("kwin4_effect_flipswitchEnabled", false);
466 effectconfig
.writeEntry("kwin4_effect_boxswitchEnabled", false);
467 effectconfig
.writeEntry("kwin4_effect_coverswitchEnabled", false);
468 effectconfig
.writeEntry("kwin4_effect_flipswitchEnabled", true);
471 KConfigGroup
presentwindowsconfig(mKWinConfig
, "Effect-PresentWindows");
472 presentwindowsconfig
.writeEntry("TabBox", presentWindowSwitching
);
474 int desktopSwitcher
= ui
.desktopSwitchingCombo
->currentIndex();
475 bool cubeDesktopSwitching
= false;
476 switch( desktopSwitcher
)
480 effectconfig
.writeEntry("kwin4_effect_slideEnabled", false);
481 effectconfig
.writeEntry("kwin4_effect_fadedesktopEnabled", false);
485 effectconfig
.writeEntry("kwin4_effect_slideEnabled", true);
486 effectconfig
.writeEntry("kwin4_effect_fadedesktopEnabled", false);
490 cubeDesktopSwitching
= true;
491 effectconfig
.writeEntry("kwin4_effect_slideEnabled", false);
492 effectconfig
.writeEntry("kwin4_effect_cubeEnabled", true);
493 effectconfig
.writeEntry("kwin4_effect_fadedesktopEnabled", false);
497 effectconfig
.writeEntry("kwin4_effect_slideEnabled", false);
498 effectconfig
.writeEntry("kwin4_effect_fadedesktopEnabled", true);
501 KConfigGroup
cubeconfig(mKWinConfig
, "Effect-Cube");
502 cubeconfig
.writeEntry("AnimateDesktopChange", cubeDesktopSwitching
);
505 void KWinCompositingConfig::saveEffectsTab()
507 ui
.effectSelector
->save();
510 bool KWinCompositingConfig::saveAdvancedTab()
512 bool advancedChanged
= false;
513 static const int hps
[] = { 6 /*always*/, 5 /*shown*/, 4 /*never*/ };
515 KConfigGroup
config(mKWinConfig
, "Compositing");
516 QString glModes
[] = { "TFP", "SHM", "Fallback" };
518 if( config
.readEntry("Backend", "OpenGL")
519 != ((ui
.compositingType
->currentIndex() == 0) ? "OpenGL" : "XRender")
520 || config
.readEntry("GLMode", "TFP") != glModes
[ui
.glMode
->currentIndex()]
521 || config
.readEntry("GLDirect", mDefaultPrefs
.enableDirectRendering())
522 != ui
.glDirect
->isChecked()
523 || config
.readEntry("GLVSync", mDefaultPrefs
.enableVSync()) != ui
.glVSync
->isChecked()
524 || config
.readEntry("DisableChecks", false ) != ui
.disableChecks
->isChecked())
526 m_showConfirmDialog
= true;
527 advancedChanged
= true;
529 else if( config
.readEntry("HiddenPreviews", 5) != hps
[ ui
.windowThumbnails
->currentIndex() ]
530 || config
.readEntry("XRenderSmoothScale", false ) != ui
.xrenderSmoothScale
->isChecked() )
531 advancedChanged
= true;
533 config
.writeEntry("Backend", (ui
.compositingType
->currentIndex() == OPENGL_INDEX
) ? "OpenGL" : "XRender");
534 config
.writeEntry("HiddenPreviews", hps
[ ui
.windowThumbnails
->currentIndex() ] );
535 config
.writeEntry("DisableChecks", ui
.disableChecks
->isChecked());
537 config
.writeEntry("GLMode", glModes
[ui
.glMode
->currentIndex()]);
538 config
.writeEntry("GLTextureFilter", ui
.glTextureFilter
->currentIndex());
539 config
.writeEntry("GLDirect", ui
.glDirect
->isChecked());
540 config
.writeEntry("GLVSync", ui
.glVSync
->isChecked());
542 config
.writeEntry("XRenderSmoothScale", ui
.xrenderSmoothScale
->isChecked());
544 return advancedChanged
;
547 void KWinCompositingConfig::save()
549 // Save current config. We'll use this for restoring in case something goes wrong.
550 KConfigGroup
config(mKWinConfig
, "Compositing");
551 mPreviousConfig
= config
.entryMap();
553 // bah; tab content being dependent on the other is really bad; and
554 // deprecated in the HIG for a reason. Its confusing!
555 // Make sure we only call save on each tab once; as they are stateful due to the revert concept
556 if ( ui
.tabWidget
->currentIndex() == 0 ) // "General" tab was active
568 saveElectricBorders();
569 bool advancedChanged
= saveAdvancedTab();
571 // Copy Plugins group from temp config to real config
572 QMap
<QString
, QString
> entries
= mTmpConfig
->entryMap("Plugins");
573 QMap
<QString
, QString
>::const_iterator it
= entries
.constBegin();
574 KConfigGroup
realconfig(mKWinConfig
, "Plugins");
575 realconfig
.deleteGroup();
576 for(; it
!= entries
.constEnd(); ++it
)
577 realconfig
.writeEntry(it
.key(), it
.value());
579 emit
changed( false );
581 configChanged(advancedChanged
);
583 if(m_showConfirmDialog
)
585 m_showConfirmDialog
= false;
586 showConfirmDialog(advancedChanged
);
590 void KWinCompositingConfig::configChanged(bool reinitCompositing
)
592 // Send signal to kwin
594 // Send signal to all kwin instances
595 QDBusMessage message
= QDBusMessage::createSignal("/KWin", "org.kde.KWin",
596 //reinitCompositing ? "reinitCompositing" : "reloadConfig");
597 "reinitCompositing");
598 QDBusConnection::sessionBus().send(message
);
601 // If we added or removed shadows we need to reload decorations as well
602 // We have to do this separately so the settings are in sync
603 // HACK: This should really just reload decorations, not do a full reconfigure
605 // HACK: We send two messages to it's correctly synced. Code that was reverted in r894182 was better
606 message
= QDBusMessage::createSignal("/KWin", "org.kde.KWin",
607 //reinitCompositing ? "reinitCompositing" : "reloadConfig");
609 QDBusConnection::sessionBus().send(message
);
611 KConfigGroup effectConfig
;
613 effectConfig
= KConfigGroup( mTmpConfig
, "Compositing" );
614 bool enabledBefore
= effectConfig
.readEntry( "Enabled", mDefaultPrefs
.enableCompositing() );
615 effectConfig
= KConfigGroup( mKWinConfig
, "Compositing" );
616 bool enabledAfter
= effectConfig
.readEntry( "Enabled", mDefaultPrefs
.enableCompositing() );
618 effectConfig
= KConfigGroup( mTmpConfig
, "Plugins" );
619 bool shadowBefore
= effectEnabled( "shadow", effectConfig
);
620 effectConfig
= KConfigGroup( mKWinConfig
, "Plugins" );
621 bool shadowAfter
= effectEnabled( "shadow", effectConfig
);
623 if( enabledBefore
!= enabledAfter
|| shadowBefore
!= shadowAfter
)
625 message
= QDBusMessage::createMethodCall( "org.kde.kwin", "/KWin", "org.kde.KWin", "reconfigure" );
626 QDBusConnection::sessionBus().send( message
);
631 void KWinCompositingConfig::defaults()
633 ui
.tabWidget
->setCurrentIndex(0);
635 ui
.useCompositing
->setChecked(mDefaultPrefs
.enableCompositing());
636 ui
.effectWinManagement
->setChecked(true);
637 ui
.effectShadows
->setChecked(true);
638 ui
.effectAnimations
->setChecked(true);
640 ui
.windowSwitchingCombo
->setCurrentIndex( 1 );
641 ui
.desktopSwitchingCombo
->setCurrentIndex( 1 );
642 ui
.animationSpeedCombo
->setCurrentIndex( 3 );
644 ui
.effectSelector
->defaults();
646 ui
.compositingType
->setCurrentIndex( 0 );
647 ui
.windowThumbnails
->setCurrentIndex( 1 );
648 ui
.disableChecks
->setChecked( false );
649 ui
.glMode
->setCurrentIndex( 0 );
650 ui
.glTextureFilter
->setCurrentIndex( 1 );
651 ui
.glDirect
->setChecked( mDefaultPrefs
.enableDirectRendering() );
652 ui
.glVSync
->setChecked( mDefaultPrefs
.enableVSync() );
653 ui
.xrenderSmoothScale
->setChecked( false );
655 for( int i
=0; i
<8; i
++ )
657 // set all edges to no effect
658 ui
.edges_monitor
->selectEdgeItem( i
, 0 );
660 // set top left to present windows
661 ui
.edges_monitor
->selectEdgeItem( (int)Monitor::TopLeft
, (int)PresentWindowsAll
);
664 QString
KWinCompositingConfig::quickHelp() const
666 return i18n("<h1>Desktop Effects</h1>");
669 void KWinCompositingConfig::setupElectricBorders()
671 addItemToEdgesMonitor( i18n("No Effect"));
673 // search the effect names
674 KServiceTypeTrader
* trader
= KServiceTypeTrader::self();
675 KService::List services
;
676 services
= trader
->query("KWin/Effect", "[X-KDE-PluginInfo-Name] == 'kwin4_effect_presentwindows'");
677 if( !services
.isEmpty() )
679 addItemToEdgesMonitor( services
.first()->name() + " - " + i18n( "All Desktops" ));
680 addItemToEdgesMonitor( services
.first()->name() + " - " + i18n( "Current Desktop" ));
682 services
= trader
->query("KWin/Effect", "[X-KDE-PluginInfo-Name] == 'kwin4_effect_desktopgrid'");
683 if( !services
.isEmpty() )
684 addItemToEdgesMonitor( services
.first()->name());
685 services
= trader
->query("KWin/Effect", "[X-KDE-PluginInfo-Name] == 'kwin4_effect_cube'");
686 if( !services
.isEmpty() )
687 addItemToEdgesMonitor( services
.first()->name());
688 services
= trader
->query("KWin/Effect", "[X-KDE-PluginInfo-Name] == 'kwin4_effect_cylinder'");
689 if( !services
.isEmpty() )
690 addItemToEdgesMonitor( services
.first()->name());
691 services
= trader
->query("KWin/Effect", "[X-KDE-PluginInfo-Name] == 'kwin4_effect_sphere'");
692 if( !services
.isEmpty() )
693 addItemToEdgesMonitor( services
.first()->name());
696 void KWinCompositingConfig::addItemToEdgesMonitor(const QString
& item
)
698 for( int i
=0; i
<8; i
++ )
699 ui
.edges_monitor
->addEdgeItem( i
, item
);
702 void KWinCompositingConfig::electricBorderSelectionChanged(int edge
, int index
)
704 if( index
== (int)NoEffect
)
706 for( int i
=0; i
<8; i
++)
710 if( ui
.edges_monitor
->selectedEdgeItem( i
) == index
)
711 ui
.edges_monitor
->selectEdgeItem( i
, (int)NoEffect
);
716 void KWinCompositingConfig::loadElectricBorders()
719 KConfigGroup
presentwindowsconfig(mKWinConfig
, "Effect-PresentWindows");
720 changeElectricBorder( (ElectricBorder
)presentwindowsconfig
.readEntry( "BorderActivateAll",
721 int( ElectricTopLeft
)), (int)PresentWindowsAll
);
722 changeElectricBorder( (ElectricBorder
)presentwindowsconfig
.readEntry( "BorderActivate",
723 int( ElectricNone
)), (int)PresentWindowsCurrent
);
725 KConfigGroup
gridconfig(mKWinConfig
, "Effect-DesktopGrid");
726 changeElectricBorder( (ElectricBorder
)gridconfig
.readEntry( "BorderActivate",
727 int( ElectricNone
)), (int)DesktopGrid
);
729 KConfigGroup
cubeconfig(mKWinConfig
, "Effect-Cube");
730 changeElectricBorder( (ElectricBorder
)cubeconfig
.readEntry( "BorderActivate",
731 int( ElectricNone
)), (int)Cube
);
733 KConfigGroup
cylinderconfig(mKWinConfig
, "Effect-Cylinder");
734 changeElectricBorder( (ElectricBorder
)cylinderconfig
.readEntry( "BorderActivate",
735 int( ElectricNone
)), (int)Cylinder
);
737 KConfigGroup
sphereconfig(mKWinConfig
, "Effect-Sphere");
738 changeElectricBorder( (ElectricBorder
)sphereconfig
.readEntry( "BorderActivate",
739 int( ElectricNone
)), (int)Sphere
);
742 void KWinCompositingConfig::changeElectricBorder( ElectricBorder border
, int index
)
747 ui
.edges_monitor
->selectEdgeItem( (int)Monitor::Top
, index
);
749 case ElectricTopRight
:
750 ui
.edges_monitor
->selectEdgeItem( (int)Monitor::TopRight
, index
);
753 ui
.edges_monitor
->selectEdgeItem( (int)Monitor::Right
, index
);
755 case ElectricBottomRight
:
756 ui
.edges_monitor
->selectEdgeItem( (int)Monitor::BottomRight
, index
);
759 ui
.edges_monitor
->selectEdgeItem( (int)Monitor::Bottom
, index
);
761 case ElectricBottomLeft
:
762 ui
.edges_monitor
->selectEdgeItem( (int)Monitor::BottomLeft
, index
);
765 ui
.edges_monitor
->selectEdgeItem( (int)Monitor::Left
, index
);
767 case ElectricTopLeft
:
768 ui
.edges_monitor
->selectEdgeItem( (int)Monitor::TopLeft
, index
);
776 ElectricBorder
KWinCompositingConfig::checkEffectHasElectricBorder( int index
)
778 if( ui
.edges_monitor
->selectedEdgeItem( (int)Monitor::Top
) == index
)
780 if( ui
.edges_monitor
->selectedEdgeItem( (int)Monitor::TopRight
) == index
)
781 return ElectricTopRight
;
782 if( ui
.edges_monitor
->selectedEdgeItem( (int)Monitor::Right
) == index
)
783 return ElectricRight
;
784 if( ui
.edges_monitor
->selectedEdgeItem( (int)Monitor::BottomRight
) == index
)
785 return ElectricBottomRight
;
786 if( ui
.edges_monitor
->selectedEdgeItem( (int)Monitor::Bottom
) == index
)
787 return ElectricBottom
;
788 if( ui
.edges_monitor
->selectedEdgeItem( (int)Monitor::BottomLeft
) == index
)
789 return ElectricBottomLeft
;
790 if( ui
.edges_monitor
->selectedEdgeItem( (int)Monitor::Left
) == index
)
792 if( ui
.edges_monitor
->selectedEdgeItem( (int)Monitor::TopLeft
) == index
)
793 return ElectricTopLeft
;
797 void KWinCompositingConfig::saveElectricBorders()
799 KConfigGroup
presentwindowsconfig(mKWinConfig
, "Effect-PresentWindows");
800 presentwindowsconfig
.writeEntry( "BorderActivateAll", (int)checkEffectHasElectricBorder( (int)PresentWindowsAll
));
801 presentwindowsconfig
.writeEntry( "BorderActivate", (int)checkEffectHasElectricBorder( (int)PresentWindowsCurrent
));
803 KConfigGroup
gridconfig(mKWinConfig
, "Effect-DesktopGrid");
804 gridconfig
.writeEntry( "BorderActivate", (int)checkEffectHasElectricBorder( (int)DesktopGrid
));
806 KConfigGroup
cubeconfig(mKWinConfig
, "Effect-Cube");
807 cubeconfig
.writeEntry( "BorderActivate", (int)checkEffectHasElectricBorder( (int)Cube
));
809 KConfigGroup
cylinderconfig(mKWinConfig
, "Effect-Cylinder");
810 cylinderconfig
.writeEntry( "BorderActivate", (int)checkEffectHasElectricBorder( (int)Cylinder
));
812 KConfigGroup
sphereconfig(mKWinConfig
, "Effect-Sphere");
813 sphereconfig
.writeEntry( "BorderActivate", (int)checkEffectHasElectricBorder( (int)Sphere
));