Client test for xdg-shell v6 configure events
Task-number: QTBUG-66689 Change-Id: Ifdf38a9ab73357fdbe61e77f0464b227ddd2e8ac Reviewed-by: Andy Nichols <andy.nichols@qt.io>
This commit is contained in:
parent
1605c84bbf
commit
9df7980958
@ -153,6 +153,7 @@ public slots:
|
||||
// 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(!compositor->surface());
|
||||
QTRY_VERIFY(!compositor->xdgToplevelV6());
|
||||
}
|
||||
|
||||
private slots:
|
||||
|
@ -219,6 +219,14 @@ void MockCompositor::sendSurfaceLeave(const QSharedPointer<MockSurface> &surface
|
||||
processCommand(command);
|
||||
}
|
||||
|
||||
void MockCompositor::sendXdgToplevelV6Configure(const QSharedPointer<MockXdgToplevelV6> toplevel, const QSize &size)
|
||||
{
|
||||
Command command = makeCommand(Impl::Compositor::sendXdgToplevelV6Configure, m_compositor);
|
||||
command.parameters << QVariant::fromValue(toplevel);
|
||||
command.parameters << QVariant::fromValue(size);
|
||||
processCommand(command);
|
||||
}
|
||||
|
||||
void MockCompositor::waitForStartDrag()
|
||||
{
|
||||
Command command = makeCommand(Impl::Compositor::waitForStartDrag, m_compositor);
|
||||
@ -251,6 +259,16 @@ QSharedPointer<MockOutput> MockCompositor::output(int index)
|
||||
return result;
|
||||
}
|
||||
|
||||
QSharedPointer<MockXdgToplevelV6> MockCompositor::xdgToplevelV6(int index)
|
||||
{
|
||||
QSharedPointer<MockXdgToplevelV6> result;
|
||||
lock();
|
||||
if (Impl::XdgToplevelV6 *toplevel = m_compositor->xdgShellV6()->toplevels().value(index, nullptr))
|
||||
result = toplevel->mockToplevel();
|
||||
unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
MockCompositor::Command MockCompositor::makeCommand(Command::Callback callback, void *target)
|
||||
{
|
||||
Command command;
|
||||
@ -400,6 +418,11 @@ QVector<Output *> Compositor::outputs() const
|
||||
return m_outputs;
|
||||
}
|
||||
|
||||
XdgShellV6 *Compositor::xdgShellV6() const
|
||||
{
|
||||
return m_xdgShellV6.data();
|
||||
}
|
||||
|
||||
uint32_t Compositor::nextSerial()
|
||||
{
|
||||
return wl_display_next_serial(m_display);
|
||||
@ -429,5 +452,10 @@ Output *Compositor::resolveOutput(const QVariant &v)
|
||||
return mockOutput ? mockOutput->handle() : nullptr;
|
||||
}
|
||||
|
||||
XdgToplevelV6 *Compositor::resolveToplevel(const QVariant &v)
|
||||
{
|
||||
QSharedPointer<MockXdgToplevelV6> mockToplevel = v.value<QSharedPointer<MockXdgToplevelV6>>();
|
||||
return mockToplevel ? mockToplevel->handle() : nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -29,6 +29,8 @@
|
||||
#ifndef MOCKCOMPOSITOR_H
|
||||
#define MOCKCOMPOSITOR_H
|
||||
|
||||
#include "mockxdgshellv6.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <qglobal.h>
|
||||
#include <wayland-server.h>
|
||||
@ -70,6 +72,8 @@ public:
|
||||
QVector<Surface *> surfaces() const;
|
||||
QVector<Output *> outputs() const;
|
||||
|
||||
XdgShellV6 *xdgShellV6() const;
|
||||
|
||||
void addSurface(Surface *surface);
|
||||
void removeSurface(Surface *surface);
|
||||
|
||||
@ -93,6 +97,7 @@ public:
|
||||
static void sendRemoveOutput(void *data, const QList<QVariant> ¶meters);
|
||||
static void sendOutputGeometry(void *data, const QList<QVariant> ¶meters);
|
||||
static void sendSurfaceEnter(void *data, const QList<QVariant> ¶meters);
|
||||
static void sendXdgToplevelV6Configure(void *data, const QList<QVariant> ¶meters);
|
||||
static void sendSurfaceLeave(void *data, const QList<QVariant> ¶meters);
|
||||
|
||||
public:
|
||||
@ -102,6 +107,7 @@ private:
|
||||
static void bindCompositor(wl_client *client, void *data, uint32_t version, uint32_t id);
|
||||
static Surface *resolveSurface(const QVariant &v);
|
||||
static Output *resolveOutput(const QVariant &v);
|
||||
static XdgToplevelV6 *resolveToplevel(const QVariant &v);
|
||||
|
||||
void initShm();
|
||||
|
||||
@ -146,6 +152,22 @@ private:
|
||||
|
||||
Q_DECLARE_METATYPE(QSharedPointer<MockSurface>)
|
||||
|
||||
class MockXdgToplevelV6
|
||||
{
|
||||
public:
|
||||
Impl::XdgToplevelV6 *handle() const { return m_toplevel; }
|
||||
|
||||
void sendConfigure(const QSharedPointer<MockXdgToplevelV6> toplevel);
|
||||
private:
|
||||
MockXdgToplevelV6(Impl::XdgToplevelV6 *toplevel) : m_toplevel(toplevel) {}
|
||||
friend class Impl::Compositor;
|
||||
friend class Impl::XdgToplevelV6;
|
||||
|
||||
Impl::XdgToplevelV6 *m_toplevel;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(QSharedPointer<MockXdgToplevelV6>)
|
||||
|
||||
class MockOutput {
|
||||
public:
|
||||
Impl::Output *handle() const { return m_output; }
|
||||
@ -187,10 +209,12 @@ public:
|
||||
void sendOutputGeometry(const QSharedPointer<MockOutput> &output, const QRect &geometry);
|
||||
void sendSurfaceEnter(const QSharedPointer<MockSurface> &surface, QSharedPointer<MockOutput> &output);
|
||||
void sendSurfaceLeave(const QSharedPointer<MockSurface> &surface, QSharedPointer<MockOutput> &output);
|
||||
void sendXdgToplevelV6Configure(const QSharedPointer<MockXdgToplevelV6> toplevel, const QSize &size);
|
||||
void waitForStartDrag();
|
||||
|
||||
QSharedPointer<MockSurface> surface();
|
||||
QSharedPointer<MockOutput> output(int index = 0);
|
||||
QSharedPointer<MockXdgToplevelV6> xdgToplevelV6(int index = 0);
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
|
@ -28,47 +28,26 @@
|
||||
|
||||
#include "mockxdgshellv6.h"
|
||||
#include "mocksurface.h"
|
||||
#include "mockcompositor.h"
|
||||
|
||||
namespace Impl {
|
||||
|
||||
class XdgSurfaceV6;
|
||||
|
||||
class XdgToplevelV6 : public QtWaylandServer::zxdg_toplevel_v6
|
||||
void Compositor::sendXdgToplevelV6Configure(void *data, const QList<QVariant> ¶meters)
|
||||
{
|
||||
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, 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);
|
||||
Compositor *compositor = static_cast<Compositor *>(data);
|
||||
XdgToplevelV6 *toplevel = resolveToplevel(parameters.at(0));
|
||||
Q_ASSERT(toplevel && toplevel->resource());
|
||||
QSize size = parameters.at(1).toSize();
|
||||
Q_ASSERT(size.isValid());
|
||||
QByteArray states;
|
||||
toplevel->send_configure(size.width(), size.height(), states);
|
||||
toplevel->xdgSurface()->send_configure(compositor->nextSerial());
|
||||
}
|
||||
|
||||
XdgSurfaceV6::XdgSurfaceV6(wl_client *client, uint32_t id, Surface *surface)
|
||||
XdgSurfaceV6::XdgSurfaceV6(XdgShellV6 *shell, Surface *surface, wl_client *client, uint32_t id)
|
||||
: QtWaylandServer::zxdg_surface_v6(client, id, 1)
|
||||
, m_surface(surface)
|
||||
, m_shell(shell)
|
||||
{
|
||||
}
|
||||
|
||||
@ -79,9 +58,35 @@ void XdgSurfaceV6::zxdg_surface_v6_get_toplevel(QtWaylandServer::zxdg_surface_v6
|
||||
m_surface->map();
|
||||
}
|
||||
|
||||
void XdgSurfaceV6::zxdg_surface_v6_destroy(QtWaylandServer::zxdg_surface_v6::Resource *resource)
|
||||
{
|
||||
Q_ASSERT(!m_toplevel);
|
||||
wl_resource_destroy(resource->handle);
|
||||
}
|
||||
|
||||
XdgToplevelV6::XdgToplevelV6(XdgSurfaceV6 *xdgSurface, wl_client *client, uint32_t id, int version)
|
||||
: QtWaylandServer::zxdg_toplevel_v6(client, id, version)
|
||||
, m_xdgSurface(xdgSurface)
|
||||
, m_mockToplevel(new MockXdgToplevelV6(this))
|
||||
{
|
||||
m_xdgSurface->shell()->addToplevel(this);
|
||||
}
|
||||
|
||||
XdgToplevelV6::~XdgToplevelV6()
|
||||
{
|
||||
m_xdgSurface->shell()->removeToplevel(this);
|
||||
m_mockToplevel->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);
|
||||
}
|
||||
|
||||
void Impl::XdgShellV6::zxdg_shell_v6_get_xdg_surface(QtWaylandServer::zxdg_shell_v6::Resource *resource, uint32_t id, wl_resource *surface)
|
||||
{
|
||||
new XdgSurfaceV6(resource->client(), id, Surface::fromResource(surface));
|
||||
new XdgSurfaceV6(this, Surface::fromResource(surface), resource->client(), id);
|
||||
}
|
||||
|
||||
} // namespace Impl
|
||||
|
@ -28,16 +28,72 @@
|
||||
|
||||
#include <qwayland-server-xdg-shell-unstable-v6.h>
|
||||
|
||||
#include <QSharedPointer>
|
||||
#include <QVector>
|
||||
|
||||
#ifndef MOCKXDGSHELLV6_H
|
||||
#define MOCKXDGSHELLV6_H
|
||||
|
||||
class MockXdgToplevelV6;
|
||||
|
||||
namespace Impl {
|
||||
|
||||
class XdgToplevelV6;
|
||||
class XdgShellV6;
|
||||
class Surface;
|
||||
|
||||
class XdgSurfaceV6 : public QtWaylandServer::zxdg_surface_v6
|
||||
{
|
||||
public:
|
||||
XdgSurfaceV6(XdgShellV6 *shell, Surface *surface, wl_client *client, uint32_t id);
|
||||
XdgShellV6 *shell() const { return m_shell; }
|
||||
|
||||
protected:
|
||||
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;
|
||||
|
||||
private:
|
||||
Surface *m_surface = nullptr;
|
||||
XdgToplevelV6 *m_toplevel = nullptr;
|
||||
XdgShellV6 *m_shell = nullptr;
|
||||
|
||||
friend class XdgToplevelV6;
|
||||
};
|
||||
|
||||
class XdgToplevelV6 : public QtWaylandServer::zxdg_toplevel_v6
|
||||
{
|
||||
public:
|
||||
XdgToplevelV6(XdgSurfaceV6 *xdgSurface, wl_client *client, uint32_t id, int version);
|
||||
~XdgToplevelV6() override;
|
||||
XdgSurfaceV6 *xdgSurface() const { return m_xdgSurface; }
|
||||
|
||||
QSharedPointer<MockXdgToplevelV6> mockToplevel() const { return m_mockToplevel; }
|
||||
|
||||
protected:
|
||||
void zxdg_toplevel_v6_destroy_resource(Resource *) override { delete this; }
|
||||
void zxdg_toplevel_v6_destroy(Resource *resource) override;
|
||||
|
||||
private:
|
||||
XdgSurfaceV6 *m_xdgSurface = nullptr;
|
||||
QSharedPointer<MockXdgToplevelV6> m_mockToplevel;
|
||||
};
|
||||
|
||||
class XdgShellV6 : public QtWaylandServer::zxdg_shell_v6
|
||||
{
|
||||
public:
|
||||
explicit XdgShellV6(::wl_display *display) : zxdg_shell_v6(display, 1) {}
|
||||
QVector<XdgToplevelV6 *> toplevels() const { return m_toplevels; }
|
||||
|
||||
protected:
|
||||
void zxdg_shell_v6_get_xdg_surface(Resource *resource, uint32_t id, ::wl_resource *surface) override;
|
||||
|
||||
private:
|
||||
void addToplevel(XdgToplevelV6 *toplevel) { m_toplevels.append(toplevel); }
|
||||
void removeToplevel(XdgToplevelV6 *toplevel) { m_toplevels.removeOne(toplevel); }
|
||||
QVector<XdgToplevelV6 *> m_toplevels;
|
||||
|
||||
friend class XdgToplevelV6;
|
||||
};
|
||||
|
||||
} // namespace Impl
|
||||
|
@ -76,10 +76,12 @@ public slots:
|
||||
// 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());
|
||||
QTRY_VERIFY(!m_compositor->xdgToplevelV6());
|
||||
}
|
||||
|
||||
private slots:
|
||||
void createDestroyWindow();
|
||||
void configure();
|
||||
|
||||
private:
|
||||
MockCompositor *m_compositor = nullptr;
|
||||
@ -96,6 +98,32 @@ void tst_WaylandClientXdgShellV6::createDestroyWindow()
|
||||
QTRY_VERIFY(!m_compositor->surface());
|
||||
}
|
||||
|
||||
void tst_WaylandClientXdgShellV6::configure()
|
||||
{
|
||||
QSharedPointer<MockOutput> output;
|
||||
QTRY_VERIFY(output = m_compositor->output());
|
||||
|
||||
TestWindow window;
|
||||
window.show();
|
||||
|
||||
QSharedPointer<MockSurface> surface;
|
||||
QTRY_VERIFY(surface = m_compositor->surface());
|
||||
|
||||
m_compositor->processWaylandEvents();
|
||||
QTRY_VERIFY(window.isVisible());
|
||||
QTRY_VERIFY(!window.isExposed()); //Window should not be exposed before the first configure event
|
||||
|
||||
//TODO: according to xdg-shell protocol, a buffer should not be attached to a the surface
|
||||
//until it's configured. Ensure this in the test!
|
||||
|
||||
QSharedPointer<MockXdgToplevelV6> toplevel;
|
||||
QTRY_VERIFY(toplevel = m_compositor->xdgToplevelV6());
|
||||
const QSize newSize(123, 456);
|
||||
m_compositor->sendXdgToplevelV6Configure(toplevel, newSize);
|
||||
QTRY_VERIFY(window.isExposed());
|
||||
QTRY_COMPARE(window.frameGeometry(), QRect(QPoint(), newSize));
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
setenv("XDG_RUNTIME_DIR", ".", 1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user