[autotest] Welcome to integration testing KWin
This is the beginning of a new testing era for KWin: finally we are able to test against a running KWin. This works by making use of the new virtual framebuffer backend for Wayland. It starts a specific Application subclass which is mostly a fork of ApplicationWayland. The individual tests are able to influence the socket name and the size of the virtual screen. This is supposed to be done in initTestCase. To know when KWin is fully started one can use the workspaceCreated signal of KWin::Application. KWin is not started in another process, but the kwin library is used, so the test has pretty much full introspection to everything going on inside KWin. It can access the Workspace, WaylandServer, fake input events through InputRedirection and so on. Once the test KWin is running it's possible to connect to it using KWayland::Client library. This allows to introspect the Workspace to see whether all worked as expected (e.g. correct stacking order, active window and so on). This first autotest is mostly meant to illustrate how to setup a test and how one can use KWayland::Client to interact with the mock KWin. For more tests it is suggested to move the connections to the Wayland server in the init() and cleanup() methods. The change also affects the qpa plugin: the specific check to only run in binaries called kwin_wayland doesn't hold any more. This can now be overwritten by an env variable. Please note that this first test will probably fail in the CI system as it might not have XWayland which is needed by KWin.
This commit is contained in:
parent
4b74b294ab
commit
7fed20f136
6 changed files with 503 additions and 1 deletions
|
@ -1,4 +1,5 @@
|
|||
add_definitions(-DKWIN_UNIT_TEST)
|
||||
add_subdirectory(wayland)
|
||||
|
||||
########################################################
|
||||
# Test ScreenPaintData
|
||||
|
|
10
autotests/wayland/CMakeLists.txt
Normal file
10
autotests/wayland/CMakeLists.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
add_definitions(-DKWINBACKENDPATH="${CMAKE_BINARY_DIR}/backends/virtual/KWinWaylandVirtualBackend.so")
|
||||
add_definitions(-DKWINQPAPATH="${CMAKE_BINARY_DIR}/plugins/qpa/")
|
||||
########################################################
|
||||
# Test Start
|
||||
########################################################
|
||||
set( testStart_SRCS start_test.cpp kwin_wayland_test.cpp )
|
||||
add_executable(testStart ${testStart_SRCS})
|
||||
target_link_libraries( testStart kwin Qt5::Test)
|
||||
add_test(kwin-testStart testStart)
|
||||
ecm_mark_as_test(testStart)
|
260
autotests/wayland/kwin_wayland_test.cpp
Normal file
260
autotests/wayland/kwin_wayland_test.cpp
Normal file
|
@ -0,0 +1,260 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2015 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
#include "kwin_wayland_test.h"
|
||||
#include "../../abstract_backend.h"
|
||||
#include "../../wayland_server.h"
|
||||
#include "../../workspace.h"
|
||||
#include "../../xcbutils.h"
|
||||
|
||||
#include <QAbstractEventDispatcher>
|
||||
#include <QPluginLoader>
|
||||
#include <QSocketNotifier>
|
||||
#include <QThread>
|
||||
#include <QtConcurrentRun>
|
||||
|
||||
// system
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <iostream>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
static void readDisplay(int pipe);
|
||||
|
||||
WaylandTestApplication::WaylandTestApplication(int &argc, char **argv)
|
||||
: Application(OperationModeXwayland, argc, argv)
|
||||
{
|
||||
WaylandServer *server = WaylandServer::create(this);
|
||||
QPluginLoader loader(QStringLiteral(KWINBACKENDPATH));
|
||||
loader.instance()->setParent(server);
|
||||
}
|
||||
|
||||
WaylandTestApplication::~WaylandTestApplication()
|
||||
{
|
||||
destroyCompositor();
|
||||
destroyWorkspace();
|
||||
if (x11Connection()) {
|
||||
Xcb::setInputFocus(XCB_INPUT_FOCUS_POINTER_ROOT);
|
||||
destroyAtoms();
|
||||
xcb_disconnect(x11Connection());
|
||||
}
|
||||
if (m_xwaylandProcess) {
|
||||
m_xwaylandProcess->terminate();
|
||||
m_xwaylandProcess->waitForFinished();
|
||||
}
|
||||
}
|
||||
|
||||
void WaylandTestApplication::performStartup()
|
||||
{
|
||||
// first load options - done internally by a different thread
|
||||
createOptions();
|
||||
waylandServer()->createInternalConnection();
|
||||
|
||||
// try creating the Wayland Backend
|
||||
createInput();
|
||||
createBackend();
|
||||
}
|
||||
|
||||
void WaylandTestApplication::createBackend()
|
||||
{
|
||||
AbstractBackend *backend = waylandServer()->backend();
|
||||
connect(backend, &AbstractBackend::screensQueried, this, &WaylandTestApplication::continueStartupWithScreens);
|
||||
connect(backend, &AbstractBackend::initFailed, this,
|
||||
[] () {
|
||||
std::cerr << "FATAL ERROR: backend failed to initialize, exiting now" << std::endl;
|
||||
::exit(1);
|
||||
}
|
||||
);
|
||||
backend->init();
|
||||
}
|
||||
|
||||
void WaylandTestApplication::continueStartupWithScreens()
|
||||
{
|
||||
disconnect(waylandServer()->backend(), &AbstractBackend::screensQueried, this, &WaylandTestApplication::continueStartupWithScreens);
|
||||
createScreens();
|
||||
waylandServer()->initOutputs();
|
||||
|
||||
createCompositor();
|
||||
|
||||
startXwaylandServer();
|
||||
}
|
||||
|
||||
void WaylandTestApplication::continueStartupWithX()
|
||||
{
|
||||
createX11Connection();
|
||||
xcb_connection_t *c = x11Connection();
|
||||
if (!c) {
|
||||
// about to quit
|
||||
return;
|
||||
}
|
||||
QSocketNotifier *notifier = new QSocketNotifier(xcb_get_file_descriptor(c), QSocketNotifier::Read, this);
|
||||
auto processXcbEvents = [this, c] {
|
||||
while (auto event = xcb_poll_for_event(c)) {
|
||||
updateX11Time(event);
|
||||
long result = 0;
|
||||
if (QThread::currentThread()->eventDispatcher()->filterNativeEvent(QByteArrayLiteral("xcb_generic_event_t"), event, &result)) {
|
||||
free(event);
|
||||
continue;
|
||||
}
|
||||
if (Workspace::self()) {
|
||||
Workspace::self()->workspaceEvent(event);
|
||||
}
|
||||
free(event);
|
||||
}
|
||||
xcb_flush(c);
|
||||
};
|
||||
connect(notifier, &QSocketNotifier::activated, this, processXcbEvents);
|
||||
connect(QThread::currentThread()->eventDispatcher(), &QAbstractEventDispatcher::aboutToBlock, this, processXcbEvents);
|
||||
connect(QThread::currentThread()->eventDispatcher(), &QAbstractEventDispatcher::awake, this, processXcbEvents);
|
||||
|
||||
// create selection owner for WM_S0 - magic X display number expected by XWayland
|
||||
KSelectionOwner owner("WM_S0", c, x11RootWindow());
|
||||
owner.claim(true);
|
||||
|
||||
createAtoms();
|
||||
|
||||
setupEventFilters();
|
||||
|
||||
// Check whether another windowmanager is running
|
||||
const uint32_t maskValues[] = {XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT};
|
||||
ScopedCPointer<xcb_generic_error_t> redirectCheck(xcb_request_check(connection(),
|
||||
xcb_change_window_attributes_checked(connection(),
|
||||
rootWindow(),
|
||||
XCB_CW_EVENT_MASK,
|
||||
maskValues)));
|
||||
if (!redirectCheck.isNull()) {
|
||||
::exit(1);
|
||||
}
|
||||
|
||||
createWorkspace();
|
||||
|
||||
Xcb::sync(); // Trigger possible errors, there's still a chance to abort
|
||||
}
|
||||
|
||||
void WaylandTestApplication::createX11Connection()
|
||||
{
|
||||
int screenNumber = 0;
|
||||
xcb_connection_t *c = nullptr;
|
||||
if (m_xcbConnectionFd == -1) {
|
||||
c = xcb_connect(nullptr, &screenNumber);
|
||||
} else {
|
||||
c = xcb_connect_to_fd(m_xcbConnectionFd, nullptr);
|
||||
}
|
||||
if (int error = xcb_connection_has_error(c)) {
|
||||
std::cerr << "FATAL ERROR: Creating connection to XServer failed: " << error << std::endl;
|
||||
exit(1);
|
||||
return;
|
||||
}
|
||||
setX11Connection(c);
|
||||
// we don't support X11 multi-head in Wayland
|
||||
setX11ScreenNumber(screenNumber);
|
||||
setX11RootWindow(defaultScreen()->root);
|
||||
}
|
||||
|
||||
void WaylandTestApplication::startXwaylandServer()
|
||||
{
|
||||
int pipeFds[2];
|
||||
if (pipe(pipeFds) != 0) {
|
||||
std::cerr << "FATAL ERROR failed to create pipe to start Xwayland " << std::endl;
|
||||
exit(1);
|
||||
return;
|
||||
}
|
||||
int sx[2];
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sx) < 0) {
|
||||
std::cerr << "FATAL ERROR: failed to open socket to open XCB connection" << std::endl;
|
||||
exit(1);
|
||||
return;
|
||||
}
|
||||
int fd = dup(sx[1]);
|
||||
if (fd < 0) {
|
||||
std::cerr << "FATAL ERROR: failed to open socket to open XCB connection" << std::endl;
|
||||
exit(20);
|
||||
return;
|
||||
}
|
||||
|
||||
const int waylandSocket = waylandServer()->createXWaylandConnection();
|
||||
if (waylandSocket == -1) {
|
||||
std::cerr << "FATAL ERROR: failed to open socket for Xwayland" << std::endl;
|
||||
exit(1);
|
||||
return;
|
||||
}
|
||||
const int wlfd = dup(waylandSocket);
|
||||
if (wlfd < 0) {
|
||||
std::cerr << "FATAL ERROR: failed to open socket for Xwayland" << std::endl;
|
||||
exit(20);
|
||||
return;
|
||||
}
|
||||
|
||||
m_xcbConnectionFd = sx[0];
|
||||
|
||||
m_xwaylandProcess = new QProcess(kwinApp());
|
||||
m_xwaylandProcess->setProgram(QStringLiteral("Xwayland"));
|
||||
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
||||
env.insert("WAYLAND_SOCKET", QByteArray::number(wlfd));
|
||||
m_xwaylandProcess->setProcessEnvironment(env);
|
||||
m_xwaylandProcess->setArguments({QStringLiteral("-displayfd"),
|
||||
QString::number(pipeFds[1]),
|
||||
QStringLiteral("-rootless"),
|
||||
QStringLiteral("-wm"),
|
||||
QString::number(fd)});
|
||||
connect(m_xwaylandProcess, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error), this,
|
||||
[] (QProcess::ProcessError error) {
|
||||
if (error == QProcess::FailedToStart) {
|
||||
std::cerr << "FATAL ERROR: failed to start Xwayland" << std::endl;
|
||||
} else {
|
||||
std::cerr << "FATAL ERROR: Xwayland failed, going to exit now" << std::endl;
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
);
|
||||
const int xDisplayPipe = pipeFds[0];
|
||||
connect(m_xwaylandProcess, &QProcess::started, this,
|
||||
[this, xDisplayPipe] {
|
||||
QFutureWatcher<void> *watcher = new QFutureWatcher<void>(this);
|
||||
QObject::connect(watcher, &QFutureWatcher<void>::finished, this, &WaylandTestApplication::continueStartupWithX, Qt::QueuedConnection);
|
||||
QObject::connect(watcher, &QFutureWatcher<void>::finished, watcher, &QFutureWatcher<void>::deleteLater, Qt::QueuedConnection);
|
||||
watcher->setFuture(QtConcurrent::run(readDisplay, xDisplayPipe));
|
||||
}
|
||||
);
|
||||
m_xwaylandProcess->start();
|
||||
close(pipeFds[1]);
|
||||
}
|
||||
|
||||
static void readDisplay(int pipe)
|
||||
{
|
||||
QFile readPipe;
|
||||
if (!readPipe.open(pipe, QIODevice::ReadOnly)) {
|
||||
std::cerr << "FATAL ERROR failed to open pipe to start X Server" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
QByteArray displayNumber = readPipe.readLine();
|
||||
|
||||
displayNumber.prepend(QByteArray(":"));
|
||||
displayNumber.remove(displayNumber.size() -1, 1);
|
||||
std::cout << "X-Server started on display " << displayNumber.constData() << std::endl;
|
||||
|
||||
setenv("DISPLAY", displayNumber.constData(), true);
|
||||
|
||||
// close our pipe
|
||||
close(pipe);
|
||||
}
|
||||
|
||||
}
|
67
autotests/wayland/kwin_wayland_test.h
Normal file
67
autotests/wayland/kwin_wayland_test.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2015 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
#ifndef KWIN_WAYLAND_TEST_H
|
||||
#define KWIN_WAYLAND_TEST_H
|
||||
|
||||
#include "../../main.h"
|
||||
|
||||
// Qt
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class WaylandTestApplication : public Application
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
WaylandTestApplication(int &argc, char **argv);
|
||||
virtual ~WaylandTestApplication();
|
||||
|
||||
protected:
|
||||
void performStartup() override;
|
||||
|
||||
private:
|
||||
void createBackend();
|
||||
void createX11Connection();
|
||||
void continueStartupWithScreens();
|
||||
void continueStartupWithX();
|
||||
void startXwaylandServer();
|
||||
|
||||
int m_xcbConnectionFd = -1;
|
||||
QProcess *m_xwaylandProcess = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#define WAYLANTEST_MAIN(TestObject) \
|
||||
int main(int argc, char *argv[]) \
|
||||
{ \
|
||||
setenv("QT_QPA_PLATFORM", "wayland-org.kde.kwin.qpa", true); \
|
||||
setenv("QT_QPA_PLATFORM_PLUGIN_PATH", KWINQPAPATH, true); \
|
||||
setenv("KWIN_FOCRE_OWN_QPA", "1", true); \
|
||||
KWin::WaylandTestApplication app(argc, argv); \
|
||||
app.setAttribute(Qt::AA_Use96Dpi, true); \
|
||||
TestObject tc; \
|
||||
QTEST_SET_MAIN_SOURCE_PATH \
|
||||
return QTest::qExec(&tc, argc, argv); \
|
||||
}
|
||||
|
||||
#endif
|
164
autotests/wayland/start_test.cpp
Normal file
164
autotests/wayland/start_test.cpp
Normal file
|
@ -0,0 +1,164 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2015 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
#include "kwin_wayland_test.h"
|
||||
#include "abstract_backend.h"
|
||||
#include "screens.h"
|
||||
#include "wayland_server.h"
|
||||
#include "workspace.h"
|
||||
#include "shell_client.h"
|
||||
|
||||
#include <KWayland/Client/connection_thread.h>
|
||||
#include <KWayland/Client/compositor.h>
|
||||
#include <KWayland/Client/event_queue.h>
|
||||
#include <KWayland/Client/registry.h>
|
||||
#include <KWayland/Client/shell.h>
|
||||
#include <KWayland/Client/shm_pool.h>
|
||||
#include <KWayland/Client/surface.h>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
static const QString s_socketName = QStringLiteral("wayland_test_kwin_start_test-0");
|
||||
|
||||
class StartTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
void testScreens();
|
||||
void testNoWindowsAtStart();
|
||||
void testCreateWindow();
|
||||
};
|
||||
|
||||
void StartTest::initTestCase()
|
||||
{
|
||||
QSignalSpy workspaceCreatedSpy(kwinApp(), &Application::workspaceCreated);
|
||||
QVERIFY(workspaceCreatedSpy.isValid());
|
||||
waylandServer()->backend()->setInitialWindowSize(QSize(1280, 1024));
|
||||
waylandServer()->init(s_socketName.toLocal8Bit());
|
||||
kwinApp()->start();
|
||||
QVERIFY(workspaceCreatedSpy.wait());
|
||||
}
|
||||
|
||||
void StartTest::testScreens()
|
||||
{
|
||||
QCOMPARE(screens()->count(), 1);
|
||||
QCOMPARE(screens()->size(), QSize(1280, 1024));
|
||||
QCOMPARE(screens()->geometry(), QRect(0, 0, 1280, 1024));
|
||||
}
|
||||
|
||||
void StartTest::testNoWindowsAtStart()
|
||||
{
|
||||
QVERIFY(workspace()->clientList().isEmpty());
|
||||
QVERIFY(workspace()->desktopList().isEmpty());
|
||||
QVERIFY(workspace()->allClientList().isEmpty());
|
||||
QVERIFY(workspace()->deletedList().isEmpty());
|
||||
QVERIFY(workspace()->unmanagedList().isEmpty());
|
||||
QVERIFY(waylandServer()->clients().isEmpty());
|
||||
}
|
||||
|
||||
void StartTest::testCreateWindow()
|
||||
{
|
||||
// first we need to connect to the server
|
||||
using namespace KWayland::Client;
|
||||
auto connection = new ConnectionThread;
|
||||
QSignalSpy connectedSpy(connection, &ConnectionThread::connected);
|
||||
QVERIFY(connectedSpy.isValid());
|
||||
connection->setSocketName(s_socketName);
|
||||
QThread *thread = new QThread(this);
|
||||
connection->moveToThread(thread);
|
||||
thread->start();
|
||||
connection->initConnection();
|
||||
QVERIFY(connectedSpy.wait());
|
||||
|
||||
QSignalSpy shellClientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded);
|
||||
QVERIFY(shellClientAddedSpy.isValid());
|
||||
QSignalSpy shellClientRemovedSpy(waylandServer(), &WaylandServer::shellClientRemoved);
|
||||
QVERIFY(shellClientRemovedSpy.isValid());
|
||||
|
||||
{
|
||||
EventQueue queue;
|
||||
queue.setup(connection);
|
||||
Registry registry;
|
||||
registry.setEventQueue(&queue);
|
||||
registry.create(connection);
|
||||
QSignalSpy registryAnnouncedSpy(®istry, &Registry::interfacesAnnounced);
|
||||
QVERIFY(registryAnnouncedSpy.isValid());
|
||||
registry.setup();
|
||||
QVERIFY(registryAnnouncedSpy.wait());
|
||||
|
||||
const auto compositorData = registry.interface(Registry::Interface::Compositor);
|
||||
const auto shellData = registry.interface(Registry::Interface::Shell);
|
||||
const auto shmData = registry.interface(Registry::Interface::Shm);
|
||||
QScopedPointer<KWayland::Client::Compositor> compositor(registry.createCompositor(compositorData.name, compositorData.version));
|
||||
QVERIFY(!compositor.isNull());
|
||||
QScopedPointer<Shell> shell(registry.createShell(shellData.name, shellData.version));
|
||||
QVERIFY(!shell.isNull());
|
||||
|
||||
QScopedPointer<Surface> surface(compositor->createSurface());
|
||||
QVERIFY(!surface.isNull());
|
||||
QSignalSpy surfaceRenderedSpy(surface.data(), &Surface::frameRendered);
|
||||
QVERIFY(surfaceRenderedSpy.isValid());
|
||||
|
||||
QScopedPointer<ShellSurface> shellSurface(shell->createSurface(surface.data()));
|
||||
QVERIFY(!shellSurface.isNull());
|
||||
connection->flush();
|
||||
QVERIFY(waylandServer()->clients().isEmpty());
|
||||
// now dispatch should give us the client
|
||||
waylandServer()->dispatch();
|
||||
QCOMPARE(waylandServer()->clients().count(), 1);
|
||||
// but still not yet in workspace
|
||||
QVERIFY(workspace()->allClientList().isEmpty());
|
||||
|
||||
// let's render
|
||||
QImage img(QSize(100, 50), QImage::Format_ARGB32);
|
||||
img.fill(Qt::blue);
|
||||
QScopedPointer<ShmPool> shm(registry.createShmPool(shmData.name, shmData.version));
|
||||
QVERIFY(!shm.isNull());
|
||||
surface->attachBuffer(shm->createBuffer(img));
|
||||
surface->damage(QRect(0, 0, 100, 50));
|
||||
surface->commit();
|
||||
|
||||
connection->flush();
|
||||
QVERIFY(shellClientAddedSpy.wait());
|
||||
QCOMPARE(workspace()->allClientList().count(), 1);
|
||||
QCOMPARE(workspace()->allClientList().first(), waylandServer()->clients().first());
|
||||
QVERIFY(workspace()->activeClient());
|
||||
QCOMPARE(workspace()->activeClient()->pos(), QPoint(0, 0));
|
||||
QCOMPARE(workspace()->activeClient()->size(), QSize(100, 50));
|
||||
QCOMPARE(workspace()->activeClient()->geometry(), QRect(0, 0, 100, 50));
|
||||
|
||||
// and kwin will render it
|
||||
QVERIFY(surfaceRenderedSpy.wait());
|
||||
}
|
||||
// this should tear down everything again
|
||||
QVERIFY(shellClientRemovedSpy.wait());
|
||||
QVERIFY(waylandServer()->clients().isEmpty());
|
||||
|
||||
// cleanup
|
||||
connection->deleteLater();
|
||||
thread->quit();
|
||||
thread->wait();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
WAYLANTEST_MAIN(KWin::StartTest)
|
||||
#include "start_test.moc"
|
|
@ -33,7 +33,7 @@ public:
|
|||
QPlatformIntegration *KWinIntegrationPlugin::create(const QString &system, const QStringList ¶mList)
|
||||
{
|
||||
Q_UNUSED(paramList)
|
||||
if (!QCoreApplication::applicationFilePath().endsWith(QLatin1Literal("kwin_wayland"))) {
|
||||
if (!QCoreApplication::applicationFilePath().endsWith(QLatin1Literal("kwin_wayland")) && !qEnvironmentVariableIsSet("KWIN_FOCRE_OWN_QPA")) {
|
||||
// Not KWin
|
||||
return nullptr;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue