diff options
author | Johan Klokkhammer Helsing <johan.helsing@qt.io> | 2017-08-18 17:28:01 +0200 |
---|---|---|
committer | Johan Helsing <johan.helsing@qt.io> | 2017-11-15 08:34:27 +0000 |
commit | 69d587b9a8e336cff4356c49e4f37aae2a474a4f (patch) | |
tree | cd53978cb4c7ea0b8933034e04b600d0f41e3c41 /tests | |
parent | 9cf680f94b78baf1bb92051021ebc243dec1f02e (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.cpp | 45 | ||||
-rw-r--r-- | tests/auto/client/shared/mockcompositor.cpp | 59 | ||||
-rw-r--r-- | tests/auto/client/shared/mockcompositor.h | 32 | ||||
-rw-r--r-- | tests/auto/client/shared/mockinput.cpp | 6 | ||||
-rw-r--r-- | tests/auto/client/shared/mockoutput.cpp | 73 | ||||
-rw-r--r-- | tests/auto/client/shared/mockoutput.h | 62 | ||||
-rw-r--r-- | tests/auto/client/shared/mocksurface.cpp | 29 | ||||
-rw-r--r-- | tests/auto/client/shared/shared.pri | 3 | ||||
-rw-r--r-- | tests/auto/client/xdgshellv6/tst_xdgshellv6.cpp | 2 |
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> ¶meters); - 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> ¶meters); static void sendDataDeviceLeave(void *data, const QList<QVariant> ¶meters); static void waitForStartDrag(void *data, const QList<QVariant> ¶meters); + static void setOutputMode(void *compositor, const QList<QVariant> ¶meters); + static void sendAddOutput(void *data, const QList<QVariant> ¶meters); + static void sendSurfaceEnter(void *data, const QList<QVariant> ¶meters); + static void sendSurfaceLeave(void *data, const QList<QVariant> ¶meters); 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> ¶meters) { 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> ¶meters) { + 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> ¶meters) +{ + 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> ¶meters) +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> ¶meters) +{ + 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> ¶meters) +{ + 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(); |