kwindowsystem/compositingchanged.patch

119 lines
4.6 KiB
Diff

Subject: [xcb] Ensure the compositingChanged signal is emitted if NETEventFilter is recreated
Author: Martin Gräßlin <mgraesslin@kde.org>
The Xcb implementation of KWindowSystem has two operations modes and when
switching between the two it recreates the NETEventFilter.
This could result in the compositingChanged signal never to be emitted if:
1) NETEventFilter gets created before compositor is started
2) NETEventFilter gets recreated after compositor is started but before
the old filter had a chance to process the XFixes event
This was the cause for e.g. plasmashell not properly detecting that a
Compositor is running on X11.
This change ensures that the signal is emitted if the compositing state
differs after the recreation. Also a test case is added which simulates
the condition.
BUG: 362531
---
autotests/CMakeLists.txt | 1
autotests/compositingenabled_test.cpp | 53 ++++++++++++++++++++++++++++++++++
src/platforms/xcb/kwindowsystem.cpp | 4 ++
3 files changed, 58 insertions(+)
Index: kwindowsystem-5.24.0/autotests/CMakeLists.txt
===================================================================
--- kwindowsystem-5.24.0.orig/autotests/CMakeLists.txt
+++ kwindowsystem-5.24.0/autotests/CMakeLists.txt
@@ -48,6 +48,7 @@ if(X11_FOUND)
netrootinfotestwm
netwininfotestclient
netwininfotestwm
+ compositingenabled_test
)
kwindowsystem_executable_tests(
Index: kwindowsystem-5.24.0/autotests/compositingenabled_test.cpp
===================================================================
--- /dev/null
+++ kwindowsystem-5.24.0/autotests/compositingenabled_test.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2016 Martin Gräßlin <mgraesslin@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <KWindowSystem>
+#include <kmanagerselection.h>
+#include <QtTest/QtTest>
+
+class CompositingEnabledTest : public QObject
+{
+ Q_OBJECT
+private Q_SLOTS:
+ void testRecreatingNetEventFilter();
+};
+
+void CompositingEnabledTest::testRecreatingNetEventFilter()
+{
+ // this test simulates the condition that the compositor gets enabled while the NetEventFilter gets recreated
+ QVERIFY(!KWindowSystem::compositingActive());
+
+ // fake the compositor
+ QSignalSpy compositingChangedSpy(KWindowSystem::self(), &KWindowSystem::compositingChanged);
+ QVERIFY(compositingChangedSpy.isValid());
+ KSelectionOwner compositorSelection("_NET_WM_CM_S0");
+ QSignalSpy claimedSpy(&compositorSelection, &KSelectionOwner::claimedOwnership);
+ QVERIFY(claimedSpy.isValid());
+ compositorSelection.claim(true);
+ connect(&compositorSelection, &KSelectionOwner::claimedOwnership,
+ [] {
+ // let's connect to a signal which will cause a re-creation of NetEventFilter
+ QSignalSpy workAreaChangedSpy(KWindowSystem::self(), &KWindowSystem::workAreaChanged);
+ QVERIFY(workAreaChangedSpy.isValid());
+ }
+ );
+
+ QTRY_VERIFY(KWindowSystem::compositingActive());
+ QCOMPARE(compositingChangedSpy.count(), 1);
+}
+
+QTEST_MAIN(CompositingEnabledTest)
+#include "compositingenabled_test.moc"
Index: kwindowsystem-5.24.0/src/platforms/xcb/kwindowsystem.cpp
===================================================================
--- kwindowsystem-5.24.0.orig/src/platforms/xcb/kwindowsystem.cpp
+++ kwindowsystem-5.24.0/src/platforms/xcb/kwindowsystem.cpp
@@ -482,6 +482,7 @@ void KWindowSystemPrivateX11::init(Filte
}
if (!s_d || s_d->what < what) {
+ const bool wasCompositing = s_d ? s_d->compositingEnabled : false;
MainThreadInstantiator instantiator(what);
NETEventFilter *filter;
if (instantiator.thread() == QCoreApplication::instance()->thread()) {
@@ -498,6 +499,9 @@ void KWindowSystemPrivateX11::init(Filte
}
d.reset(filter);
d->activate();
+ if (wasCompositing != s_d_func()->compositingEnabled) {
+ emit KWindowSystem::self()->compositingChanged(s_d_func()->compositingEnabled);
+ }
}
}