Send configure events in shell-agnostic client tests

xdg-shell >= unstable v6 requires surfaces to be configured before buffers can
be attached. Make sure to send a configure event when a compositor would
normally do it.

Task-number: QTBUG-66510
Change-Id: Icbff6ebaa597e858d92d621849aa0df7a8a976f3
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
This commit is contained in:
Johan Klokkhammer Helsing 2018-02-26 16:52:18 +01:00 committed by Johan Helsing
parent 9df7980958
commit 45dbab401a
9 changed files with 78 additions and 10 deletions

View File

@ -226,6 +226,8 @@ void tst_WaylandClient::windowScreens()
QSharedPointer<MockSurface> surface;
QTRY_VERIFY(surface = compositor->surface());
compositor->sendShellSurfaceConfigure(surface);
QTRY_COMPARE(QGuiApplication::screens().size(), 1);
QScreen *primaryScreen = QGuiApplication::screens().first();
QCOMPARE(window.screen(), primaryScreen);
@ -267,6 +269,7 @@ void tst_WaylandClient::removePrimaryScreen()
QSharedPointer<MockSurface> surface;
QTRY_VERIFY(surface = compositor->surface());
compositor->sendShellSurfaceConfigure(surface);
QTRY_COMPARE(QGuiApplication::screens().size(), 1);
QScreen *primaryScreen = QGuiApplication::screens().first();
QCOMPARE(window.screen(), primaryScreen);
@ -308,6 +311,9 @@ void tst_WaylandClient::events()
QSharedPointer<MockSurface> surface;
QTRY_VERIFY(surface = compositor->surface());
compositor->sendShellSurfaceConfigure(surface);
QTRY_VERIFY(window.isExposed());
QCOMPARE(window.focusInEventCount, 0);
compositor->setKeyboardFocus(surface);
@ -363,6 +369,7 @@ void tst_WaylandClient::backingStore()
QSharedPointer<MockSurface> surface;
QTRY_VERIFY(surface = compositor->surface());
compositor->sendShellSurfaceConfigure(surface);
QRect rect(QPoint(), window.size());
@ -435,6 +442,7 @@ void tst_WaylandClient::touchDrag()
QSharedPointer<MockSurface> surface;
QTRY_VERIFY(surface = compositor->surface());
compositor->sendShellSurfaceConfigure(surface);
compositor->setKeyboardFocus(surface);
QTRY_COMPARE(QGuiApplication::focusWindow(), &window);
@ -460,6 +468,7 @@ void tst_WaylandClient::mouseDrag()
QSharedPointer<MockSurface> surface;
QTRY_VERIFY(surface = compositor->surface());
compositor->sendShellSurfaceConfigure(surface);
compositor->setKeyboardFocus(surface);
QTRY_COMPARE(QGuiApplication::focusWindow(), &window);
@ -528,6 +537,7 @@ void tst_WaylandClient::hiddenPopupParent()
// with the set_popup request.
QSharedPointer<MockSurface> surface;
QTRY_VERIFY(surface = compositor->surface());
compositor->sendShellSurfaceConfigure(surface);
QPoint mousePressPos(16, 16);
QCOMPARE(toplevel.mousePressEventCount, 0);
compositor->sendMousePress(surface, toplevel.frameOffset() + mousePressPos);
@ -552,6 +562,7 @@ void tst_WaylandClient::glWindow()
testWindow->show();
QSharedPointer<MockSurface> surface;
QTRY_VERIFY(surface = compositor->surface());
compositor->sendShellSurfaceConfigure(surface);
QTRY_VERIFY(testWindow->paintGLCalled);

View File

@ -219,6 +219,14 @@ void MockCompositor::sendSurfaceLeave(const QSharedPointer<MockSurface> &surface
processCommand(command);
}
void MockCompositor::sendShellSurfaceConfigure(const QSharedPointer<MockSurface> surface, const QSize &size)
{
Command command = makeCommand(Impl::Compositor::sendShellSurfaceConfigure, m_compositor);
command.parameters << QVariant::fromValue(surface);
command.parameters << QVariant::fromValue(size);
processCommand(command);
}
void MockCompositor::sendXdgToplevelV6Configure(const QSharedPointer<MockXdgToplevelV6> toplevel, const QSize &size)
{
Command command = makeCommand(Impl::Compositor::sendXdgToplevelV6Configure, m_compositor);

View File

@ -97,8 +97,9 @@ public:
static void sendRemoveOutput(void *data, const QList<QVariant> &parameters);
static void sendOutputGeometry(void *data, const QList<QVariant> &parameters);
static void sendSurfaceEnter(void *data, const QList<QVariant> &parameters);
static void sendXdgToplevelV6Configure(void *data, const QList<QVariant> &parameters);
static void sendSurfaceLeave(void *data, const QList<QVariant> &parameters);
static void sendShellSurfaceConfigure(void *data, const QList<QVariant> &parameters);
static void sendXdgToplevelV6Configure(void *data, const QList<QVariant> &parameters);
public:
bool m_startDragSeen = false;
@ -209,7 +210,8 @@ 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 sendShellSurfaceConfigure(const QSharedPointer<MockSurface> surface, const QSize &size = QSize(0, 0));
void sendXdgToplevelV6Configure(const QSharedPointer<MockXdgToplevelV6> toplevel, const QSize &size = QSize(0, 0));
void waitForStartDrag();
QSharedPointer<MockSurface> surface();

View File

@ -29,6 +29,9 @@
#include "mocksurface.h"
#include "mockoutput.h"
#include "mockcompositor.h"
#include "mockwlshell.h"
#include <QDebug>
namespace Impl {
@ -60,6 +63,23 @@ void Compositor::sendSurfaceLeave(void *data, const QList<QVariant> &parameters)
surface->send_leave(outputResource->handle);
}
void Compositor::sendShellSurfaceConfigure(void *data, const QList<QVariant> &parameters)
{
Compositor *compositor = static_cast<Compositor *>(data);
Surface *surface = resolveSurface(parameters.at(0));
QSize size = parameters.at(1).toSize();
Q_ASSERT(size.isValid());
if (auto toplevel = surface->xdgToplevelV6()) {
toplevel->send_configure(size.width(), size.height(), QByteArray());
toplevel->xdgSurface()->send_configure(compositor->nextSerial());
} else if (auto wlShellSurface = surface->wlShellSurface()) {
const uint edges = 0;
wlShellSurface->send_configure(edges, size.width(), size.height());
} else {
qWarning() << "The mocking framework doesn't know how to send a configure event for this surface";
}
}
Surface::Surface(wl_client *client, uint32_t id, int v, Compositor *compositor)
: QtWaylandServer::wl_surface(client, id, v)
, m_compositor(compositor)

View File

@ -37,6 +37,9 @@
namespace Impl {
class XdgToplevelV6;
class WlShellSurface;
class Surface : public QtWaylandServer::wl_surface
{
public:
@ -47,6 +50,8 @@ public:
static Surface *fromResource(struct ::wl_resource *resource);
void map();
bool isMapped() const;
XdgToplevelV6 *xdgToplevelV6() const { return m_xdgToplevelV6; }
WlShellSurface *wlShellSurface() const { return m_wlShellSurface; }
QSharedPointer<MockSurface> mockSurface() const { return m_mockSurface; }
@ -64,11 +69,16 @@ protected:
void surface_commit(Resource *resource) override;
private:
wl_resource *m_buffer = nullptr;
XdgToplevelV6 *m_xdgToplevelV6 = nullptr;
WlShellSurface *m_wlShellSurface = nullptr;
Compositor *m_compositor = nullptr;
QSharedPointer<MockSurface> m_mockSurface;
QList<wl_resource *> m_frameCallbackList;
bool m_mapped = false;
friend class XdgToplevelV6;
friend class WlShellSurface;
};
}

View File

@ -31,19 +31,19 @@
namespace Impl {
class WlShellSurface : public QtWaylandServer::wl_shell_surface
{
public:
explicit WlShellSurface(::wl_client *client, int id, Surface *surface);
void shell_surface_destroy_resource(Resource *) override { delete this; }
};
WlShellSurface::WlShellSurface(wl_client *client, int id, Surface *surface)
: QtWaylandServer::wl_shell_surface(client, id, 1)
, m_surface(surface)
{
surface->m_wlShellSurface = this;
surface->map();
}
WlShellSurface::~WlShellSurface()
{
m_surface->m_wlShellSurface = nullptr;
}
void WlShell::shell_get_shell_surface(QtWaylandServer::wl_shell::Resource *resource, uint32_t id, wl_resource *surface)
{
new WlShellSurface(resource->client(), id, Surface::fromResource(surface));

View File

@ -33,6 +33,19 @@
namespace Impl {
class Surface;
class WlShellSurface : public QtWaylandServer::wl_shell_surface
{
public:
explicit WlShellSurface(::wl_client *client, int id, Surface *surface);
~WlShellSurface() override;
void shell_surface_destroy_resource(Resource *) override { delete this; }
private:
Surface *m_surface = nullptr;
};
class WlShell : public QtWaylandServer::wl_shell
{
public:

View File

@ -55,7 +55,6 @@ void XdgSurfaceV6::zxdg_surface_v6_get_toplevel(QtWaylandServer::zxdg_surface_v6
{
int version = wl_resource_get_version(resource->handle);
m_toplevel = new XdgToplevelV6(this, resource->client(), id, version);
m_surface->map();
}
void XdgSurfaceV6::zxdg_surface_v6_destroy(QtWaylandServer::zxdg_surface_v6::Resource *resource)
@ -69,12 +68,16 @@ XdgToplevelV6::XdgToplevelV6(XdgSurfaceV6 *xdgSurface, wl_client *client, uint32
, m_xdgSurface(xdgSurface)
, m_mockToplevel(new MockXdgToplevelV6(this))
{
auto *surface = m_xdgSurface->surface();
surface->m_xdgToplevelV6 = this;
m_xdgSurface->shell()->addToplevel(this);
surface->map();
}
XdgToplevelV6::~XdgToplevelV6()
{
m_xdgSurface->shell()->removeToplevel(this);
m_xdgSurface->surface()->m_xdgToplevelV6 = nullptr;
m_mockToplevel->m_toplevel = nullptr;
}

View File

@ -47,6 +47,7 @@ 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; }
Surface *surface() const { return m_surface; }
protected:
void zxdg_surface_v6_destroy_resource(Resource *) override { delete this; }