summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorJohan Klokkhammer Helsing <johan.helsing@qt.io>2017-08-18 17:28:01 +0200
committerJohan Helsing <johan.helsing@qt.io>2017-11-15 08:34:27 +0000
commit69d587b9a8e336cff4356c49e4f37aae2a474a4f (patch)
treecd53978cb4c7ea0b8933034e04b600d0f41e3c41 /tests
parent9cf680f94b78baf1bb92051021ebc243dec1f02e (diff)
Client: Test that the current screen is updated by surface events
Change-Id: If96691a2d844263a1e01a86df8b0d58f23848a4c Reviewed-by: Pier Luigi Fiorini <pierluigi.fiorini@liri.io>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/client/client/tst_client.cpp45
-rw-r--r--tests/auto/client/shared/mockcompositor.cpp59
-rw-r--r--tests/auto/client/shared/mockcompositor.h32
-rw-r--r--tests/auto/client/shared/mockinput.cpp6
-rw-r--r--tests/auto/client/shared/mockoutput.cpp73
-rw-r--r--tests/auto/client/shared/mockoutput.h62
-rw-r--r--tests/auto/client/shared/mocksurface.cpp29
-rw-r--r--tests/auto/client/shared/shared.pri3
-rw-r--r--tests/auto/client/xdgshellv6/tst_xdgshellv6.cpp2
9 files changed, 267 insertions, 44 deletions
diff --git a/tests/auto/client/client/tst_client.cpp b/tests/auto/client/client/tst_client.cpp
index f337e6b4a..b4dc75131 100644
--- a/tests/auto/client/client/tst_client.cpp
+++ b/tests/auto/client/client/tst_client.cpp
@@ -137,7 +137,8 @@ public slots:
}
private slots:
- void screen();
+ void primaryScreen();
+ void windowScreens();
void createDestroyWindow();
void events();
void backingStore();
@@ -151,11 +152,49 @@ private:
MockCompositor *compositor;
};
-void tst_WaylandClient::screen()
+void tst_WaylandClient::primaryScreen()
{
+ compositor->setOutputMode(screenSize);
QTRY_COMPARE(QGuiApplication::primaryScreen()->size(), screenSize);
}
+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);
+
+ window.destroy();
+ QTRY_VERIFY(!compositor->surface());
+}
+
void tst_WaylandClient::createDestroyWindow()
{
TestWindow window;
@@ -417,7 +456,7 @@ int main(int argc, char **argv)
setenv("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1", 1);
MockCompositor compositor;
- compositor.setOutputGeometry(QRect(QPoint(), screenSize));
+ compositor.setOutputMode(screenSize);
QGuiApplication app(argc, argv);
compositor.applicationInitialized();
diff --git a/tests/auto/client/shared/mockcompositor.cpp b/tests/auto/client/shared/mockcompositor.cpp
index 411a89757..67c05b90a 100644
--- a/tests/auto/client/shared/mockcompositor.cpp
+++ b/tests/auto/client/shared/mockcompositor.cpp
@@ -28,6 +28,7 @@
#include "mockcompositor.h"
#include "mockinput.h"
+#include "mockoutput.h"
#include "mocksurface.h"
#include <wayland-xdg-shell-unstable-v6-server-protocol.h>
@@ -77,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);
}
@@ -182,6 +183,28 @@ void MockCompositor::sendDataDeviceLeave(const QSharedPointer<MockSurface> &surf
processCommand(command);
}
+void MockCompositor::sendAddOutput()
+{
+ Command command = makeCommand(Impl::Compositor::sendAddOutput, m_compositor);
+ 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);
@@ -204,6 +227,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;
@@ -267,8 +299,6 @@ namespace Impl {
Compositor::Compositor()
: m_display(wl_display_create())
{
- 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,7 +315,7 @@ 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);
@@ -350,6 +380,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);
@@ -367,5 +402,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/shared/mockcompositor.h b/tests/auto/client/shared/mockcompositor.h
index a304b3792..54706bd83 100644
--- a/tests/auto/client/shared/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,21 +86,23 @@ 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 sendSurfaceEnter(void *data, const QList<QVariant> &parameters);
+ static void sendSurfaceLeave(void *data, const QList<QVariant> &parameters);
public:
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 = nullptr;
@@ -108,7 +110,6 @@ private:
wl_shm *m_shm = nullptr;
int m_fd = -1;
- wl_list m_outputResources;
uint32_t m_time = 0;
QScopedPointer<Seat> m_seat;
@@ -117,6 +118,7 @@ private:
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);
@@ -140,6 +142,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:
@@ -151,7 +163,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);
@@ -166,9 +178,13 @@ public:
void sendDataDeviceMotion(const QPoint &position);
void sendDataDeviceDrop(const QSharedPointer<MockSurface> &surface);
void sendDataDeviceLeave(const QSharedPointer<MockSurface> &surface);
+ void sendAddOutput();
+ 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/shared/mockinput.cpp b/tests/auto/client/shared/mockinput.cpp
index 9e5689210..3e7b294b4 100644
--- a/tests/auto/client/shared/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);
diff --git a/tests/auto/client/shared/mockoutput.cpp b/tests/auto/client/shared/mockoutput.cpp
index 86561976f..de8e019ad 100644
--- a/tests/auto/client/shared/mockoutput.cpp
+++ b/tests/auto/client/shared/mockoutput.cpp
@@ -27,41 +27,76 @@
****************************************************************************/
#include "mockcompositor.h"
+#include "mockoutput.h"
+
+#include <QDebug>
namespace Impl {
-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);
+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);
- Compositor *compositor = static_cast<Compositor *>(compositorData);
- registerResource(&compositor->m_outputResources, resource);
+ // Wait for the client to bind to the output
+ while (output->resourceMap().isEmpty())
+ compositor->dispatchEvents();
+}
- compositor->sendOutputGeometry(resource);
- compositor->sendOutputMode(resource);
+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);
}
-void Compositor::sendOutputGeometry(wl_resource *resource)
+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))
{
- const QRect &r = m_outputGeometry;
- wl_output_send_geometry(resource, r.x(), r.y(), r.width(), r.height(), 0, "", "",0);
}
-void Compositor::sendOutputMode(wl_resource *resource)
+void Output::setCurrentMode(const QSize &size)
{
- const QRect &r = m_outputGeometry;
- wl_output_send_mode(resource, WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED, r.width(), r.height(), 60);
+ qDebug() << Q_FUNC_INFO << size;
+ m_size = size;
+ for (Resource *resource : resourceMap())
+ sendCurrentMode(resource);
}
-void Compositor::setOutputGeometry(void *c, const QList<QVariant> &parameters)
+void Output::output_bind_resource(QtWaylandServer::wl_output::Resource *resource)
{
- Compositor *compositor = static_cast<Compositor *>(c);
- compositor->m_outputGeometry = parameters.first().toRect();
+ sendGeometry(resource);
+ sendCurrentMode(resource);
+}
- wl_resource *resource;
- wl_list_for_each(resource, &compositor->m_outputResources, link)
- compositor->sendOutputGeometry(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/shared/mockoutput.h b/tests/auto/client/shared/mockoutput.h
new file mode 100644
index 000000000..d5a2bb56b
--- /dev/null
+++ b/tests/auto/client/shared/mockoutput.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef MOCKOUTPUT_H
+#define MOCKOUTPUT_H
+
+#include <qglobal.h>
+
+#include "qwayland-server-wayland.h"
+
+#include "mockcompositor.h"
+
+namespace Impl {
+
+class Output : public QtWaylandServer::wl_output
+{
+public:
+ Output(::wl_display *display, const QSize &resolution, const QPoint &position);
+
+ QSharedPointer<MockOutput> mockOutput() const { return m_mockOutput; }
+ void setCurrentMode(const QSize &size);
+
+protected:
+ void output_bind_resource(Resource *resource) override;
+
+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/shared/mocksurface.cpp b/tests/auto/client/shared/mocksurface.cpp
index 61c9ac1b7..7aa2a00b2 100644
--- a/tests/auto/client/shared/mocksurface.cpp
+++ b/tests/auto/client/shared/mocksurface.cpp
@@ -27,10 +27,39 @@
****************************************************************************/
#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(nullptr)
diff --git a/tests/auto/client/shared/shared.pri b/tests/auto/client/shared/shared.pri
index 5edfc09c0..7b0382efc 100644
--- a/tests/auto/client/shared/shared.pri
+++ b/tests/auto/client/shared/shared.pri
@@ -21,4 +21,5 @@ SOURCES += \
HEADERS += \
../shared/mockcompositor.h \
../shared/mockinput.h \
- ../shared/mocksurface.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
index 6d0f4a003..5aac336f2 100644
--- a/tests/auto/client/xdgshellv6/tst_xdgshellv6.cpp
+++ b/tests/auto/client/xdgshellv6/tst_xdgshellv6.cpp
@@ -108,7 +108,7 @@ int main(int argc, char **argv)
setenv("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1", 1);
MockCompositor compositor;
- compositor.setOutputGeometry(QRect(QPoint(), screenSize));
+ compositor.setOutputMode(screenSize);
QGuiApplication app(argc, argv);
compositor.applicationInitialized();