@@ -52,8 +54,21 @@ bool CompositingPrefs::recommendCompositing() const
return mRecommendCompositing;
}
+bool CompositingPrefs::openGlIsBroken()
+{
+ KSharedConfigPtr config = KSharedConfig::openConfig("kwinrc");
+ return KConfigGroup(config, "Compositing").readEntry("OpenGLIsUnsafe", false);
+}
+
bool CompositingPrefs::compositingPossible()
{
+ // first off, check whether we figured that we'll crash on detection because of a buggy driver
+ KSharedConfigPtr config = KSharedConfig::openConfig("kwinrc");
+ KConfigGroup gl_workaround_group(config, "Compositing");
+ if (gl_workaround_group.readEntry("Backend", "OpenGL") == "OpenGL" &&
+ gl_workaround_group.readEntry("OpenGLIsUnsafe", false))
+ return false;
+
#ifdef KWIN_HAVE_COMPOSITING
Extensions::init();
if (!Extensions::compositeAvailable()) {
@@ -85,6 +100,17 @@ bool CompositingPrefs::compositingPossible()
QString CompositingPrefs::compositingNotPossibleReason()
{
#ifdef KWIN_HAVE_COMPOSITING
+ // first off, check whether we figured that we'll crash on detection because of a buggy driver
+ KSharedConfigPtr config = KSharedConfig::openConfig("kwinrc");
+ KConfigGroup gl_workaround_group(config, "Compositing");
+ if (gl_workaround_group.readEntry("Backend", "OpenGL") == "OpenGL" &&
+ gl_workaround_group.readEntry("OpenGLIsUnsafe", false))
+ return i18n("OpenGL compositing (the default) has crashed KWin in the past.
"
+ "This was most likely due to a driver bug."
+ "If you think that you have meanwhile upgraded to a stable driver,
"
+ "you can reset this protection but be aware that this might result in an immediate crash!
"
+ "Alternatively, you might want to use the XRender backend instead.
");
+
Extensions::init();
if (!Extensions::compositeAvailable() || !Extensions::damageAvailable()) {
return i18n("Required X extensions (XComposite and XDamage) are not available.");
@@ -111,10 +137,19 @@ QString CompositingPrefs::compositingNotPossibleReason()
void CompositingPrefs::detect()
{
- if (!compositingPossible()) {
+ if (!compositingPossible() || openGlIsBroken()) {
return;
}
+ // NOTICE: this is intended to workaround broken GL implementations that successfully segfault
+ // on glXQuery :-(
+ // we tag GL as unsafe. It *must* be reset before every return, and in case we "unexpectedly"
+ // end (aka "segfaulted") we know that we shall not try again
+ KSharedConfigPtr config = KSharedConfig::openConfig("kwinrc");
+ KConfigGroup gl_workaround_config = KConfigGroup(config, "Compositing");
+ gl_workaround_config.writeEntry("OpenGLIsUnsafe", true);
+ gl_workaround_config.sync();
+
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
#ifdef KWIN_HAVE_OPENGLES
bool haveContext = false;
@@ -153,6 +188,8 @@ void CompositingPrefs::detect()
}
if (!Extensions::glxAvailable()) {
kDebug(1212) << "No GLX available";
+ gl_workaround_config.writeEntry("OpenGLIsUnsafe", false);
+ gl_workaround_config.sync();
return;
}
int glxmajor, glxminor;
@@ -177,6 +214,8 @@ void CompositingPrefs::detect()
glXMakeCurrent(display(), olddrawable, oldcontext);
deleteGLXContext();
#endif
+ gl_workaround_config.writeEntry("OpenGLIsUnsafe", false);
+ gl_workaround_config.sync();
#endif
}
diff --git a/compositingprefs.h b/compositingprefs.h
index 89c97a7d5f..4cfc0095ef 100644
--- a/compositingprefs.h
+++ b/compositingprefs.h
@@ -39,6 +39,7 @@ public:
static bool compositingPossible();
static QString compositingNotPossibleReason();
+ static bool openGlIsBroken();
bool recommendCompositing() const;
bool enableVSync() const {
return mEnableVSync;
diff --git a/kcmkwin/kwincompositing/main.cpp b/kcmkwin/kwincompositing/main.cpp
index 8b447253c6..a2bba83ad8 100644
--- a/kcmkwin/kwincompositing/main.cpp
+++ b/kcmkwin/kwincompositing/main.cpp
@@ -82,6 +82,7 @@ KWinCompositingConfig::KWinCompositingConfig(QWidget *parent, const QVariantList
layout()->setMargin(0);
ui.tabWidget->setCurrentIndex(0);
ui.statusTitleWidget->hide();
+ ui.rearmGlSupport->hide();
// For future use
(void) I18N_NOOP("Use GLSL shaders");
@@ -102,6 +103,7 @@ KWinCompositingConfig::KWinCompositingConfig(QWidget *parent, const QVariantList
connect(ui.tabWidget, SIGNAL(currentChanged(int)), this, SLOT(currentTabChanged(int)));
+ connect(ui.rearmGlSupportButton, SIGNAL(clicked()), this, SLOT(rearmGlSupport()));
connect(ui.useCompositing, SIGNAL(toggled(bool)), this, SLOT(changed()));
connect(ui.effectWinManagement, SIGNAL(toggled(bool)), this, SLOT(changed()));
connect(ui.effectAnimations, SIGNAL(toggled(bool)), this, SLOT(changed()));
@@ -143,34 +145,8 @@ KWinCompositingConfig::KWinCompositingConfig(QWidget *parent, const QVariantList
a->setGlobalShortcut( KShortcut( Qt::ALT + Qt::SHIFT + Qt::Key_F12 ));
connect(ui.toggleEffectsShortcut, SIGNAL(keySequenceChanged(const QKeySequence&)), this, SLOT(toggleEffectShortcutChanged(const QKeySequence&)));
- // NOTICE: this is intended to workaround broken GL implementations that successfully segfault on glXQuery :-(
- KConfigGroup unsafeConfig(mKWinConfig, "Compositing");
- const bool glUnsafe = unsafeConfig.readEntry("OpenGLIsUnsafe", false);
- if (!glUnsafe && CompositingPrefs::compositingPossible()) {
- unsafeConfig.writeEntry("OpenGLIsUnsafe", true);
- unsafeConfig.sync();
-
- // Driver-specific config detection
- mDefaultPrefs.detect();
- initEffectSelector();
- // Initialize the user interface with the config loaded from kwinrc.
- load();
-
- unsafeConfig.writeEntry("OpenGLIsUnsafe", false);
- unsafeConfig.sync();
- } else {
- // TODO: Add a "force recheck" button that removes the "OpenGLInUnsafe" flag
-
- ui.useCompositing->setEnabled(false);
- ui.useCompositing->setChecked(false);
-
- QString text = i18n("Desktop effects are not available on this system due to the following technical issues:");
- text += "
";
- text += CompositingPrefs::compositingNotPossibleReason();
- ui.statusTitleWidget->setText(text);
- ui.statusTitleWidget->setPixmap(KTitleWidget::InfoMessage, KTitleWidget::ImageLeft);
- ui.statusTitleWidget->show();
- }
+ // Initialize the user interface with the config loaded from kwinrc.
+ load();
KAboutData *about = new KAboutData(I18N_NOOP("kcmkwincompositing"), 0,
ki18n("KWin Desktop Effects Configuration Module"),
@@ -357,12 +333,27 @@ void KWinCompositingConfig::loadGeneralTab()
ui.desktopSwitchingCombo->setCurrentIndex(3);
}
+void KWinCompositingConfig::rearmGlSupport()
+{
+ // rearm config
+ KConfigGroup gl_workaround_config = KConfigGroup(mKWinConfig, "Compositing");
+ gl_workaround_config.writeEntry("OpenGLIsUnsafe", false);
+ gl_workaround_config.sync();
+
+ // save last changes
+ save();
+
+ // Initialize the user interface with the config loaded from kwinrc.
+ load();
+}
+
void KWinCompositingConfig::toogleSmoothScaleUi(int compositingType)
{
ui.glScaleFilter->setVisible(compositingType == OPENGL_INDEX);
ui.xrScaleFilter->setVisible(compositingType == XRENDER_INDEX);
ui.scaleMethodLabel->setBuddy(compositingType == XRENDER_INDEX ? ui.xrScaleFilter : ui.glScaleFilter);
+ ui.glGroup->setEnabled(compositingType == OPENGL_INDEX);
}
void KWinCompositingConfig::toggleEffectShortcutChanged(const QKeySequence &seq)
@@ -413,9 +404,33 @@ void KWinCompositingConfig::loadAdvancedTab()
toogleSmoothScaleUi(ui.compositingType->currentIndex());
}
+void KWinCompositingConfig::updateStatusUI(bool compositingIsPossible)
+{
+ if (compositingIsPossible) {
+ ui.compositingOptionsContainer->show();
+ ui.statusTitleWidget->hide();
+ ui.rearmGlSupport->hide();
+
+ // Driver-specific config detection
+ mDefaultPrefs.detect();
+ }
+ else {
+ ui.compositingOptionsContainer->hide();
+ QString text = i18n("Desktop effects are not available on this system due to the following technical issues:");
+ text += "
";
+ text += CompositingPrefs::compositingNotPossibleReason();
+ ui.statusTitleWidget->setText(text);
+ ui.statusTitleWidget->setPixmap(KTitleWidget::InfoMessage, KTitleWidget::ImageLeft);
+ ui.statusTitleWidget->show();
+ ui.rearmGlSupport->setVisible(CompositingPrefs::openGlIsBroken());
+ }
+}
+
void KWinCompositingConfig::load()
{
+ initEffectSelector();
mKWinConfig->reparseConfiguration();
+ updateStatusUI(CompositingPrefs::compositingPossible());
// Copy Plugins group to temp config file
QMap entries = mKWinConfig->entryMap("Plugins");
@@ -537,7 +552,7 @@ bool KWinCompositingConfig::saveAdvancedTab()
KConfigGroup config(mKWinConfig, "Compositing");
if (config.readEntry("Backend", "OpenGL")
- != ((ui.compositingType->currentIndex() == 0) ? "OpenGL" : "XRender")
+ != ((ui.compositingType->currentIndex() == OPENGL_INDEX) ? "OpenGL" : "XRender")
|| config.readEntry("GLDirect", mDefaultPrefs.enableDirectRendering())
!= ui.glDirect->isChecked()
|| config.readEntry("GLVSync", mDefaultPrefs.enableVSync()) != ui.glVSync->isChecked()
@@ -568,6 +583,20 @@ bool KWinCompositingConfig::saveAdvancedTab()
void KWinCompositingConfig::save()
{
+ if (ui.compositingType->currentIndex() == OPENGL_INDEX &&
+ CompositingPrefs::openGlIsBroken() && !ui.rearmGlSupport->isVisible())
+ {
+ KConfigGroup config(mKWinConfig, "Compositing");
+ QString oldBackend = config.readEntry("Backend", "OpenGL");
+ config.writeEntry("Backend", "OpenGL");
+ config.sync();
+ updateStatusUI(false);
+ config.writeEntry("Backend", oldBackend);
+ config.sync();
+ ui.tabWidget->setCurrentIndex(0);
+ return;
+ }
+
// Save current config. We'll use this for restoring in case something goes wrong.
KConfigGroup config(mKWinConfig, "Compositing");
mPreviousConfig = config.entryMap();
@@ -659,11 +688,16 @@ 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);
+ // maybe it's ok now?
+ if (reinitCompositing && !ui.compositingOptionsContainer->isVisible())
+ load();
+
// HACK: We can't just do this here, due to the asynchronous nature of signals.
// We also can't change reinitCompositing into a message (which would allow
// callWithCallbac() to do this neater) due to multiple kwin instances.
diff --git a/kcmkwin/kwincompositing/main.h b/kcmkwin/kwincompositing/main.h
index 84742b701f..d9937759cc 100644
--- a/kcmkwin/kwincompositing/main.h
+++ b/kcmkwin/kwincompositing/main.h
@@ -76,11 +76,13 @@ public slots:
void initEffectSelector();
private slots:
+ void rearmGlSupport();
void toogleSmoothScaleUi(int compositingType);
void toggleEffectShortcutChanged(const QKeySequence &seq);
private:
bool effectEnabled(const QString& effect, const KConfigGroup& cfg) const;
+ void updateStatusUI(bool compositingIsPossible);
KSharedConfigPtr mKWinConfig;
Ui::KWinCompositingConfig ui;
diff --git a/kcmkwin/kwincompositing/main.ui b/kcmkwin/kwincompositing/main.ui
index 2e4218f76b..a96896062d 100644
--- a/kcmkwin/kwincompositing/main.ui
+++ b/kcmkwin/kwincompositing/main.ui
@@ -6,8 +6,8 @@
0
0
- 560
- 472
+ 544
+ 523
@@ -20,9 +20,117 @@
General
-
+
-
-
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+
-
+
+
+
+ 75
+ true
+
+
+
+ Pressing this button can crash the desktop.
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 125
+ 71
+
+
+
+
+ -
+
+
+ I have saved my data.
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 125
+ 71
+
+
+
+
+ -
+
+
+ false
+
+
+ Re-enable OpenGL detection
+
+
+
+
+
-
@@ -376,6 +484,9 @@
0
+
+ Qt::WheelFocus
+
@@ -384,8 +495,24 @@
Advanced
-
- -
+
+
-
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 8
+
+
+
+
+ -
-
@@ -435,8 +562,27 @@
- -
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 0
+ 0
+
+
General Options
@@ -591,8 +737,40 @@ p, li { white-space: pre-wrap; }
- -
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 0
+ 0
+
+
OpenGL Options
@@ -634,7 +812,7 @@ On legacy hardware disabling Shaders can improve the performance.
- -
+
-
Qt::Vertical
@@ -647,6 +825,32 @@ On legacy hardware disabling Shaders can improve the performance.
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
@@ -686,5 +890,22 @@ On legacy hardware disabling Shaders can improve the performance.
animationSpeedCombo
-
+
+
+ rearmSafetyCheck
+ toggled(bool)
+ rearmGlSupportButton
+ setEnabled(bool)
+
+
+ 161
+ 64
+
+
+ 194
+ 119
+
+
+
+
diff --git a/kcmkwin/kwinscreenedges/main.cpp b/kcmkwin/kwinscreenedges/main.cpp
index 1cbbef1cf8..1819459a9b 100644
--- a/kcmkwin/kwinscreenedges/main.cpp
+++ b/kcmkwin/kwinscreenedges/main.cpp
@@ -64,16 +64,7 @@ KWinScreenEdgesConfig::KWinScreenEdgesConfig(QWidget* parent, const QVariantList
connect(m_ui->quickMaximizeBox, SIGNAL(stateChanged(int)), this, SLOT(groupChanged()));
connect(m_ui->quickTileBox, SIGNAL(stateChanged(int)), this, SLOT(groupChanged()));
- // NOTICE: this is intended to workaround broken GL implementations that successfully segfault on glXQuery :-(
- KConfigGroup gl_workaround_config(m_config, "Compositing");
- const bool checkIsSafe = gl_workaround_config.readEntry("CheckIsSafe", true);
- if (checkIsSafe && CompositingPrefs::compositingPossible()) {
- gl_workaround_config.writeEntry("CheckIsSafe", false);
- gl_workaround_config.sync();
- m_defaultPrefs.detect(); // Driver-specific config detection
- gl_workaround_config.writeEntry("CheckIsSafe", true);
- gl_workaround_config.sync();
- }
+ m_defaultPrefs.detect(); // Driver-specific config detection
load();
}