diff --git a/src/wayland/autotests/client/test_wayland_shell.cpp b/src/wayland/autotests/client/test_wayland_shell.cpp index 94cc03d34a..2f24c2b830 100644 --- a/src/wayland/autotests/client/test_wayland_shell.cpp +++ b/src/wayland/autotests/client/test_wayland_shell.cpp @@ -23,12 +23,15 @@ License along with this library. If not, see . #include "../../src/client/compositor.h" #include "../../src/client/connection_thread.h" #include "../../src/client/event_queue.h" +#include "../../src/client/pointer.h" +#include "../../src/client/seat.h" #include "../../src/client/shell.h" #include "../../src/client/surface.h" #include "../../src/client/registry.h" #include "../../src/server/buffer_interface.h" #include "../../src/server/compositor_interface.h" #include "../../src/server/display.h" +#include "../../src/server/seat_interface.h" #include "../../src/server/shell_interface.h" #include "../../src/server/surface_interface.h" // Wayland @@ -54,14 +57,18 @@ private Q_SLOTS: void testWindowClass(); void testDestroy(); void testCast(); + void testMove(); private: KWayland::Server::Display *m_display; KWayland::Server::CompositorInterface *m_compositorInterface; KWayland::Server::ShellInterface *m_shellInterface; + KWayland::Server::SeatInterface *m_seatInterface; KWayland::Client::ConnectionThread *m_connection; KWayland::Client::Compositor *m_compositor; KWayland::Client::Shell *m_shell; + KWayland::Client::Seat *m_seat; + KWayland::Client::Pointer *m_pointer; KWayland::Client::EventQueue *m_queue; QThread *m_thread; }; @@ -73,9 +80,12 @@ TestWaylandShell::TestWaylandShell(QObject *parent) , m_display(nullptr) , m_compositorInterface(nullptr) , m_shellInterface(nullptr) + , m_seatInterface(nullptr) , m_connection(nullptr) , m_compositor(nullptr) , m_shell(nullptr) + , m_seat(nullptr) + , m_pointer(nullptr) , m_queue(nullptr) , m_thread(nullptr) { @@ -100,6 +110,12 @@ void TestWaylandShell::init() m_shellInterface->create(); QVERIFY(m_shellInterface->isValid()); + m_seatInterface = m_display->createSeat(m_display); + QVERIFY(m_seatInterface); + m_seatInterface->setHasPointer(true); + m_seatInterface->create(); + QVERIFY(m_seatInterface->isValid()); + // setup connection m_connection = new KWayland::Client::ConnectionThread; QSignalSpy connectedSpy(m_connection, SIGNAL(connected())); @@ -117,16 +133,21 @@ void TestWaylandShell::init() m_queue->setup(m_connection); QVERIFY(m_queue->isValid()); + using namespace KWayland::Client; KWayland::Client::Registry registry; + QSignalSpy interfacesAnnouncedSpy(®istry, &Registry::interfacesAnnounced); + QVERIFY(interfacesAnnouncedSpy.isValid()); QSignalSpy compositorSpy(®istry, SIGNAL(compositorAnnounced(quint32,quint32))); QSignalSpy shellSpy(®istry, SIGNAL(shellAnnounced(quint32,quint32))); + QSignalSpy seatAnnouncedSpy(®istry, &Registry::seatAnnounced); + QVERIFY(seatAnnouncedSpy.isValid()); QVERIFY(!registry.eventQueue()); registry.setEventQueue(m_queue); QCOMPARE(registry.eventQueue(), m_queue); registry.create(m_connection->display()); QVERIFY(registry.isValid()); registry.setup(); - QVERIFY(compositorSpy.wait()); + QVERIFY(interfacesAnnouncedSpy.wait()); m_compositor = new KWayland::Client::Compositor(this); m_compositor->setup(registry.bindCompositor(compositorSpy.first().first().value(), compositorSpy.first().last().value())); @@ -137,10 +158,28 @@ void TestWaylandShell::init() } m_shell = registry.createShell(shellSpy.first().first().value(), shellSpy.first().last().value(), this); QVERIFY(m_shell->isValid()); + + QVERIFY(!seatAnnouncedSpy.isEmpty()); + m_seat = registry.createSeat(seatAnnouncedSpy.first().first().value(), seatAnnouncedSpy.first().last().value(), this); + QVERIFY(seatAnnouncedSpy.isValid()); + QSignalSpy hasPointerSpy(m_seat, &Seat::hasPointerChanged); + QVERIFY(hasPointerSpy.isValid()); + QVERIFY(hasPointerSpy.wait()); + QVERIFY(hasPointerSpy.first().first().toBool()); + m_pointer = m_seat->createPointer(m_seat); + QVERIFY(m_pointer->isValid()); } void TestWaylandShell::cleanup() { + if (m_pointer) { + delete m_pointer; + m_pointer = nullptr; + } + if (m_seat) { + delete m_seat; + m_seat = nullptr; + } if (m_shell) { delete m_shell; m_shell = nullptr; @@ -164,6 +203,9 @@ void TestWaylandShell::cleanup() m_thread = nullptr; } + delete m_seatInterface; + m_seatInterface = nullptr; + delete m_shellInterface; m_shellInterface = nullptr; @@ -512,6 +554,8 @@ void TestWaylandShell::testDestroy() QVERIFY(surface->isValid()); connect(m_connection, &ConnectionThread::connectionDied, m_shell, &Shell::destroy); + connect(m_connection, &ConnectionThread::connectionDied, m_pointer, &Pointer::destroy); + connect(m_connection, &ConnectionThread::connectionDied, m_seat, &Seat::destroy); connect(m_connection, &ConnectionThread::connectionDied, m_compositor, &Compositor::destroy); connect(m_connection, &ConnectionThread::connectionDied, s.data(), &Surface::destroy); connect(m_connection, &ConnectionThread::connectionDied, m_queue, &EventQueue::destroy); @@ -522,6 +566,7 @@ void TestWaylandShell::testDestroy() m_display = nullptr; m_compositorInterface = nullptr; m_shellInterface = nullptr; + m_seatInterface = nullptr; QVERIFY(connectionDiedSpy.wait()); QVERIFY(!m_shell->isValid()); @@ -555,5 +600,36 @@ void TestWaylandShell::testCast() QCOMPARE((wl_shell*)s2, wlShell); } +void TestWaylandShell::testMove() +{ + using namespace KWayland::Client; + using namespace KWayland::Server; + QScopedPointer s(m_compositor->createSurface()); + QVERIFY(!s.isNull()); + QVERIFY(s->isValid()); + ShellSurface *surface = m_shell->createSurface(s.data(), m_shell); + + QSignalSpy serverSurfaceSpy(m_shellInterface, &ShellInterface::surfaceCreated); + QVERIFY(serverSurfaceSpy.isValid()); + QVERIFY(serverSurfaceSpy.wait()); + ShellSurfaceInterface *serverSurface = serverSurfaceSpy.first().first().value(); + QVERIFY(serverSurface); + QSignalSpy moveRequestedSpy(serverSurface, &ShellSurfaceInterface::moveRequested); + QVERIFY(moveRequestedSpy.isValid()); + + QSignalSpy pointerButtonChangedSpy(m_pointer, &Pointer::buttonStateChanged); + QVERIFY(pointerButtonChangedSpy.isValid()); + + m_seatInterface->setFocusedPointerSurface(serverSurface->surface()); + m_seatInterface->pointerButtonPressed(Qt::LeftButton); + QVERIFY(pointerButtonChangedSpy.wait()); + + surface->requestMove(m_seat, pointerButtonChangedSpy.first().first().value()); + QVERIFY(moveRequestedSpy.wait()); + QCOMPARE(moveRequestedSpy.count(), 1); + QCOMPARE(moveRequestedSpy.first().at(0).value(), m_seatInterface); + QCOMPARE(moveRequestedSpy.first().at(1).value(), m_seatInterface->pointerButtonSerial(Qt::LeftButton)); +} + QTEST_GUILESS_MAIN(TestWaylandShell) #include "test_wayland_shell.moc" diff --git a/src/wayland/seat_interface.h b/src/wayland/seat_interface.h index d4f23bee43..f6e347243a 100644 --- a/src/wayland/seat_interface.h +++ b/src/wayland/seat_interface.h @@ -328,4 +328,6 @@ private: } } +Q_DECLARE_METATYPE(KWayland::Server::SeatInterface*) + #endif diff --git a/src/wayland/server/shell_interface.cpp b/src/wayland/server/shell_interface.cpp index 69e22e6de1..173384c460 100644 --- a/src/wayland/server/shell_interface.cpp +++ b/src/wayland/server/shell_interface.cpp @@ -252,11 +252,9 @@ void ShellSurfaceInterface::requestSize(const QSize &size) void ShellSurfaceInterface::Private::moveCallback(wl_client *client, wl_resource *resource, wl_resource *seat, uint32_t serial) { - Q_UNUSED(seat) - Q_UNUSED(serial) auto s = cast(resource); Q_ASSERT(client == *s->client); - // TODO: implement + emit s->q_func()->moveRequested(SeatInterface::get(seat), serial); } void ShellSurfaceInterface::Private::resizeCallback(wl_client *client, wl_resource *resource, wl_resource *seat, uint32_t serial, uint32_t edges) diff --git a/src/wayland/server/shell_interface.h b/src/wayland/server/shell_interface.h index e0c5bd2ade..42df1e426a 100644 --- a/src/wayland/server/shell_interface.h +++ b/src/wayland/server/shell_interface.h @@ -23,6 +23,7 @@ License along with this library. If not, see . #include #include +#include "seat_interface.h" #include "global.h" #include "resource.h" @@ -36,6 +37,7 @@ namespace Server { class Display; +class SeatInterface; class SurfaceInterface; class ShellSurfaceInterface; @@ -270,6 +272,14 @@ Q_SIGNALS: * @since 5.5 **/ void acceptsKeyboardFocusChanged(); + /** + * The surface requested a window move. + * + * @param seat The SeatInterface on which the surface requested the move + * @param serial The serial of the implicit mouse grab which triggered the move + * @since 5.5 + **/ + void moveRequested(KWayland::Server::SeatInterface *seat, quint32 serial); private: friend class ShellInterface;