Changeset View
Changeset View
Standalone View
Standalone View
autotests/client/test_drag_drop.cpp
Show All 29 Lines | |||||
30 | #include "../../src/client/registry.h" | 30 | #include "../../src/client/registry.h" | ||
31 | #include "../../src/client/seat.h" | 31 | #include "../../src/client/seat.h" | ||
32 | #include "../../src/client/shell.h" | 32 | #include "../../src/client/shell.h" | ||
33 | #include "../../src/client/shm_pool.h" | 33 | #include "../../src/client/shm_pool.h" | ||
34 | #include "../../src/client/surface.h" | 34 | #include "../../src/client/surface.h" | ||
35 | #include "../../src/server/display.h" | 35 | #include "../../src/server/display.h" | ||
36 | #include "../../src/server/compositor_interface.h" | 36 | #include "../../src/server/compositor_interface.h" | ||
37 | #include "../../src/server/datadevicemanager_interface.h" | 37 | #include "../../src/server/datadevicemanager_interface.h" | ||
38 | #include "../../src/server/datasource_interface.h" | ||||
38 | #include "../../src/server/seat_interface.h" | 39 | #include "../../src/server/seat_interface.h" | ||
39 | #include "../../src/server/shell_interface.h" | 40 | #include "../../src/server/shell_interface.h" | ||
40 | 41 | | |||
41 | class TestDragAndDrop : public QObject | 42 | class TestDragAndDrop : public QObject | ||
42 | { | 43 | { | ||
43 | Q_OBJECT | 44 | Q_OBJECT | ||
44 | 45 | | |||
45 | private Q_SLOTS: | 46 | private Q_SLOTS: | ||
46 | void init(); | 47 | void init(); | ||
47 | void cleanup(); | 48 | void cleanup(); | ||
48 | 49 | | |||
49 | void testDragAndDrop(); | 50 | void testDragAndDrop(); | ||
51 | void testDragAndDropWithCancelByDestroyDataSource(); | ||||
50 | void testPointerEventsIgnored(); | 52 | void testPointerEventsIgnored(); | ||
51 | 53 | | |||
52 | private: | 54 | private: | ||
53 | KWayland::Client::Surface *createSurface(); | 55 | KWayland::Client::Surface *createSurface(); | ||
54 | KWayland::Server::SurfaceInterface *getServerSurface(); | 56 | KWayland::Server::SurfaceInterface *getServerSurface(); | ||
55 | 57 | | |||
56 | KWayland::Server::Display *m_display = nullptr; | 58 | KWayland::Server::Display *m_display = nullptr; | ||
57 | KWayland::Server::CompositorInterface *m_compositorInterface = nullptr; | 59 | KWayland::Server::CompositorInterface *m_compositorInterface = nullptr; | ||
▲ Show 20 Lines • Show All 238 Lines • ▼ Show 20 Line(s) | 214 | { | |||
296 | QVERIFY(finishedSpy.wait()); | 298 | QVERIFY(finishedSpy.wait()); | ||
297 | delete offer; | 299 | delete offer; | ||
298 | 300 | | |||
299 | // verify that we did not get any further input events | 301 | // verify that we did not get any further input events | ||
300 | QVERIFY(pointerMotionSpy.isEmpty()); | 302 | QVERIFY(pointerMotionSpy.isEmpty()); | ||
301 | QCOMPARE(buttonPressSpy.count(), 1); | 303 | QCOMPARE(buttonPressSpy.count(), 1); | ||
302 | } | 304 | } | ||
303 | 305 | | |||
306 | | ||||
307 | void TestDragAndDrop::testDragAndDropWithCancelByDestroyDataSource() | ||||
308 | { | ||||
309 | // this test simulates the problem from BUG 389221 | ||||
310 | using namespace KWayland::Server; | ||||
311 | using namespace KWayland::Client; | ||||
312 | // first create a window | ||||
313 | QScopedPointer<Surface> s(createSurface()); | ||||
314 | auto serverSurface = getServerSurface(); | ||||
315 | QVERIFY(serverSurface); | ||||
316 | | ||||
317 | QSignalSpy dataSourceSelectedActionChangedSpy(m_dataSource, &DataSource::selectedDragAndDropActionChanged); | ||||
318 | QVERIFY(dataSourceSelectedActionChangedSpy.isValid()); | ||||
319 | | ||||
320 | // now we need to pass pointer focus to the Surface and simulate a button press | ||||
321 | QSignalSpy buttonPressSpy(m_pointer, &Pointer::buttonStateChanged); | ||||
322 | QVERIFY(buttonPressSpy.isValid()); | ||||
323 | m_seatInterface->setFocusedPointerSurface(serverSurface); | ||||
324 | m_seatInterface->setTimestamp(2); | ||||
325 | m_seatInterface->pointerButtonPressed(1); | ||||
326 | QVERIFY(buttonPressSpy.wait()); | ||||
327 | QCOMPARE(buttonPressSpy.first().at(1).value<quint32>(), quint32(2)); | ||||
328 | | ||||
329 | // add some signal spies for client side | ||||
330 | QSignalSpy dragEnteredSpy(m_dataDevice, &DataDevice::dragEntered); | ||||
331 | QVERIFY(dragEnteredSpy.isValid()); | ||||
332 | QSignalSpy dragMotionSpy(m_dataDevice, &DataDevice::dragMotion); | ||||
333 | QVERIFY(dragMotionSpy.isValid()); | ||||
334 | QSignalSpy pointerMotionSpy(m_pointer, &Pointer::motion); | ||||
335 | QVERIFY(pointerMotionSpy.isValid()); | ||||
336 | QSignalSpy dragLeftSpy(m_dataDevice, &DataDevice::dragLeft); | ||||
337 | QVERIFY(dragLeftSpy.isValid()); | ||||
338 | | ||||
339 | // now we can start the drag and drop | ||||
340 | QSignalSpy dragStartedSpy(m_seatInterface, &SeatInterface::dragStarted); | ||||
341 | QVERIFY(dragStartedSpy.isValid()); | ||||
342 | m_dataSource->setDragAndDropActions(DataDeviceManager::DnDAction::Copy | DataDeviceManager::DnDAction::Move); | ||||
343 | m_dataDevice->startDrag(buttonPressSpy.first().first().value<quint32>(), m_dataSource, s.data()); | ||||
344 | QVERIFY(dragStartedSpy.wait()); | ||||
345 | QCOMPARE(m_seatInterface->dragSurface(), serverSurface); | ||||
346 | QCOMPARE(m_seatInterface->dragSurfaceTransformation(), QMatrix4x4()); | ||||
347 | QVERIFY(!m_seatInterface->dragSource()->icon()); | ||||
348 | QCOMPARE(m_seatInterface->dragSource()->dragImplicitGrabSerial(), buttonPressSpy.first().first().value<quint32>()); | ||||
349 | QVERIFY(dragEnteredSpy.wait()); | ||||
350 | QCOMPARE(dragEnteredSpy.count(), 1); | ||||
351 | QCOMPARE(dragEnteredSpy.first().first().value<quint32>(), m_display->serial()); | ||||
352 | QCOMPARE(dragEnteredSpy.first().last().toPointF(), QPointF(0, 0)); | ||||
353 | QCOMPARE(m_dataDevice->dragSurface().data(), s.data()); | ||||
354 | auto offer = m_dataDevice->dragOffer(); | ||||
355 | QVERIFY(offer); | ||||
356 | QCOMPARE(offer->selectedDragAndDropAction(), DataDeviceManager::DnDAction::None); | ||||
357 | QSignalSpy offerActionChangedSpy(offer, &DataOffer::selectedDragAndDropActionChanged); | ||||
358 | QVERIFY(offerActionChangedSpy.isValid()); | ||||
359 | QCOMPARE(m_dataDevice->dragOffer()->offeredMimeTypes().count(), 1); | ||||
360 | QCOMPARE(m_dataDevice->dragOffer()->offeredMimeTypes().first().name(), QStringLiteral("text/plain")); | ||||
361 | QTRY_COMPARE(offer->sourceDragAndDropActions(), DataDeviceManager::DnDAction::Copy | DataDeviceManager::DnDAction::Move); | ||||
362 | offer->setDragAndDropActions(DataDeviceManager::DnDAction::Copy | DataDeviceManager::DnDAction::Move, DataDeviceManager::DnDAction::Move); | ||||
363 | QVERIFY(offerActionChangedSpy.wait()); | ||||
364 | QCOMPARE(offerActionChangedSpy.count(), 1); | ||||
365 | QCOMPARE(offer->selectedDragAndDropAction(), DataDeviceManager::DnDAction::Move); | ||||
366 | QCOMPARE(dataSourceSelectedActionChangedSpy.count(), 1); | ||||
367 | QCOMPARE(m_dataSource->selectedDragAndDropAction(), DataDeviceManager::DnDAction::Move); | ||||
368 | | ||||
369 | // simulate motion | ||||
370 | m_seatInterface->setTimestamp(3); | ||||
371 | m_seatInterface->setPointerPos(QPointF(3, 3)); | ||||
372 | QVERIFY(dragMotionSpy.wait()); | ||||
373 | QCOMPARE(dragMotionSpy.count(), 1); | ||||
374 | QCOMPARE(dragMotionSpy.first().first().toPointF(), QPointF(3, 3)); | ||||
375 | QCOMPARE(dragMotionSpy.first().last().toUInt(), 3u); | ||||
376 | | ||||
377 | // now delete the DataSource | ||||
378 | delete m_dataSource; | ||||
379 | m_dataSource = nullptr; | ||||
380 | QSignalSpy serverDragEndedSpy(m_seatInterface, &SeatInterface::dragEnded); | ||||
381 | QVERIFY(serverDragEndedSpy.isValid()); | ||||
382 | QVERIFY(dragLeftSpy.isEmpty()); | ||||
383 | QVERIFY(dragLeftSpy.wait()); | ||||
384 | QTRY_COMPARE(dragLeftSpy.count(), 1); | ||||
385 | QTRY_COMPARE(serverDragEndedSpy.count(), 1); | ||||
386 | | ||||
387 | // simulate drop | ||||
388 | QSignalSpy droppedSpy(m_dataDevice, &DataDevice::dropped); | ||||
389 | QVERIFY(droppedSpy.isValid()); | ||||
390 | m_seatInterface->setTimestamp(4); | ||||
391 | m_seatInterface->pointerButtonReleased(1); | ||||
392 | QVERIFY(!droppedSpy.wait()); | ||||
393 | | ||||
394 | // verify that we did not get any further input events | ||||
395 | QVERIFY(pointerMotionSpy.isEmpty()); | ||||
396 | QCOMPARE(buttonPressSpy.count(), 2); | ||||
397 | } | ||||
398 | | ||||
304 | void TestDragAndDrop::testPointerEventsIgnored() | 399 | void TestDragAndDrop::testPointerEventsIgnored() | ||
305 | { | 400 | { | ||
306 | // this test verifies that all pointer events are ignored on the focused Pointer device during drag | 401 | // this test verifies that all pointer events are ignored on the focused Pointer device during drag | ||
307 | using namespace KWayland::Server; | 402 | using namespace KWayland::Server; | ||
308 | using namespace KWayland::Client; | 403 | using namespace KWayland::Client; | ||
309 | // first create a window | 404 | // first create a window | ||
310 | QScopedPointer<Surface> s(createSurface()); | 405 | QScopedPointer<Surface> s(createSurface()); | ||
311 | auto serverSurface = getServerSurface(); | 406 | auto serverSurface = getServerSurface(); | ||
▲ Show 20 Lines • Show All 74 Lines • Show Last 20 Lines |