22#include <KWayland/Client/compositor.h>
23#include <KWayland/Client/connection_thread.h>
24#include <KWayland/Client/event_queue.h>
25#include <KWayland/Client/registry.h>
26#include <KWayland/Client/seat.h>
28#include "qwayland-wlr-data-control-unstable-v1.h"
34Q_DECLARE_OPAQUE_POINTER(::zwlr_data_control_offer_v1 *)
52 return m_receivedOffers;
58 m_receivedOffers << mime_type;
62 QStringList m_receivedOffers;
75 void selection(struct ::zwlr_data_control_offer_v1 *
id);
127 return {
"text/test1",
"text/test2"};
140 void testCopyToControl();
141 void testCopyToControlPrimarySelection();
142 void testCopyFromControl();
143 void testCopyFromControlPrimarySelection();
144 void testKlipperCase();
147 KWayland::Client::ConnectionThread *m_connection;
148 KWayland::Client::EventQueue *m_queue;
149 KWayland::Client::Compositor *m_clientCompositor;
150 KWayland::Client::Seat *m_clientSeat =
nullptr;
161 QList<SurfaceInterface *> m_surfaces;
164static const QString s_socketName = QStringLiteral(
"kwin-wayland-datacontrol-test-0");
166void DataControlInterfaceTest::init()
178 m_connection =
new KWayland::Client::ConnectionThread;
179 QSignalSpy connectedSpy(m_connection, &KWayland::Client::ConnectionThread::connected);
180 m_connection->setSocketName(s_socketName);
182 m_thread =
new QThread(
this);
183 m_connection->moveToThread(m_thread);
186 m_connection->initConnection();
187 QVERIFY(connectedSpy.wait());
188 QVERIFY(!m_connection->connections().isEmpty());
190 m_queue =
new KWayland::Client::EventQueue(
this);
191 QVERIFY(!m_queue->isValid());
192 m_queue->setup(m_connection);
193 QVERIFY(m_queue->isValid());
195 KWayland::Client::Registry registry;
196 connect(®istry, &KWayland::Client::Registry::interfaceAnnounced,
this, [
this, ®istry](
const QByteArray &interface, quint32 name, quint32
version) {
197 if (interface ==
"zwlr_data_control_manager_v1") {
199 m_dataControlDeviceManager->init(registry.registry(), name,
version);
202 connect(®istry, &KWayland::Client::Registry::seatAnnounced,
this, [
this, ®istry](quint32 name, quint32
version) {
206 QSignalSpy compositorSpy(®istry, &KWayland::Client::Registry::compositorAnnounced);
207 registry.create(m_connection->display());
210 wl_display_flush(m_connection->display());
212 QVERIFY(compositorSpy.wait());
213 m_clientCompositor =
registry.createCompositor(compositorSpy.first().first().value<quint32>(), compositorSpy.first().last().value<quint32>(),
this);
214 QVERIFY(m_clientCompositor->isValid());
216 QVERIFY(m_dataControlDeviceManager);
219void DataControlInterfaceTest::cleanup()
221#define CLEANUP(variable) \
224 variable = nullptr; \
226 CLEANUP(m_dataControlDeviceManager)
231 m_connection->deleteLater();
232 m_connection =
nullptr;
245 m_serverCompositor =
nullptr;
248void DataControlInterfaceTest::testCopyToControl()
254 dataControlDevice->init(m_dataControlDeviceManager->get_data_device(*m_clientSeat));
259 std::unique_ptr<TestDataSource> testSelection(
new TestDataSource);
265 QCOMPARE(newOfferSpy.count(), 1);
266 std::unique_ptr<DataControlOffer> offer(newOfferSpy.first().first().value<
DataControlOffer *>());
267 QCOMPARE(selectionSpy.first().first().value<struct ::zwlr_data_control_offer_v1 *>(), offer->object());
269 QCOMPARE(offer->receivedOffers().count(), 2);
270 QCOMPARE(offer->receivedOffers()[0],
"text/test1");
271 QCOMPARE(offer->receivedOffers()[1],
"text/test2");
274void DataControlInterfaceTest::testCopyToControlPrimarySelection()
280 dataControlDevice->init(m_dataControlDeviceManager->get_data_device(*m_clientSeat));
285 std::unique_ptr<TestDataSource> testSelection(
new TestDataSource);
291 QCOMPARE(newOfferSpy.count(), 1);
292 std::unique_ptr<DataControlOffer> offer(newOfferSpy.first().first().value<
DataControlOffer *>());
293 QCOMPARE(selectionSpy.first().first().value<struct ::zwlr_data_control_offer_v1 *>(), offer->object());
295 QCOMPARE(offer->receivedOffers().count(), 2);
296 QCOMPARE(offer->receivedOffers()[0],
"text/test1");
297 QCOMPARE(offer->receivedOffers()[1],
"text/test2");
300void DataControlInterfaceTest::testCopyFromControl()
307 dataControlDevice->init(m_dataControlDeviceManager->get_data_device(*m_clientSeat));
310 source->init(m_dataControlDeviceManager->create_data_source());
311 source->offer(
"cheese/test1");
312 source->offer(
"cheese/test2");
314 dataControlDevice->set_selection(source->object());
316 serverSelectionChangedSpy.wait();
318 QCOMPARE(m_seat->
selection()->
mimeTypes(), QStringList({
"cheese/test1",
"cheese/test2"}));
321void DataControlInterfaceTest::testCopyFromControlPrimarySelection()
328 dataControlDevice->init(m_dataControlDeviceManager->get_data_device(*m_clientSeat));
331 source->init(m_dataControlDeviceManager->create_data_source());
332 source->offer(
"cheese/test1");
333 source->offer(
"cheese/test2");
335 dataControlDevice->set_primary_selection(source->object());
337 serverSelectionChangedSpy.wait();
342void DataControlInterfaceTest::testKlipperCase()
348 dataControlDevice->init(m_dataControlDeviceManager->get_data_device(*m_clientSeat));
355 std::unique_ptr<TestDataSource> testSelection(
new TestDataSource);
362 testSelection.reset();
368 std::unique_ptr<TestDataSource> testSelection2(
new TestDataSource);
373 source->init(m_dataControlDeviceManager->create_data_source());
374 source->offer(
"fromKlipper/test1");
375 source->offer(
"application/x-kde-onlyReplaceEmpty");
377 dataControlDevice->set_selection(source->object());
379 QVERIFY(!serverSelectionChangedSpy.wait(10));
380 QCOMPARE(m_seat->
selection(), testSelection2.get());
385#include "test_datacontrol_interface.moc"
void primary_selection(struct ::zwlr_data_control_offer_v1 *id)
void dataControlOffer(DataControlOffer *offer)
void selection(struct ::zwlr_data_control_offer_v1 *id)
void zwlr_data_control_device_v1_data_offer(struct ::zwlr_data_control_offer_v1 *id) override
void zwlr_data_control_device_v1_primary_selection(struct ::zwlr_data_control_offer_v1 *id) override
void zwlr_data_control_device_v1_selection(struct ::zwlr_data_control_offer_v1 *id) override
QStringList receivedOffers()
virtual void zwlr_data_control_offer_v1_offer(const QString &mime_type) override
The AbstractDataSource class abstracts the data that can be transferred to another client.
virtual QStringList mimeTypes() const =0
void aboutToBeDestroyed()
Class holding the Wayland server display loop.
bool addSocketName(const QString &name=QString())
Represents a Seat on the Wayland Display.
void setSelection(AbstractDataSource *selection)
void setPrimarySelection(AbstractDataSource *selection)
void selectionChanged(KWin::AbstractDataSource *)
void primarySelectionChanged(KWin::AbstractDataSource *)
AbstractDataSource * selection() const
AbstractDataSource * primarySelection() const
void requestData(const QString &mimeType, qint32 fd) override
QStringList mimeTypes() const override
KWayland::Client::Registry * registry
#define CLEANUP(variable)