2020-08-02 22:22:19 +00:00
|
|
|
/*
|
|
|
|
KWin - the KDE window manager
|
|
|
|
This file is part of the KDE project.
|
2016-06-20 09:21:16 +00:00
|
|
|
|
2020-08-02 22:22:19 +00:00
|
|
|
SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
|
|
|
|
SPDX-FileCopyrightText: 2019 Roman Gilg <subdiff@gmail.com>
|
2016-06-20 09:21:16 +00:00
|
|
|
|
2020-08-02 22:22:19 +00:00
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
*/
|
2016-06-20 09:21:16 +00:00
|
|
|
#include "kwin_wayland_test.h"
|
2020-03-04 07:55:26 +00:00
|
|
|
#include "abstract_client.h"
|
2021-08-31 07:03:05 +00:00
|
|
|
#include "abstract_output.h"
|
2016-06-20 09:21:16 +00:00
|
|
|
#include "platform.h"
|
|
|
|
#include "screens.h"
|
|
|
|
#include "wayland_server.h"
|
|
|
|
#include "workspace.h"
|
2021-02-09 18:18:36 +00:00
|
|
|
#include "xwl/databridge.h"
|
2016-06-20 09:21:16 +00:00
|
|
|
|
2021-09-08 11:25:48 +00:00
|
|
|
#include <KWaylandServer/seat_interface.h>
|
2016-06-20 09:21:16 +00:00
|
|
|
|
|
|
|
#include <QProcess>
|
|
|
|
#include <QProcessEnvironment>
|
|
|
|
|
|
|
|
using namespace KWin;
|
|
|
|
|
2018-08-21 20:06:42 +00:00
|
|
|
static const QString s_socketName = QStringLiteral("wayland_test_kwin_xwayland_selections-0");
|
2016-06-20 09:21:16 +00:00
|
|
|
|
2021-09-08 11:25:48 +00:00
|
|
|
struct ProcessKillBeforeDeleter {
|
|
|
|
static inline void cleanup(QProcess *pointer)
|
|
|
|
{
|
|
|
|
if (pointer)
|
|
|
|
pointer->kill();
|
|
|
|
delete pointer;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-08-21 20:06:42 +00:00
|
|
|
class XwaylandSelectionsTest : public QObject
|
2016-06-20 09:21:16 +00:00
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
private Q_SLOTS:
|
|
|
|
void initTestCase();
|
|
|
|
void testSync_data();
|
|
|
|
void testSync();
|
|
|
|
};
|
|
|
|
|
2018-08-21 20:06:42 +00:00
|
|
|
void XwaylandSelectionsTest::initTestCase()
|
2016-06-20 09:21:16 +00:00
|
|
|
{
|
2021-09-08 11:25:48 +00:00
|
|
|
// QSKIP("Skipped as it fails for unknown reasons on build.kde.org");
|
2016-06-20 09:21:16 +00:00
|
|
|
qRegisterMetaType<KWin::AbstractClient*>();
|
|
|
|
qRegisterMetaType<QProcess::ExitStatus>();
|
2020-07-07 09:32:29 +00:00
|
|
|
QSignalSpy applicationStartedSpy(kwinApp(), &Application::started);
|
|
|
|
QVERIFY(applicationStartedSpy.isValid());
|
2016-06-20 09:21:16 +00:00
|
|
|
kwinApp()->platform()->setInitialWindowSize(QSize(1280, 1024));
|
2018-08-21 20:06:42 +00:00
|
|
|
// QSignalSpy clipboardSyncDevicedCreated{waylandServer(), &WaylandServer::xclipboardSyncDataDeviceCreated};
|
|
|
|
// QVERIFY(clipboardSyncDevicedCreated.isValid());
|
2020-12-09 13:06:15 +00:00
|
|
|
QVERIFY(waylandServer()->init(s_socketName));
|
2019-08-26 21:16:53 +00:00
|
|
|
QMetaObject::invokeMethod(kwinApp()->platform(), "setVirtualOutputs", Qt::DirectConnection, Q_ARG(int, 2));
|
2016-06-20 09:21:16 +00:00
|
|
|
|
|
|
|
kwinApp()->start();
|
2020-07-07 09:32:29 +00:00
|
|
|
QVERIFY(applicationStartedSpy.wait());
|
2021-08-31 07:03:05 +00:00
|
|
|
const auto outputs = kwinApp()->platform()->enabledOutputs();
|
|
|
|
QCOMPARE(outputs.count(), 2);
|
|
|
|
QCOMPARE(outputs[0]->geometry(), QRect(0, 0, 1280, 1024));
|
|
|
|
QCOMPARE(outputs[1]->geometry(), QRect(1280, 0, 1280, 1024));
|
2021-05-08 00:08:22 +00:00
|
|
|
Test::initWaylandWorkspace();
|
2018-08-21 20:06:42 +00:00
|
|
|
// // wait till the xclipboard sync data device is created
|
|
|
|
// if (clipboardSyncDevicedCreated.empty()) {
|
|
|
|
// QVERIFY(clipboardSyncDevicedCreated.wait());
|
|
|
|
// }
|
2016-06-20 09:21:16 +00:00
|
|
|
}
|
|
|
|
|
2018-08-21 20:06:42 +00:00
|
|
|
void XwaylandSelectionsTest::testSync_data()
|
2016-06-20 09:21:16 +00:00
|
|
|
{
|
|
|
|
QTest::addColumn<QString>("copyPlatform");
|
|
|
|
QTest::addColumn<QString>("pastePlatform");
|
|
|
|
|
2018-08-21 20:06:42 +00:00
|
|
|
QTest::newRow("x11->wayland") << QStringLiteral("xcb") << QStringLiteral("wayland");
|
|
|
|
QTest::newRow("wayland->x11") << QStringLiteral("wayland") << QStringLiteral("xcb");
|
2016-06-20 09:21:16 +00:00
|
|
|
}
|
|
|
|
|
2018-08-21 20:06:42 +00:00
|
|
|
void XwaylandSelectionsTest::testSync()
|
2016-06-20 09:21:16 +00:00
|
|
|
{
|
|
|
|
// this test verifies the syncing of X11 to Wayland clipboard
|
2017-08-25 16:18:20 +00:00
|
|
|
const QString copy = QFINDTESTDATA(QStringLiteral("copy"));
|
2016-06-20 09:21:16 +00:00
|
|
|
QVERIFY(!copy.isEmpty());
|
2017-08-25 16:18:20 +00:00
|
|
|
const QString paste = QFINDTESTDATA(QStringLiteral("paste"));
|
2016-06-20 09:21:16 +00:00
|
|
|
QVERIFY(!paste.isEmpty());
|
|
|
|
|
|
|
|
QSignalSpy clientAddedSpy(workspace(), &Workspace::clientAdded);
|
|
|
|
QVERIFY(clientAddedSpy.isValid());
|
2021-09-08 11:25:48 +00:00
|
|
|
QSignalSpy clipboardChangedSpy(waylandServer()->seat(), &KWaylandServer::SeatInterface::selectionChanged);
|
2016-06-20 09:21:16 +00:00
|
|
|
QVERIFY(clipboardChangedSpy.isValid());
|
|
|
|
|
|
|
|
QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
|
2018-08-21 20:06:42 +00:00
|
|
|
|
|
|
|
// start the copy process
|
2016-06-20 09:21:16 +00:00
|
|
|
QFETCH(QString, copyPlatform);
|
|
|
|
environment.insert(QStringLiteral("QT_QPA_PLATFORM"), copyPlatform);
|
|
|
|
environment.insert(QStringLiteral("WAYLAND_DISPLAY"), s_socketName);
|
2021-09-08 11:25:48 +00:00
|
|
|
QScopedPointer<QProcess, ProcessKillBeforeDeleter> copyProcess(new QProcess());
|
|
|
|
copyProcess->setProcessEnvironment(environment);
|
|
|
|
copyProcess->setProcessChannelMode(QProcess::ForwardedChannels);
|
|
|
|
copyProcess->setProgram(copy);
|
|
|
|
copyProcess->start();
|
|
|
|
QVERIFY(copyProcess->waitForStarted());
|
2016-06-20 09:21:16 +00:00
|
|
|
|
|
|
|
AbstractClient *copyClient = nullptr;
|
2020-07-22 18:35:41 +00:00
|
|
|
QVERIFY(clientAddedSpy.wait());
|
|
|
|
copyClient = clientAddedSpy.first().first().value<AbstractClient *>();
|
2016-06-20 09:21:16 +00:00
|
|
|
QVERIFY(copyClient);
|
|
|
|
if (workspace()->activeClient() != copyClient) {
|
|
|
|
workspace()->activateClient(copyClient);
|
|
|
|
}
|
|
|
|
QCOMPARE(workspace()->activeClient(), copyClient);
|
2021-09-08 11:25:48 +00:00
|
|
|
clipboardChangedSpy.wait();
|
2016-06-20 09:21:16 +00:00
|
|
|
|
|
|
|
// start the paste process
|
2021-09-08 11:25:48 +00:00
|
|
|
QScopedPointer<QProcess, ProcessKillBeforeDeleter> pasteProcess(new QProcess());
|
|
|
|
QSignalSpy finishedSpy(pasteProcess.data(), static_cast<void(QProcess::*)(int,QProcess::ExitStatus)>(&QProcess::finished));
|
2016-06-20 09:21:16 +00:00
|
|
|
QVERIFY(finishedSpy.isValid());
|
|
|
|
QFETCH(QString, pastePlatform);
|
|
|
|
environment.insert(QStringLiteral("QT_QPA_PLATFORM"), pastePlatform);
|
2021-09-08 11:25:48 +00:00
|
|
|
pasteProcess->setProcessEnvironment(environment);
|
|
|
|
pasteProcess->setProcessChannelMode(QProcess::ForwardedChannels);
|
|
|
|
pasteProcess->setProgram(paste);
|
|
|
|
pasteProcess->start();
|
|
|
|
QVERIFY(pasteProcess->waitForStarted());
|
2016-06-20 09:21:16 +00:00
|
|
|
|
2021-09-08 11:25:48 +00:00
|
|
|
clientAddedSpy.clear();
|
2016-06-20 09:21:16 +00:00
|
|
|
AbstractClient *pasteClient = nullptr;
|
2020-07-22 18:35:41 +00:00
|
|
|
QVERIFY(clientAddedSpy.wait());
|
|
|
|
pasteClient = clientAddedSpy.last().first().value<AbstractClient *>();
|
2016-06-20 09:21:16 +00:00
|
|
|
QCOMPARE(clientAddedSpy.count(), 1);
|
|
|
|
QVERIFY(pasteClient);
|
2018-08-21 20:06:42 +00:00
|
|
|
|
2016-06-20 09:21:16 +00:00
|
|
|
if (workspace()->activeClient() != pasteClient) {
|
2016-06-29 10:38:02 +00:00
|
|
|
QSignalSpy clientActivatedSpy(workspace(), &Workspace::clientActivated);
|
|
|
|
QVERIFY(clientActivatedSpy.isValid());
|
2016-06-20 09:21:16 +00:00
|
|
|
workspace()->activateClient(pasteClient);
|
2016-06-29 10:38:02 +00:00
|
|
|
QVERIFY(clientActivatedSpy.wait());
|
2016-06-20 09:21:16 +00:00
|
|
|
}
|
|
|
|
QTRY_COMPARE(workspace()->activeClient(), pasteClient);
|
|
|
|
QVERIFY(finishedSpy.wait());
|
|
|
|
QCOMPARE(finishedSpy.first().first().toInt(), 0);
|
|
|
|
}
|
|
|
|
|
2018-08-21 20:06:42 +00:00
|
|
|
WAYLANDTEST_MAIN(XwaylandSelectionsTest)
|
|
|
|
#include "xwayland_selections_test.moc"
|