summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/client/client.pro4
-rw-r--r--tests/auto/client/client/client.pro26
-rw-r--r--tests/auto/client/client/tst_client.cpp96
-rw-r--r--tests/auto/client/shared/mockcompositor.cpp (renamed from tests/auto/client/client/mockcompositor.cpp)71
-rw-r--r--tests/auto/client/shared/mockcompositor.h (renamed from tests/auto/client/client/mockcompositor.h)53
-rw-r--r--tests/auto/client/shared/mockinput.cpp (renamed from tests/auto/client/client/mockinput.cpp)21
-rw-r--r--tests/auto/client/shared/mockinput.h (renamed from tests/auto/client/client/mockinput.h)0
-rw-r--r--tests/auto/client/shared/mockoutput.cpp112
-rw-r--r--tests/auto/client/shared/mockoutput.h (renamed from tests/auto/client/client/mockoutput.cpp)51
-rw-r--r--tests/auto/client/shared/mockshell.cpp (renamed from tests/auto/client/client/mockshell.cpp)0
-rw-r--r--tests/auto/client/shared/mocksurface.cpp (renamed from tests/auto/client/client/mocksurface.cpp)31
-rw-r--r--tests/auto/client/shared/mocksurface.h (renamed from tests/auto/client/client/mocksurface.h)0
-rw-r--r--tests/auto/client/shared/mockxdgshellv6.cpp132
-rw-r--r--tests/auto/client/shared/shared.pri26
-rw-r--r--tests/auto/client/xdgshellv6/tst_xdgshellv6.cpp120
-rw-r--r--tests/auto/client/xdgshellv6/xdgshellv6.pro5
-rw-r--r--tests/auto/cmake/test_waylandclient/main.cpp2
-rw-r--r--tests/auto/compositor/compositor/mockclient.cpp24
-rw-r--r--tests/auto/compositor/compositor/mockclient.h4
-rw-r--r--tests/auto/compositor/compositor/testcompositor.cpp2
-rw-r--r--tests/auto/compositor/compositor/tst_compositor.cpp19
21 files changed, 698 insertions, 101 deletions
diff --git a/tests/auto/client/client.pro b/tests/auto/client/client.pro
index 916b3abe4..d19326797 100644
--- a/tests/auto/client/client.pro
+++ b/tests/auto/client/client.pro
@@ -1,3 +1,5 @@
TEMPLATE=subdirs
-SUBDIRS += client
+SUBDIRS += \
+ client \
+ xdgshellv6
diff --git a/tests/auto/client/client/client.pro b/tests/auto/client/client/client.pro
index e6e607c3f..edf80bb9b 100644
--- a/tests/auto/client/client/client.pro
+++ b/tests/auto/client/client/client.pro
@@ -1,24 +1,4 @@
-CONFIG += testcase link_pkgconfig
-TARGET = tst_client
-
-QT += testlib
-QT += core-private gui-private waylandclient-private
-
-QMAKE_USE += wayland-client wayland-server
+include (../shared/shared.pri)
-CONFIG += wayland-scanner
-WAYLANDSERVERSOURCES += \
- ../../../../src/3rdparty/protocol/wayland.xml
-
-SOURCES += \
- tst_client.cpp \
- mockcompositor.cpp \
- mockinput.cpp \
- mockshell.cpp \
- mocksurface.cpp \
- mockoutput.cpp
-
-HEADERS += \
- mockcompositor.h \
- mockinput.h \
- mocksurface.h
+TARGET = tst_client
+SOURCES += tst_client.cpp
diff --git a/tests/auto/client/client/tst_client.cpp b/tests/auto/client/client/tst_client.cpp
index aed601d8a..94198b457 100644
--- a/tests/auto/client/client/tst_client.cpp
+++ b/tests/auto/client/client/tst_client.cpp
@@ -97,6 +97,7 @@ public:
void touchEvent(QTouchEvent *event) override
{
+ Q_UNUSED(event);
++touchEventCount;
}
@@ -161,7 +162,10 @@ public slots:
}
private slots:
- void screen();
+ void primaryScreen();
+ void screens();
+ void windowScreens();
+ void removePrimaryScreen();
void createDestroyWindow();
void events();
void backingStore();
@@ -176,11 +180,96 @@ private:
MockCompositor *compositor;
};
-void tst_WaylandClient::screen()
+void tst_WaylandClient::primaryScreen()
{
+ compositor->setOutputMode(screenSize);
QTRY_COMPARE(QGuiApplication::primaryScreen()->size(), screenSize);
}
+void tst_WaylandClient::screens()
+{
+ QTRY_COMPARE(QGuiApplication::screens().size(), 1);
+ compositor->sendAddOutput();
+ QTRY_COMPARE(QGuiApplication::screens().size(), 2);
+ QSharedPointer<MockOutput> secondOutput;
+ QTRY_VERIFY(secondOutput = compositor->output(1));
+ compositor->sendRemoveOutput(secondOutput);
+ QTRY_COMPARE(QGuiApplication::screens().size(), 1);
+}
+
+void tst_WaylandClient::windowScreens()
+{
+ QSharedPointer<MockOutput> firstOutput;
+ QTRY_VERIFY(firstOutput = compositor->output());
+
+ TestWindow window;
+ window.show();
+
+ QSharedPointer<MockSurface> surface;
+ QTRY_VERIFY(surface = compositor->surface());
+ QTRY_COMPARE(QGuiApplication::screens().size(), 1);
+ QScreen *primaryScreen = QGuiApplication::screens().first();
+ QCOMPARE(window.screen(), primaryScreen);
+
+ compositor->sendAddOutput();
+
+ QTRY_COMPARE(QGuiApplication::screens().size(), 2);
+ QScreen *secondaryScreen = QGuiApplication::screens().at(1);
+ QVERIFY(secondaryScreen);
+
+ window.setScreen(secondaryScreen);
+ QCOMPARE(window.screen(), secondaryScreen);
+
+ QSharedPointer<MockOutput> secondOutput;
+ QTRY_VERIFY(secondOutput = compositor->output(1));
+ compositor->sendSurfaceEnter(surface, firstOutput);
+
+ compositor->sendSurfaceEnter(surface, secondOutput);
+ QTRY_COMPARE(window.screen(), primaryScreen);
+
+ compositor->sendSurfaceLeave(surface, firstOutput);
+ QTRY_COMPARE(window.screen(), secondaryScreen);
+
+ compositor->sendRemoveOutput(secondOutput);
+ QTRY_COMPARE(QGuiApplication::screens().size(), 1);
+ QCOMPARE(window.screen(), primaryScreen);
+
+ window.destroy();
+ QTRY_VERIFY(!compositor->surface());
+}
+
+void tst_WaylandClient::removePrimaryScreen()
+{
+ QSharedPointer<MockOutput> firstOutput;
+ QTRY_VERIFY(firstOutput = compositor->output());
+
+ TestWindow window;
+ window.show();
+
+ QSharedPointer<MockSurface> surface;
+ QTRY_VERIFY(surface = compositor->surface());
+ QTRY_COMPARE(QGuiApplication::screens().size(), 1);
+ QScreen *primaryScreen = QGuiApplication::screens().first();
+ QCOMPARE(window.screen(), primaryScreen);
+
+ compositor->sendAddOutput();
+
+ QTRY_COMPARE(QGuiApplication::screens().size(), 2);
+ QScreen *secondaryScreen = QGuiApplication::screens().at(1);
+ QVERIFY(secondaryScreen);
+
+ compositor->sendRemoveOutput(firstOutput);
+ QTRY_COMPARE(QGuiApplication::screens().size(), 1);
+
+ compositor->sendMousePress(surface, window.frameOffset() + QPoint(10, 10));
+ QTRY_COMPARE(window.mousePressEventCount, 1);
+ compositor->sendMouseRelease(surface);
+ QTRY_COMPARE(window.mouseReleaseEventCount, 1);
+
+ window.destroy();
+ QTRY_VERIFY(!compositor->surface());
+}
+
void tst_WaylandClient::createDestroyWindow()
{
TestWindow window;
@@ -301,6 +390,7 @@ public:
protected:
void mousePressEvent(QMouseEvent *event) override
{
+ Q_UNUSED(event);
if (dragStarted)
return;
dragStarted = true;
@@ -452,7 +542,7 @@ int main(int argc, char **argv)
setenv("QT_QPA_PLATFORM", "wayland", 1); // force QGuiApplication to use wayland plugin
MockCompositor compositor;
- compositor.setOutputGeometry(QRect(QPoint(), screenSize));
+ compositor.setOutputMode(screenSize);
QGuiApplication app(argc, argv);
diff --git a/tests/auto/client/client/mockcompositor.cpp b/tests/auto/client/shared/mockcompositor.cpp
index 2c5f2541f..e7c6e90d2 100644
--- a/tests/auto/client/client/mockcompositor.cpp
+++ b/tests/auto/client/shared/mockcompositor.cpp
@@ -28,8 +28,11 @@
#include "mockcompositor.h"
#include "mockinput.h"
+#include "mockoutput.h"
#include "mocksurface.h"
+#include <wayland-xdg-shell-unstable-v6-server-protocol.h>
+
#include <stdio.h>
MockCompositor::MockCompositor()
: m_alive(true)
@@ -75,10 +78,10 @@ void MockCompositor::processWaylandEvents()
m_waitCondition.wakeOne();
}
-void MockCompositor::setOutputGeometry(const QRect &rect)
+void MockCompositor::setOutputMode(const QSize &size)
{
- Command command = makeCommand(Impl::Compositor::setOutputGeometry, m_compositor);
- command.parameters << rect;
+ Command command = makeCommand(Impl::Compositor::setOutputMode, m_compositor);
+ command.parameters << size;
processCommand(command);
}
@@ -180,6 +183,35 @@ void MockCompositor::sendDataDeviceLeave(const QSharedPointer<MockSurface> &surf
processCommand(command);
}
+void MockCompositor::sendAddOutput()
+{
+ Command command = makeCommand(Impl::Compositor::sendAddOutput, m_compositor);
+ processCommand(command);
+}
+
+void MockCompositor::sendRemoveOutput(const QSharedPointer<MockOutput> &output)
+{
+ Command command = makeCommand(Impl::Compositor::sendRemoveOutput, m_compositor);
+ command.parameters << QVariant::fromValue(output);
+ processCommand(command);
+}
+
+void MockCompositor::sendSurfaceEnter(const QSharedPointer<MockSurface> &surface, QSharedPointer<MockOutput> &output)
+{
+ Command command = makeCommand(Impl::Compositor::sendSurfaceEnter, m_compositor);
+ command.parameters << QVariant::fromValue(surface);
+ command.parameters << QVariant::fromValue(output);
+ processCommand(command);
+}
+
+void MockCompositor::sendSurfaceLeave(const QSharedPointer<MockSurface> &surface, QSharedPointer<MockOutput> &output)
+{
+ Command command = makeCommand(Impl::Compositor::sendSurfaceLeave, m_compositor);
+ command.parameters << QVariant::fromValue(surface);
+ command.parameters << QVariant::fromValue(output);
+ processCommand(command);
+}
+
void MockCompositor::waitForStartDrag()
{
Command command = makeCommand(Impl::Compositor::waitForStartDrag, m_compositor);
@@ -202,6 +234,15 @@ QSharedPointer<MockSurface> MockCompositor::surface()
return result;
}
+QSharedPointer<MockOutput> MockCompositor::output(int index)
+{
+ QSharedPointer<MockOutput> result;
+ lock();
+ result = m_compositor->outputs().at(index)->mockOutput();
+ unlock();
+ return result;
+}
+
MockCompositor::Command MockCompositor::makeCommand(Command::Callback callback, void *target)
{
Command command;
@@ -264,11 +305,7 @@ namespace Impl {
Compositor::Compositor()
: m_display(wl_display_create())
- , m_startDragSeen(false)
- , m_time(0)
{
- wl_list_init(&m_outputResources);
-
if (wl_display_add_socket(m_display, 0)) {
fprintf(stderr, "Fatal: Failed to open server socket\n");
exit(EXIT_FAILURE);
@@ -285,8 +322,9 @@ Compositor::Compositor()
m_keyboard = m_seat->keyboard();
m_touch = m_seat->touch();
- wl_global_create(m_display, &wl_output_interface, 1, this, bindOutput);
+ m_outputs.append(new Output(m_display, QSize(1920, 1080), QPoint(0, 0)));
wl_global_create(m_display, &wl_shell_interface, 1, this, bindShell);
+ wl_global_create(m_display, &zxdg_shell_v6_interface, 1, this, bindXdgShellV6);
m_loop = wl_display_get_event_loop(m_display);
m_fd = wl_event_loop_get_fd(m_loop);
@@ -349,6 +387,11 @@ QVector<Surface *> Compositor::surfaces() const
return m_surfaces;
}
+QVector<Output *> Compositor::outputs() const
+{
+ return m_outputs;
+}
+
uint32_t Compositor::nextSerial()
{
return wl_display_next_serial(m_display);
@@ -366,5 +409,17 @@ void Compositor::removeSurface(Surface *surface)
m_pointer->handleSurfaceDestroyed(surface);
}
+Surface *Compositor::resolveSurface(const QVariant &v)
+{
+ QSharedPointer<MockSurface> mockSurface = v.value<QSharedPointer<MockSurface> >();
+ return mockSurface ? mockSurface->handle() : nullptr;
+}
+
+Output *Compositor::resolveOutput(const QVariant &v)
+{
+ QSharedPointer<MockOutput> mockOutput = v.value<QSharedPointer<MockOutput> >();
+ return mockOutput ? mockOutput->handle() : nullptr;
+}
+
}
diff --git a/tests/auto/client/client/mockcompositor.h b/tests/auto/client/shared/mockcompositor.h
index dd6450fc9..9258b1926 100644
--- a/tests/auto/client/client/mockcompositor.h
+++ b/tests/auto/client/shared/mockcompositor.h
@@ -51,6 +51,7 @@ class Touch;
class Seat;
class DataDeviceManager;
class Surface;
+class Output;
class Compositor
{
@@ -64,9 +65,8 @@ public:
uint32_t nextSerial();
uint32_t time() { return ++m_time; }
- static void setOutputGeometry(void *compositor, const QList<QVariant> &parameters);
-
QVector<Surface *> surfaces() const;
+ QVector<Output *> outputs() const;
void addSurface(Surface *surface);
void removeSurface(Surface *surface);
@@ -86,36 +86,40 @@ public:
static void sendDataDeviceDrop(void *data, const QList<QVariant> &parameters);
static void sendDataDeviceLeave(void *data, const QList<QVariant> &parameters);
static void waitForStartDrag(void *data, const QList<QVariant> &parameters);
+ static void setOutputMode(void *compositor, const QList<QVariant> &parameters);
+ static void sendAddOutput(void *data, const QList<QVariant> &parameters);
+ static void sendRemoveOutput(void *data, const QList<QVariant> &parameters);
+ static void sendSurfaceEnter(void *data, const QList<QVariant> &parameters);
+ static void sendSurfaceLeave(void *data, const QList<QVariant> &parameters);
public:
- bool m_startDragSeen;
+ bool m_startDragSeen = false;
private:
static void bindCompositor(wl_client *client, void *data, uint32_t version, uint32_t id);
- static void bindOutput(wl_client *client, void *data, uint32_t version, uint32_t id);
static void bindShell(wl_client *client, void *data, uint32_t version, uint32_t id);
+ static void bindXdgShellV6(wl_client *client, void *compositorData, uint32_t version, uint32_t id);
+ static Surface *resolveSurface(const QVariant &v);
+ static Output *resolveOutput(const QVariant &v);
void initShm();
- void sendOutputGeometry(wl_resource *resource);
- void sendOutputMode(wl_resource *resource);
-
QRect m_outputGeometry;
- wl_display *m_display;
- wl_event_loop *m_loop;
- wl_shm *m_shm;
- int m_fd;
+ wl_display *m_display = nullptr;
+ wl_event_loop *m_loop = nullptr;
+ wl_shm *m_shm = nullptr;
+ int m_fd = -1;
- wl_list m_outputResources;
- uint32_t m_time;
+ uint32_t m_time = 0;
QScopedPointer<Seat> m_seat;
- Pointer *m_pointer;
- Keyboard *m_keyboard;
- Touch *m_touch;
+ Pointer *m_pointer = nullptr;
+ Keyboard *m_keyboard = nullptr;
+ Touch *m_touch = nullptr;
QScopedPointer<DataDeviceManager> m_data_device_manager;
QVector<Surface *> m_surfaces;
+ QVector<Output *> m_outputs;
};
void registerResource(wl_list *list, wl_resource *resource);
@@ -139,6 +143,16 @@ private:
Q_DECLARE_METATYPE(QSharedPointer<MockSurface>)
+class MockOutput {
+public:
+ Impl::Output *handle() const { return m_output; }
+ MockOutput(Impl::Output *output);
+private:
+ Impl::Output *m_output;
+};
+
+Q_DECLARE_METATYPE(QSharedPointer<MockOutput>)
+
class MockCompositor
{
public:
@@ -150,7 +164,7 @@ public:
int waylandFileDescriptor() const;
void processWaylandEvents();
- void setOutputGeometry(const QRect &rect);
+ void setOutputMode(const QSize &size);
void setKeyboardFocus(const QSharedPointer<MockSurface> &surface);
void sendMousePress(const QSharedPointer<MockSurface> &surface, const QPoint &pos);
void sendMouseRelease(const QSharedPointer<MockSurface> &surface);
@@ -165,9 +179,14 @@ public:
void sendDataDeviceMotion(const QPoint &position);
void sendDataDeviceDrop(const QSharedPointer<MockSurface> &surface);
void sendDataDeviceLeave(const QSharedPointer<MockSurface> &surface);
+ void sendAddOutput();
+ void sendRemoveOutput(const QSharedPointer<MockOutput> &output);
+ void sendSurfaceEnter(const QSharedPointer<MockSurface> &surface, QSharedPointer<MockOutput> &output);
+ void sendSurfaceLeave(const QSharedPointer<MockSurface> &surface, QSharedPointer<MockOutput> &output);
void waitForStartDrag();
QSharedPointer<MockSurface> surface();
+ QSharedPointer<MockOutput> output(int index = 0);
void lock();
void unlock();
diff --git a/tests/auto/client/client/mockinput.cpp b/tests/auto/client/shared/mockinput.cpp
index b2bcdf2e6..9cea85b6d 100644
--- a/tests/auto/client/client/mockinput.cpp
+++ b/tests/auto/client/shared/mockinput.cpp
@@ -32,12 +32,6 @@
namespace Impl {
-static Surface *resolveSurface(const QVariant &v)
-{
- QSharedPointer<MockSurface> mockSurface = v.value<QSharedPointer<MockSurface> >();
- return mockSurface ? mockSurface->handle() : 0;
-}
-
void Compositor::setKeyboardFocus(void *data, const QList<QVariant> &parameters)
{
Compositor *compositor = static_cast<Compositor *>(data);
@@ -194,6 +188,7 @@ void Compositor::sendDataDeviceLeave(void *data, const QList<QVariant> &paramete
void Compositor::waitForStartDrag(void *data, const QList<QVariant> &parameters)
{
+ Q_UNUSED(parameters);
Compositor *compositor = static_cast<Compositor *>(data);
Q_ASSERT(compositor);
while (!compositor->m_startDragSeen) {
@@ -239,8 +234,8 @@ void Seat::seat_get_touch(Resource *resource, uint32_t id)
Keyboard::Keyboard(Compositor *compositor)
: wl_keyboard()
, m_compositor(compositor)
- , m_focusResource(Q_NULLPTR)
- , m_focus(Q_NULLPTR)
+ , m_focusResource(nullptr)
+ , m_focus(nullptr)
{
}
@@ -293,8 +288,8 @@ void Keyboard::keyboard_destroy_resource(wl_keyboard::Resource *resource)
Pointer::Pointer(Compositor *compositor)
: wl_pointer()
, m_compositor(compositor)
- , m_focusResource(Q_NULLPTR)
- , m_focus(Q_NULLPTR)
+ , m_focusResource(nullptr)
+ , m_focus(nullptr)
{
}
@@ -447,6 +442,11 @@ DataDevice::~DataDevice()
void DataDevice::data_device_start_drag(QtWaylandServer::wl_data_device::Resource *resource, wl_resource *source, wl_resource *origin, wl_resource *icon, uint32_t serial)
{
+ Q_UNUSED(resource);
+ Q_UNUSED(source);
+ Q_UNUSED(origin);
+ Q_UNUSED(icon);
+ Q_UNUSED(serial);
m_compositor->m_startDragSeen = true;
}
@@ -469,6 +469,7 @@ DataDevice *DataDeviceManager::dataDevice() const
void DataDeviceManager::data_device_manager_get_data_device(Resource *resource, uint32_t id, struct ::wl_resource *seat)
{
+ Q_UNUSED(seat);
if (!m_data_device)
m_data_device.reset(new DataDevice(m_compositor));
m_data_device->add(resource->client(), id, 1);
diff --git a/tests/auto/client/client/mockinput.h b/tests/auto/client/shared/mockinput.h
index 9c217b6ac..9c217b6ac 100644
--- a/tests/auto/client/client/mockinput.h
+++ b/tests/auto/client/shared/mockinput.h
diff --git a/tests/auto/client/shared/mockoutput.cpp b/tests/auto/client/shared/mockoutput.cpp
new file mode 100644
index 000000000..7d7b7413a
--- /dev/null
+++ b/tests/auto/client/shared/mockoutput.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mockcompositor.h"
+#include "mockoutput.h"
+
+#include <QDebug>
+
+namespace Impl {
+
+void Compositor::sendAddOutput(void *data, const QList<QVariant> &parameters) {
+ Q_UNUSED(parameters);
+ Compositor *compositor = static_cast<Compositor *>(data);
+ auto output = new Output(compositor->m_display, QSize(1920, 1200), QPoint(0, 0));
+ compositor->m_outputs.append(output);
+
+ // Wait for the client to bind to the output
+ while (output->resourceMap().isEmpty())
+ compositor->dispatchEvents();
+}
+
+void Compositor::sendRemoveOutput(void *data, const QList<QVariant> &parameters) {
+ Compositor *compositor = static_cast<Compositor *>(data);
+ Q_ASSERT(compositor);
+ Output *output = resolveOutput(parameters.first());
+ Q_ASSERT(output);
+ bool wasRemoved = compositor->m_outputs.removeOne(output);
+ Q_ASSERT(wasRemoved);
+ delete output;
+}
+
+void Compositor::setOutputMode(void *data, const QList<QVariant> &parameters)
+{
+ Compositor *compositor = static_cast<Compositor *>(data);
+ QSize size = parameters.first().toSize();
+ Output *output = compositor->m_outputs.first();
+ Q_ASSERT(output);
+ output->setCurrentMode(size);
+}
+
+Output::Output(wl_display *display, const QSize &resolution, const QPoint &position)
+ : wl_output(display, 2)
+ , m_size(resolution)
+ , m_position(position)
+ , m_physicalSize(520, 320)
+ , m_mockOutput(new MockOutput(this))
+{
+}
+
+void Output::setCurrentMode(const QSize &size)
+{
+ qDebug() << Q_FUNC_INFO << size;
+ m_size = size;
+ for (Resource *resource : resourceMap())
+ sendCurrentMode(resource);
+}
+
+void Output::output_bind_resource(QtWaylandServer::wl_output::Resource *resource)
+{
+ sendGeometry(resource);
+ sendCurrentMode(resource);
+}
+
+void Output::sendGeometry(Resource *resource)
+{
+ const int subPixel = 0;
+ const int transform = 0;
+
+ send_geometry(resource->handle,
+ m_position.x(), m_position.y(),
+ m_physicalSize.width(), m_physicalSize.height(),
+ subPixel, "", "", transform );
+}
+
+void Output::sendCurrentMode(Resource *resource)
+{
+ send_mode(resource->handle,
+ WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED,
+ m_size.width(), m_size.height(), 60000);
+}
+
+} // Impl
+
+MockOutput::MockOutput(Impl::Output *output)
+ : m_output(output)
+{
+}
diff --git a/tests/auto/client/client/mockoutput.cpp b/tests/auto/client/shared/mockoutput.h
index 86561976f..d5a2bb56b 100644
--- a/tests/auto/client/client/mockoutput.cpp
+++ b/tests/auto/client/shared/mockoutput.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
@@ -26,42 +26,37 @@
**
****************************************************************************/
-#include "mockcompositor.h"
+#ifndef MOCKOUTPUT_H
+#define MOCKOUTPUT_H
-namespace Impl {
+#include <qglobal.h>
-void Compositor::bindOutput(wl_client *client, void *compositorData, uint32_t version, uint32_t id)
-{
- wl_resource *resource = wl_resource_create(client, &wl_output_interface, static_cast<int>(version), id);
+#include "qwayland-server-wayland.h"
- Compositor *compositor = static_cast<Compositor *>(compositorData);
- registerResource(&compositor->m_outputResources, resource);
+#include "mockcompositor.h"
- compositor->sendOutputGeometry(resource);
- compositor->sendOutputMode(resource);
-}
+namespace Impl {
-void Compositor::sendOutputGeometry(wl_resource *resource)
+class Output : public QtWaylandServer::wl_output
{
- const QRect &r = m_outputGeometry;
- wl_output_send_geometry(resource, r.x(), r.y(), r.width(), r.height(), 0, "", "",0);
-}
+public:
+ Output(::wl_display *display, const QSize &resolution, const QPoint &position);
-void Compositor::sendOutputMode(wl_resource *resource)
-{
- const QRect &r = m_outputGeometry;
- wl_output_send_mode(resource, WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED, r.width(), r.height(), 60);
-}
+ QSharedPointer<MockOutput> mockOutput() const { return m_mockOutput; }
+ void setCurrentMode(const QSize &size);
-void Compositor::setOutputGeometry(void *c, const QList<QVariant> &parameters)
-{
- Compositor *compositor = static_cast<Compositor *>(c);
- compositor->m_outputGeometry = parameters.first().toRect();
+protected:
+ void output_bind_resource(Resource *resource) override;
- wl_resource *resource;
- wl_list_for_each(resource, &compositor->m_outputResources, link)
- compositor->sendOutputGeometry(resource);
-}
+private:
+ void sendGeometry(Resource *resource);
+ void sendCurrentMode(Resource *resource);
+ QSize m_size;
+ QPoint m_position;
+ const QSize m_physicalSize;
+ QSharedPointer<MockOutput> m_mockOutput;
+};
}
+#endif // MOCKOUTPUT_H
diff --git a/tests/auto/client/client/mockshell.cpp b/tests/auto/client/shared/mockshell.cpp
index d5eede22e..d5eede22e 100644
--- a/tests/auto/client/client/mockshell.cpp
+++ b/tests/auto/client/shared/mockshell.cpp
diff --git a/tests/auto/client/client/mocksurface.cpp b/tests/auto/client/shared/mocksurface.cpp
index 55712af11..7aa2a00b2 100644
--- a/tests/auto/client/client/mocksurface.cpp
+++ b/tests/auto/client/shared/mocksurface.cpp
@@ -27,13 +27,42 @@
****************************************************************************/
#include "mocksurface.h"
+#include "mockoutput.h"
#include "mockcompositor.h"
namespace Impl {
+void Compositor::sendSurfaceEnter(void *data, const QList<QVariant> &parameters)
+{
+ Q_UNUSED(data);
+ Surface *surface = resolveSurface(parameters.at(0));
+ Output *output = resolveOutput(parameters.at(1));
+ Q_ASSERT(surface && surface->resource());
+ Q_ASSERT(output);
+ auto outputResources = output->resourceMap().values(surface->resource()->client());
+ Q_ASSERT(!outputResources.isEmpty());
+
+ for (auto outputResource : outputResources)
+ surface->send_enter(outputResource->handle);
+}
+
+void Compositor::sendSurfaceLeave(void *data, const QList<QVariant> &parameters)
+{
+ Q_UNUSED(data);
+ Surface *surface = resolveSurface(parameters.at(0));
+ Output *output = resolveOutput(parameters.at(1));
+ Q_ASSERT(surface && surface->resource());
+ Q_ASSERT(output);
+ auto outputResources = output->resourceMap().values(surface->resource()->client());
+ Q_ASSERT(!outputResources.isEmpty());
+
+ for (auto outputResource : outputResources)
+ surface->send_leave(outputResource->handle);
+}
+
Surface::Surface(wl_client *client, uint32_t id, int v, Compositor *compositor)
: QtWaylandServer::wl_surface(client, id, v)
- , m_buffer(Q_NULLPTR)
+ , m_buffer(nullptr)
, m_compositor(compositor)
, m_mockSurface(new MockSurface(this))
, m_mapped(false)
diff --git a/tests/auto/client/client/mocksurface.h b/tests/auto/client/shared/mocksurface.h
index 5155599bb..5155599bb 100644
--- a/tests/auto/client/client/mocksurface.h
+++ b/tests/auto/client/shared/mocksurface.h
diff --git a/tests/auto/client/shared/mockxdgshellv6.cpp b/tests/auto/client/shared/mockxdgshellv6.cpp
new file mode 100644
index 000000000..b26ac1c8d
--- /dev/null
+++ b/tests/auto/client/shared/mockxdgshellv6.cpp
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mockcompositor.h"
+#include "mocksurface.h"
+
+#include <qwayland-server-xdg-shell-unstable-v6.h>
+
+namespace Impl {
+
+class XdgSurfaceV6;
+
+class XdgToplevelV6 : public QtWaylandServer::zxdg_toplevel_v6
+{
+public:
+ XdgToplevelV6(XdgSurfaceV6 *xdgSurface, wl_client *client, uint32_t id, int version)
+ : QtWaylandServer::zxdg_toplevel_v6(client, id, version)
+ , m_xdgSurface(xdgSurface)
+ {}
+ void zxdg_toplevel_v6_destroy_resource(Resource *) override { delete this; }
+ void zxdg_toplevel_v6_destroy(Resource *resource) override;
+ XdgSurfaceV6 *m_xdgSurface = nullptr;
+};
+
+class XdgSurfaceV6 : public QtWaylandServer::zxdg_surface_v6
+{
+public:
+ XdgSurfaceV6(wl_client *client, uint32_t id, int version, Surface *surface);
+ void zxdg_surface_v6_destroy_resource(Resource *) override { delete this; }
+ void zxdg_surface_v6_get_toplevel(Resource *resource, uint32_t id) override;
+ void zxdg_surface_v6_destroy(Resource *resource) override
+ {
+ Q_ASSERT(!m_toplevel);
+ wl_resource_destroy(resource->handle);
+ }
+ Surface *m_surface = nullptr;
+ XdgToplevelV6 *m_toplevel = nullptr;
+};
+
+void XdgToplevelV6::zxdg_toplevel_v6_destroy(QtWaylandServer::zxdg_toplevel_v6::Resource *resource)
+{
+ m_xdgSurface->m_toplevel = nullptr;
+ wl_resource_destroy(resource->handle);
+}
+
+XdgSurfaceV6::XdgSurfaceV6(wl_client *client, uint32_t id, int version, Surface *surface)
+ : QtWaylandServer::zxdg_surface_v6(client, id, version)
+ , m_surface(surface)
+{
+}
+
+void XdgSurfaceV6::zxdg_surface_v6_get_toplevel(QtWaylandServer::zxdg_surface_v6::Resource *resource, uint32_t id)
+{
+ int version = wl_resource_get_version(resource->handle);
+ m_toplevel = new XdgToplevelV6(this, resource->client(), id, version);
+ m_surface->map();
+}
+
+
+void shell_destroy(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ Q_UNUSED(client);
+ Q_UNUSED(resource);
+}
+
+void create_positioner(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t id)
+{
+ Q_UNUSED(client);
+ Q_UNUSED(resource);
+ Q_UNUSED(id);
+}
+
+void get_xdg_surface(struct wl_client *client,
+ struct wl_resource *compositorResource,
+ uint32_t id,
+ struct wl_resource *surfaceResource)
+{
+ int version = wl_resource_get_version(compositorResource);
+ new XdgSurfaceV6(client, id, version, Surface::fromResource(surfaceResource));
+}
+
+void pong(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t serial)
+{
+ Q_UNUSED(client);
+ Q_UNUSED(resource);
+ Q_UNUSED(serial);
+}
+
+void Compositor::bindXdgShellV6(wl_client *client, void *compositorData, uint32_t version, uint32_t id)
+{
+ static const struct zxdg_shell_v6_interface shellInterface = {
+ shell_destroy,
+ create_positioner,
+ get_xdg_surface,
+ pong
+ };
+
+ wl_resource *resource = wl_resource_create(client, &zxdg_shell_v6_interface, static_cast<int>(version), id);
+ wl_resource_set_implementation(resource, &shellInterface, compositorData, nullptr);
+}
+
+}
diff --git a/tests/auto/client/shared/shared.pri b/tests/auto/client/shared/shared.pri
new file mode 100644
index 000000000..608664bb7
--- /dev/null
+++ b/tests/auto/client/shared/shared.pri
@@ -0,0 +1,26 @@
+CONFIG += testcase link_pkgconfig
+QT += testlib
+QT += core-private gui-private waylandclient-private
+
+QMAKE_USE += wayland-client wayland-server
+
+CONFIG += wayland-scanner
+WAYLANDSERVERSOURCES += \
+ ../../../../src/3rdparty/protocol/wayland.xml \
+ ../../../../src/3rdparty/protocol/xdg-shell-unstable-v6.xml
+
+INCLUDEPATH += ../shared
+
+SOURCES += \
+ ../shared/mockcompositor.cpp \
+ ../shared/mockinput.cpp \
+ ../shared/mockshell.cpp \
+ ../shared/mockxdgshellv6.cpp \
+ ../shared/mocksurface.cpp \
+ ../shared/mockoutput.cpp
+
+HEADERS += \
+ ../shared/mockcompositor.h \
+ ../shared/mockinput.h \
+ ../shared/mocksurface.h \
+ ../shared/mockoutput.h
diff --git a/tests/auto/client/xdgshellv6/tst_xdgshellv6.cpp b/tests/auto/client/xdgshellv6/tst_xdgshellv6.cpp
new file mode 100644
index 000000000..5aac336f2
--- /dev/null
+++ b/tests/auto/client/xdgshellv6/tst_xdgshellv6.cpp
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mockcompositor.h"
+
+#include <QBackingStore>
+#include <QPainter>
+#include <QScreen>
+#include <QWindow>
+#include <QMimeData>
+#include <QPixmap>
+#include <QDrag>
+
+#include <QtTest/QtTest>
+
+static const QSize screenSize(1600, 1200);
+
+class TestWindow : public QWindow
+{
+public:
+ TestWindow()
+ {
+ setSurfaceType(QSurface::RasterSurface);
+ setGeometry(0, 0, 32, 32);
+ create();
+ }
+};
+
+class tst_WaylandClientXdgShellV6 : public QObject
+{
+ Q_OBJECT
+public:
+ tst_WaylandClientXdgShellV6(MockCompositor *c)
+ : m_compositor(c)
+ {
+ QSocketNotifier *notifier = new QSocketNotifier(m_compositor->waylandFileDescriptor(), QSocketNotifier::Read, this);
+ connect(notifier, &QSocketNotifier::activated, this, &tst_WaylandClientXdgShellV6::processWaylandEvents);
+ // connect to the event dispatcher to make sure to flush out the outgoing message queue
+ connect(QCoreApplication::eventDispatcher(), &QAbstractEventDispatcher::awake, this, &tst_WaylandClientXdgShellV6::processWaylandEvents);
+ connect(QCoreApplication::eventDispatcher(), &QAbstractEventDispatcher::aboutToBlock, this, &tst_WaylandClientXdgShellV6::processWaylandEvents);
+ }
+
+public slots:
+ void processWaylandEvents()
+ {
+ m_compositor->processWaylandEvents();
+ }
+
+ void cleanup()
+ {
+ // make sure the surfaces from the last test are properly cleaned up
+ // and don't show up as false positives in the next test
+ QTRY_VERIFY(!m_compositor->surface());
+ }
+
+private slots:
+ void createDestroyWindow();
+
+private:
+ MockCompositor *m_compositor;
+};
+
+void tst_WaylandClientXdgShellV6::createDestroyWindow()
+{
+ TestWindow window;
+ window.show();
+
+ QTRY_VERIFY(m_compositor->surface());
+
+ window.destroy();
+ QTRY_VERIFY(!m_compositor->surface());
+}
+
+int main(int argc, char **argv)
+{
+ setenv("XDG_RUNTIME_DIR", ".", 1);
+ setenv("QT_QPA_PLATFORM", "wayland", 1); // force QGuiApplication to use wayland plugin
+ setenv("QT_WAYLAND_SHELL_INTEGRATION", "xdg-shell-v6", 1);
+
+ // wayland-egl hangs in the test setup when we try to initialize. Until it gets
+ // figured out, avoid clientBufferIntegration() from being called in
+ // QWaylandWindow::createDecorations().
+ setenv("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1", 1);
+
+ MockCompositor compositor;
+ compositor.setOutputMode(screenSize);
+
+ QGuiApplication app(argc, argv);
+ compositor.applicationInitialized();
+
+ tst_WaylandClientXdgShellV6 tc(&compositor);
+ return QTest::qExec(&tc, argc, argv);
+}
+
+#include <tst_xdgshellv6.moc>
diff --git a/tests/auto/client/xdgshellv6/xdgshellv6.pro b/tests/auto/client/xdgshellv6/xdgshellv6.pro
new file mode 100644
index 000000000..4fec593df
--- /dev/null
+++ b/tests/auto/client/xdgshellv6/xdgshellv6.pro
@@ -0,0 +1,5 @@
+include (../shared/shared.pri)
+
+TARGET = tst_client_xdgshellv6
+SOURCES += tst_xdgshellv6.cpp
+
diff --git a/tests/auto/cmake/test_waylandclient/main.cpp b/tests/auto/cmake/test_waylandclient/main.cpp
index f0ccdef4b..33f4470bb 100644
--- a/tests/auto/cmake/test_waylandclient/main.cpp
+++ b/tests/auto/cmake/test_waylandclient/main.cpp
@@ -3,5 +3,5 @@
int main()
{
// use symbol
- QtWaylandClient::QWaylandCursor cursor(Q_NULLPTR);
+ QtWaylandClient::QWaylandCursor cursor(nullptr);
}
diff --git a/tests/auto/compositor/compositor/mockclient.cpp b/tests/auto/compositor/compositor/mockclient.cpp
index da1096fb9..bdc2b3b93 100644
--- a/tests/auto/compositor/compositor/mockclient.cpp
+++ b/tests/auto/compositor/compositor/mockclient.cpp
@@ -41,13 +41,13 @@
#include <sys/mman.h>
const struct wl_registry_listener MockClient::registryListener = {
- MockClient::handleGlobal
+ MockClient::handleGlobal,
+ MockClient::handleGlobalRemove
};
MockClient::MockClient()
: display(wl_display_connect("wayland-qt-test-0"))
, compositor(0)
- , output(0)
, registry(0)
, wlshell(0)
, xdgShell(nullptr)
@@ -74,9 +74,9 @@ MockClient::MockClient()
timeout.start();
do {
QCoreApplication::processEvents();
- } while (!(compositor && output) && timeout.elapsed() < 1000);
+ } while (!(compositor && !m_outputs.isEmpty()) && timeout.elapsed() < 1000);
- if (!compositor || !output)
+ if (!compositor || m_outputs.empty())
qFatal("MockClient(): failed to receive globals from display");
}
@@ -165,12 +165,19 @@ void MockClient::handleGlobal(void *data, wl_registry *registry, uint32_t id, co
resolve(data)->handleGlobal(id, QByteArray(interface));
}
+void MockClient::handleGlobalRemove(void *data, wl_registry *wl_registry, uint32_t id)
+{
+ Q_UNUSED(wl_registry);
+ resolve(data)->handleGlobalRemove(id);
+}
+
void MockClient::handleGlobal(uint32_t id, const QByteArray &interface)
{
if (interface == "wl_compositor") {
compositor = static_cast<wl_compositor *>(wl_registry_bind(registry, id, &wl_compositor_interface, 1));
} else if (interface == "wl_output") {
- output = static_cast<wl_output *>(wl_registry_bind(registry, id, &wl_output_interface, 2));
+ auto output = static_cast<wl_output *>(wl_registry_bind(registry, id, &wl_output_interface, 2));
+ m_outputs.insert(id, output);
wl_output_add_listener(output, &outputListener, this);
} else if (interface == "wl_shm") {
shm = static_cast<wl_shm *>(wl_registry_bind(registry, id, &wl_shm_interface, 1));
@@ -186,6 +193,11 @@ void MockClient::handleGlobal(uint32_t id, const QByteArray &interface)
}
}
+void MockClient::handleGlobalRemove(uint32_t id)
+{
+ m_outputs.remove(id);
+}
+
wl_surface *MockClient::createSurface()
{
flushDisplay();
@@ -248,7 +260,7 @@ ShmBuffer::ShmBuffer(const QSize &size, wl_shm *shm)
ShmBuffer::~ShmBuffer()
{
- munmap(image.bits(), image.byteCount());
+ munmap(image.bits(), image.sizeInBytes());
wl_buffer_destroy(handle);
wl_shm_pool_destroy(shm_pool);
}
diff --git a/tests/auto/compositor/compositor/mockclient.h b/tests/auto/compositor/compositor/mockclient.h
index 1881393a6..dd50f9a28 100644
--- a/tests/auto/compositor/compositor/mockclient.h
+++ b/tests/auto/compositor/compositor/mockclient.h
@@ -64,7 +64,7 @@ public:
wl_display *display;
wl_compositor *compositor;
- wl_output *output;
+ QMap<uint, wl_output *> m_outputs;
wl_shm *shm;
wl_registry *registry;
wl_shell *wlshell;
@@ -96,6 +96,7 @@ private:
static MockClient *resolve(void *data) { return static_cast<MockClient *>(data); }
static const struct wl_registry_listener registryListener;
static void handleGlobal(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version);
+ static void handleGlobalRemove(void *data, struct wl_registry *wl_registry, uint32_t id);
static int sourceUpdate(uint32_t mask, void *data);
static void outputGeometryEvent(void *data,
@@ -117,6 +118,7 @@ private:
static void outputScale(void *data, wl_output *output, int factor);
void handleGlobal(uint32_t id, const QByteArray &interface);
+ void handleGlobalRemove(uint32_t id);
static const wl_output_listener outputListener;
};
diff --git a/tests/auto/compositor/compositor/testcompositor.cpp b/tests/auto/compositor/compositor/testcompositor.cpp
index 733bea5b3..f91d0d3f1 100644
--- a/tests/auto/compositor/compositor/testcompositor.cpp
+++ b/tests/auto/compositor/compositor/testcompositor.cpp
@@ -42,7 +42,7 @@ TestCompositor::TestCompositor(bool createInputDev)
void TestCompositor::create()
{
- new QWaylandOutput(this, Q_NULLPTR);
+ new QWaylandOutput(this, nullptr);
QWaylandCompositor::create();
connect(this, &QWaylandCompositor::surfaceCreated, this, &TestCompositor::onSurfaceCreated);
diff --git a/tests/auto/compositor/compositor/tst_compositor.cpp b/tests/auto/compositor/compositor/tst_compositor.cpp
index c51c13bd6..96095a0d4 100644
--- a/tests/auto/compositor/compositor/tst_compositor.cpp
+++ b/tests/auto/compositor/compositor/tst_compositor.cpp
@@ -67,6 +67,7 @@ private slots:
void sizeFollowsWindow();
void mapSurface();
void frameCallback();
+ void removeOutput();
void advertisesXdgShellSupport();
void createsXdgSurfaces();
@@ -201,7 +202,7 @@ void tst_WaylandCompositor::keyboardGrab()
QTRY_COMPARE(grabKeyReleaseSpy.count(), 2);
// Stop grabbing
- seat->setKeyboardFocus(Q_NULLPTR);
+ seat->setKeyboardFocus(nullptr);
seat->sendFullKeyEvent(&ke);
seat->sendFullKeyEvent(&ke1);
QTRY_COMPARE(grabKeyPressSpy.count(), 2);
@@ -378,6 +379,22 @@ void tst_WaylandCompositor::frameCallback()
wl_surface_destroy(surface);
}
+void tst_WaylandCompositor::removeOutput()
+{
+ TestCompositor compositor;
+ QWindow window;
+ window.resize(800, 600);
+ auto output = new QWaylandOutput(&compositor, &window);
+
+ compositor.create();
+ MockClient client;
+ QTRY_COMPARE(client.m_outputs.size(), 2);
+
+ delete output;
+ compositor.flushClients();
+ QTRY_COMPARE(client.m_outputs.size(), 1);
+}
+
void tst_WaylandCompositor::seatCapabilities()
{
TestCompositor compositor;